lambda 表达式可以替代多态性吗?Java 中 lambda 表达式的优点。

2022-09-01 19:23:09

我正在学习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();

    }
}

我已经使用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);
    }

}

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


答案 1

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

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

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

和:

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

lambda 表达式完全不允许这两者:

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

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

    这与上面的第二个代码片段并不完全相同(在更复杂的示例中,可以在 中提供基本实现,并在 和 中重写它;而 lambdas 则无法做到这一点)。此外,有人认为上面的两个赋值使用不同的源代码是正确的。ShapeRectangleSquare

  3. 不能像类那样只是“强制转换”类型:

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

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


答案 2

我同意@yelliver和@cricket_007,你所做的只是使用匿名类而不是子类。

你写了

Shape s1 = new Shape("Rectangle");
Drawable rectangle = () -> System.out.println("Drawing rectangle with 2 equal sides.");
s1.draw(rectangle);

它就像

Shape s1 = new Shape("Rectangle");
Drawable rectangle = new Drawable() {
    @Override
    public void draw() {
        System.out.println("Drawing rectangle with 2 equal sides.");
    }
};
s1.draw(rectangle);

因此,您创建的两个示例并不相同。第一个示例使用子类,而第二个示例使用匿名类。

所以我认为,它可能是多态性的替代方案。

显然,它不是替代方案,它只是另一种实现方式。

Java 中 lambda 表达式的优点。

1. 更少的代码行

在上面的例子中,你可以看到匿名类被->更改。

2. 通过在方法中传递行为来支持顺序和并行执行

只需使用 ,即可迭代任何集合。(示例foreach())

list.forEach(item->System.out.println(item));

3. Lambda 表达式和对象

在Java中,任何lambda表达式都是一个对象,就像一个功能接口的实例一样。我们可以将 lambda 表达式分配给任何变量,并像传递任何其他对象一样传递它(示例)。喜欢

list.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());

推荐