令人难以理解为什么最好有一个抽象类。所以我要说我必须计算不同形状的区域(圆形,矩形)。我被告知最好有一个抽象/界面形状,然后像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类并使我的代码更简单。
那么具有抽象/接口类形状的实际目的是什么?提前感谢您的任何解释
答案 0 :(得分:16)
看起来形状类没有用处。我不能在形状类中执行getArea的实现,因为不同的形状会以不同的方式计算区域。我可以删除shape类并使我的代码更简单。
假设您有一个由多个形状组成的图片 - 一些圆形,一些矩形等。您可以将所有这些形状存储在List<Shape>
中,然后使用以下方法计算总面积:
int totalArea = 0;
for (Shape shape : shapes) {
totalArea += shape.getArea();
}
如果您没有通用的Shape
类或接口,您会怎么做?您的Picture
类必须知道每个单独的形状类,而不是使用不同形状类之间的共性来使代码更通用。
另一个例子,考虑流。想象一下,我们没有InputStream
类 - 我们只有个别的子类。然后每次编写必须读取某些数据的代码时,您必须为您希望能够处理的每个子类提供重载,即使每个方法中的代码完全相同。 InputStream
抽象出差异,暴露了共同的功能(阅读,跳过等)。这样你就可以编写一个只需要InputStream
的方法,然后使用FileInputStream
或ByteArrayInputStream
等来调用它...而不需要关心它接收哪个方法
答案 1 :(得分:7)
如果您想传递给任意Shape
的方法,您可以这样做:
public void method(Shape shape) {
int area = shape.getArea();
}
这称为多态性。 如果没有抽象类或接口,则无法执行此操作。
答案 2 :(得分:5)
如果要根据共享的某些行为或属性对类进行分组,可以使用接口或抽象类。这将允许您使用接口/抽象类作为参数类型或泛型。例如,在您的情况下,您可以执行以下操作:
List <Shape>
。getArea()
。然后,您可以在方法whichIsGreater (Shape shape1, Shape shape2)
中使用它,该方法将在其实现中使用getArea()
方法。 使用接口或抽象类还有一个非常重要的方面。为您的类定义抽象类(或接口)会显示代码设计的意图。有人会选择你的代码,通过正确定义的继承来理解它会更容易。
良好代码设计的目标并不是真正编写尽可能短的代码。这是关于有效但也清晰且自我记录的代码。
为了完整答案,我重复了其他答案中提出的一些观点 - 没有任何不尊重的意图。
答案 3 :(得分:2)
在您的特定情况下,Shape应为interface
而不是abstract class
。
interface
基本上只是abstract class
,只有public
个方法,没有实现。当您能够实现对所有或至少大多数实现子类都正确的特定方法时,abstract class
是有意义的。在这种情况下,这是“不要重复自己”(DRY)原则的应用。
为什么要使用抽象类或接口呢?
因为现在你可以只有一个List<Shape>
,你可以将各种不同的形状放入其中,而你不需要关心它究竟是哪种形状。 JVM将为您完成工作,并选择它必须选择哪个getArea
实现。