简体   繁体   中英

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.

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. I could just remove shape class and make my code simpler.

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. I could just remove shape class and make my code simpler.

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:

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? 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.

As another example, consider streams. Imagine that we didn't have the InputStream class - we just had the individual subclasses. 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). 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.

If you want to pass to a method an arbitrary Shape you can do:

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> .
  2. Pass a shape to a method. Let's say you have a method getArea() on your Shape class/interface. You can use it then in a method whichIsGreater (Shape shape1, Shape shape2) that would use getArea() method in its implementation.

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 . An interface is basically an abstract class with only public methods and no implementations. 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. It's an application of the Don't Repeat Yourself (DRY) principle in this case.

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. The JVM will do the work for you and choose which getArea implementation it has to choose.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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