Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can lambda expressions be the alternative of polymorphism?

Tags:

I am learning lambda expressions and functional interfaces. We can directly write an implementation of the interface by the lambda expression. So I think, it could be the alternative for polymorphism.

I have some code using polymorphism,

interface Drawable {     public void draw(); }   class Shape {      protected String name;      public Shape(String name) {         this.name = name;     } }  class Rectangle extends Shape implements Drawable  {      public Rectangle(String name) {         super(name);     }      @Override     public void draw() {         System.out.println("I am "+this.name);         System.out.println("Drawing rectangle with 2 equal sides.");     } }  class Square extends Shape implements Drawable {      public Square(String name) {         super(name);     }      @Override     public void draw() {         System.out.println("I am "+this.name);         System.out.println("Drawing square with 4 equal sides.");     } }   public class DrawShape {      public static void main(String ar[]) {          Drawable rectangle = new Rectangle("Rectangle");         rectangle.draw();          Drawable square = new Square("Square");         square.draw();      } } 

I have written above code using lambda expressions and functional interface,

@FunctionalInterface interface Drawable {     public void draw(); }   class Shape {     private String name;     public Shape(String name) {         this.name = name;     }      public void draw(Drawable d1) {         System.out.println("I am "+this.name);         d1.draw();     } }    public class DrawShape {      public static void main(String[] args) {         Shape s1 = new Shape("Rectangle");         Drawable rectangle = () -> System.out.println("Drawing rectangle with 2 equal sides.");         s1.draw(rectangle);          Shape s2 = new Shape("Square");         Drawable sqaure = () -> System.out.println("Drawing square with 4 equal sides.");         s2.draw(sqaure);     }  } 

Which is the better approach? What about other aspects like code reusability, code maintenance and modification, coupling and cohesion etc for lambda?

like image 726
Kaustubh Khare Avatar asked Jul 31 '18 04:07

Kaustubh Khare


People also ask

Which can be used instead of lambda expression?

How to replace lambda expression with method reference in Java 8. If you are using a lambda expression as an anonymous function but not doing anything with the argument passed, you can replace lambda expression with method reference.

Can lambda expressions be used for all interfaces?

From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface can have any number of default methods.

Is lambda expression only for functional interface?

No, all the lambda expressions in this code implement the BiFunction<Integer, Integer, Integer> function interface. The body of the lambda expressions is allowed to call methods of the MathOperation class. It doesn't have to refer only to methods of a functional interface.

Can we replace anonymous class with lambda?

Since the most common use of Anonymous class is to provide a throwaway, stateless implementation of abstract class and interface with a single function, those can be replaced by lambda expressions, but when you have a state field or implementing more than one interface, you cannot use lambdas to replace the anonymous ...


1 Answers

I would argue that lambda expressions allow developers to write fully polymorphic types, the way full class implementations do.

Polymorphism is often seen in two ways:

Drawable drawable = new Rectangle("name"); drawable.draw(); Shape shape = (Shape) drawable; //same object, multiple types. 

And:

Drawable drawable2 = new Rectangle("name"); drawable2.draw(); //Rectangle.draw() implementation invoked drawable2 = new Square("name"); drawable2.draw(); //Square.draw() implementation 

Neither of these two is perfectly allowed for by lambda expressions:

  1. Lambda expressions will only be used to implement functional interfaces. This is the first major limitation.
  2. Although one can do this:

    Drawable drawable = () -> System.out.println("drawing rectangle"); drawable = () -> System.out.println("drawing square"); 

    This is not strictly the same thing as the second code snippet above (in a more complex example, one would be able to provide a basic implementation in Shape, and have it overridden in Rectangle and Square; and that wouldn't be possible with lambdas). Also, one would be correct to argue that the two assignments above use different source code.

  3. One can't just "cast" types as with classes:

    Drawable drawable3 = () -> System.out.println("Drawing something"); Shape shape3 = (Shape) drawable3; //Class cast exception. 

In other words, lambda expressions are a good fit for functional programming coding, not a substitute for good Object-Oriented design.

like image 147
ernest_k Avatar answered Sep 18 '22 17:09

ernest_k