简体   繁体   English

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

[英]Why bother with abstract or interface classes?

This has been boggling me as to why its better to have an abstract class. 这令人难以理解为什么最好有一个抽象类。 So lets say i have to calculate areas of a different shapes (circle, rectangle). 所以我要说我必须计算不同形状的区域(圆形,矩形)。 I was taught its better to have a abstract/interface shape and then classes such as Rectangle, Circle extending it. 我被教会更好地拥有一个抽象/界面形状,然后像Rectangle,Circle这样的类扩展它。

I made the following code 我做了以下代码

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

It seems like shape class serves no purpose. 看起来形状类没有用处。 I can't do an impementation of getArea in shape class, since different shapes calculate area differently. 我不能在形状类中执行getArea的实现,因为不同的形状会以不同的方式计算区域。 I could just remove shape class and make my code simpler. 我可以删除shape类并使我的代码更简单。

So what would be the actual purpose of having an abstract/interface class shape? 那么具有抽象/接口类形状的实际目的是什么? Thanks in advance for any explanations 提前感谢您的任何解释

It seems like shape class serves no purpose. 看起来形状类没有用处。 I can't do an impementation of getArea in shape class, since different shapes calculate area differently. 我不能在形状类中执行getArea的实现,因为不同的形状会以不同的方式计算区域。 I could just remove shape class and make my code simpler. 我可以删除shape类并使我的代码更简单。

Suppose you have a picture which is composed of several shapes - some circles, some rectangles etc. You can store all those shapes in a List<Shape> , and then compute the total area using: 假设您有一个由多个形状组成的图片 - 一些圆形,一些矩形等。您可以将所有这些形状存储在List<Shape> ,然后使用以下方法计算总面积:

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

How would you do this if you didn't have a common Shape class or interface? 如果你没有常见的Shape类或接口,你会怎么做? Your Picture class would have to know about each individual shape class, rather than using the commonality between the different shape classes to make the code more general. 您的Picture类必须知道每个单独的形状类,而不是使用不同形状类之间的通用性来使代码更通用。

As another example, consider streams. 另一个例子,考虑流。 Imagine that we didn't have the InputStream class - we just had the individual subclasses. 想象一下,我们没有InputStream类 - 我们只有各个子类。 Then every time you wrote code which had to read some data, you'd have to provide an overload for each individual subclass you wanted to be able to handle, even though the code would be exactly the same in each method. 然后每次编写必须读取某些数据的代码时,您必须为您希望能够处理的每个子类提供重载,即使每个方法中的代码完全相同。 InputStream abstracts away the differences, exposing the common functionality (reading, skipping etc). InputStream抽象出差异,暴露了常见的功能(阅读,跳过等)。 That way you can write a single method which just takes InputStream , and then call it with a FileInputStream , or a ByteArrayInputStream etc... without the method needing to care which one it receives. 这样你就可以编写一个只接受InputStream方法,然后使用FileInputStreamByteArrayInputStream等调用它......而不需要关心它接收哪一个方法。

If you want to pass to a method an arbitrary Shape you can do: 如果要传递给任意Shape的方法,您可以执行以下操作:

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

This is called polymorphism. 这称为多态性。 If there is no abstract class or interface you can't do this. 如果没有抽象类或接口,则无法执行此操作。

You can use an interface or an abstract class when you want to group classes based on certain behaviours or properties they share. 如果要根据共享的某些行为或属性对类进行分组,可以使用接口或抽象类。 This will allow you to use the interface/abstract class as types of parameters or in generics. 这将允许您使用接口/抽象类作为参数类型或泛型。 In your case, for example, you may do the following: 例如,在您的情况下,您可以执行以下操作:

  1. Creating a list of different shapes List <Shape> . 创建不同形状的List <Shape>
  2. Pass a shape to a method. 将形状传递给方法。 Let's say you have a method getArea() on your Shape class/interface. 假设您在Shape类/接口上有一个方法getArea() You can use it then in a method whichIsGreater (Shape shape1, Shape shape2) that would use getArea() method in its implementation. 您可以在其实现中使用getArea()方法的whichIsGreater (Shape shape1, Shape shape2) getArea()方法中使用它。

There is one more very important aspect of using interfaces or abstract classes. 使用接口或抽象类还有一个非常重要的方面。 Having an abstract class (or an interface) defined for your classes shows the intention of your code design. 为您的类定义一个抽象类(或接口)可以显示您的代码设计的意图 Someone who would pick up your code, would have much easier task to understand it with properly defined inheritance. 有人会选择你的代码,通过正确定义的继承来理解它的任务会更容易。

The goal of good code design is not really writing the shortest possible code. 良好代码设计的目标并不是真正编写尽可能短的代码。 It's about efficient but also clear and self-documented code. 它是关于有效但也清晰且自我记录的代码。

For completeness of my answer, I have repeated some of the points raised in other answers - no disrespect intended. 为了完整答案,我重复了其他答案中提出的一些观点 - 没有任何不尊重的意图。

In your particular case, Shape should be an interface not an abstract class . 在您的特定情况下,Shape应该是一个interface而不是一个abstract class An interface is basically an abstract class with only public methods and no implementations. interface基本上是一个abstract class ,只有public方法而没有实现。 An abstract class makes sense when you you are able to implement a certain method that is correct for all or at least most of the implementing subclasses. 当您能够实现对所有或至少大多数实现子类都正确的特定方法时, abstract class是有意义的。 It's an application of the Don't Repeat Yourself (DRY) principle in this case. 在这种情况下,这是“不要重复自己”(DRY)原则的应用。

Why bother with abstract classes or interfaces? 为什么要烦扰抽象类或接口?

Because now you can have just a List<Shape> where you can put all kinds of different Shapes into and you do not need to care which shape it exactly is. 因为现在你可以只有一个List<Shape> ,你可以在其中放入各种不同的形状,你不需要关心它究竟是哪种形状。 The JVM will do the work for you and choose which getArea implementation it has to choose. JVM将为您完成工作,并选择它必须选择哪个getArea实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM