8

这让我很困惑,为什么拥有一个抽象类更好。所以可以说我必须计算不同形状(圆形、矩形)的面积。我被教导最好有一个抽象/界面形状,然后像 Rectangle、Circle 这样的类来扩展它。

我做了以下代码

abstract class Shape {
    abstract int getArea();
} 

class Rectangle extends Shape{
    private int width;
    private int height;

    public Rectangle (){
        this.width = width;
        this.height = height;
    }

    // get set methods ommited

    public int getArea () {
        return width * height;
    }
}

看起来形状类没有任何作用。我不能在形状类中执行 getArea ,因为不同的形状计算面积不同。我可以删除形状类并使我的代码更简单。

那么拥有抽象/接口类形状的实际目的是什么?提前感谢您的任何解释

4

4 回答 4

16

看起来形状类没有任何作用。我不能在形状类中执行 getArea ,因为不同的形状计算面积不同。我可以删除形状类并使我的代码更简单。

假设您有一张由几种形状组成的图片 - 一些圆形,一些矩形等。您可以将所有这些形状存储在 aList<Shape>中,然后使用以下方法计算总面积:

int totalArea = 0;
for (Shape shape : shapes) {
    totalArea += shape.getArea();
}

如果您没有公共Shape类或接口,您将如何做到这一点?您的Picture班级必须了解每个单独的形状类,而不是使用不同形状类之间的共性来使代码更通用。

作为另一个例子,考虑流。想象一下,我们没有InputStream类——我们只有单独的子类。然后,每次您编写必须读取一些数据的代码时,您都必须为您希望能够处理的每个单独的子类提供重载,即使每个方法中的代码完全相同。InputStream抽象出差异,暴露出共同的功能(阅读,跳过等)。这样,您可以编写一个只需要 的方法InputStream,然后用 aFileInputStream或 aByteArrayInputStream等调用它,而无需关心它接收哪个方法。

于 2013-10-19T08:04:50.723 回答
7

如果您想将任意方法传递给方法,Shape您可以执行以下操作:

public void method(Shape shape) {
   int area = shape.getArea();
}

这称为多态性。如果没有抽象类或接口,你就不能这样做。

于 2013-10-19T08:05:02.083 回答
5

当您希望根据类共享的某些行为或属性对类进行分组时,可以使用接口或抽象类。这将允许您将接口/抽象类用作参数类型或泛型。例如,在您的情况下,您可以执行以下操作:

  1. 创建不同形状的列表List <Shape>
  2. 将形状传递给方法。假设getArea()您的 Shape 类/接口上有一个方法。然后,您可以在将在其实现中whichIsGreater (Shape shape1, Shape shape2)使用方法的方法中使用它。getArea()

使用接口或抽象类还有一个非常重要的方面。为类定义抽象类(或接口)表明了代码设计的意图。拿起你的代码的人,通过正确定义的继承将更容易理解它。

良好代码设计的目标并不是真正编写尽可能短的代码。它是关于高效但也清晰和自我记录的代码。

为了我的回答的完整性,我重复了其他答案中提出的一些观点——没有不尊重的意思。

于 2013-10-19T08:12:26.783 回答
2

在您的特定情况下, Shape 应该interface不是abstract class. Aninterface基本上是一个abstract class只有public方法而没有实现的。abstract class当您能够实现对所有或至少大多数实现子类都正确的某个方法时,这是有意义的。在这种情况下,这是“不要重复自己 (DRY)”原则的应用。

为什么要为抽象类或接口烦恼?

因为现在您可以拥有一个List<Shape>可以放置各种不同形状的地方,而无需关心它到底是哪种形状。JVM 将为您完成工作并选择getArea它必须选择的实现。

于 2013-10-19T08:07:23.780 回答