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

时间:2013-10-19 08:01:48

标签: java inheritance polymorphism

令人难以理解为什么最好有一个抽象类。所以我要说我必须计算不同形状的区域(圆形,矩形)。我被告知最好有一个抽象/界面形状,然后像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的实现,因为不同的形状会以不同的方式计算区域。我可以删除shape类并使我的代码更简单。

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

4 个答案:

答案 0 :(得分:16)

  

看起来形状类没有用处。我不能在形状类中执行getArea的实现,因为不同的形状会以不同的方式计算区域。我可以删除shape类并使我的代码更简单。

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

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

如果您没有通用的Shape类或接口,您会怎么做?您的Picture类必须知道每个单独的形状类,而不是使用不同形状类之间的共性来使代码更通用。

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

答案 1 :(得分:7)

如果您想传递给任意Shape的方法,您可以这样做:

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

这称为多态性。 如果没有抽象类或接口,则无法执行此操作。

答案 2 :(得分:5)

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

  1. 创建不同形状的列表List <Shape>
  2. 将形状传递给方法。假设您的Shape类/接口上有方法getArea()。然后,您可以在方法whichIsGreater (Shape shape1, Shape shape2)中使用它,该方法将在其实现中使用getArea()方法。
  3. 使用接口或抽象类还有一个非常重要的方面。为您的类定义抽象类(或接口)会显示代码设计的意图。有人会选择你的代码,通过正确定义的继承来理解它会更容易。

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

    为了完整答案,我重复了其他答案中提出的一些观点 - 没有任何不尊重的意图。

答案 3 :(得分:2)

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

为什么要使用抽象类或接口呢?

因为现在你可以只有一个List<Shape>,你可以将各种不同的形状放入其中,而你不需要关心它究竟是哪种形状。 JVM将为您完成工作,并选择它必须选择哪个getArea实现。