lambda表达式可以替代多态吗?

Kau*_*are 25 java lambda java-8

我正在学习lambda表达式和功能接口.我们可以通过lambda表达式直接编写接口的实现.所以我认为,它可能是多态性的替代品.

我有一些使用多态的代码,

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();

    }
}
Run Code Online (Sandbox Code Playgroud)

我用lambda表达式和函数接口编写了上面的代码,

@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);
    }

}
Run Code Online (Sandbox Code Playgroud)

哪种方法更好?那么lambda的代码可重用性,代码维护和修改,耦合和内聚等其他方面呢?

ern*_*t_k 11

我认为lambda表达式允许开发人员编写完全多态的类型,就像全类实现一样.

多态性通常以两种方式出现:

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

和:

Drawable drawable2 = new Rectangle("name");
drawable2.draw(); //Rectangle.draw() implementation invoked
drawable2 = new Square("name");
drawable2.draw(); //Square.draw() implementation
Run Code Online (Sandbox Code Playgroud)

lambda表达式完全不允许这两个中的任何一个:

  1. Lambda表达式仅用于实现功能接口.这是第一个主要限制.
  2. 虽然可以这样做:

    Drawable drawable = () -> System.out.println("drawing rectangle");
    drawable = () -> System.out.println("drawing square");
    
    Run Code Online (Sandbox Code Playgroud)

    这不是严格相同的事情作为第二代码段以上(在一个更复杂的例子,人们将能够提供一种在基本实现Shape,并有它在重写RectangleSquare;以及将不可能与lambda表达式).另外,一个人认为上面的两个赋值使用不同的源代码是正确的.

  3. 人们不能像使用类一样"强制转换"类型:

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

换句话说,lambda表达式非常适合函数式编程编码,而不是良好的面向对象设计的替代品.

  • "*类版本使用动态绑定,而lambda表达式依赖于编译器.*".这句话毫无意义.无论编译器如何实现它们,对`draw()`的方法调用都将使用动态绑定,如果`Drawable`是一个接口,它将完全是同一种动态绑定,就像调用接口方法一样,它无论实现是普通类还是为lambda表达式生成,都完全无关紧要. (3认同)