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
The short answer: An abstract class allows you to create functionality that subclasses can implement or override. An interface only allows you to define functionality, not implement it. And whereas a class can extend only one abstract class, it can take advantage of multiple interfaces.
Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing a common functionality to unrelated classes. Interfaces are a good choice when we think that the API will not change for a while.
The only reason for declaring a class as abstract is so that it can't be instantiated. There are situations where you will have common functionality that is shared between a number of classes, but by itself that common functionality does not represent an object or represents an incomplete object.
Java doesn't support multiple class inheritance. So you can implement multiple inteface. more importantly you can implement interface and extend other class at the same time. If you used abstract class in place of interface which would not be possible.
The first difference between interfaces and abstract classes is what they are and how they are used to implement classes. Interfaces are implemented and abstract classes are extended.
When to use an interface If the functionality we are creating will be useful across a wide range of disparate objects, use an interface. Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing a common functionality to unrelated classes.
When to use an abstract class. An abstract class is a good choice if we are using the inheritance concept since it provides a common base class implementation to derived classes. An abstract class is also good if we want to declare non-public members. In an interface, all methods must be public.
But if the abstract class is set up, then you can still add the behavior without breaking the existing code. An abstract class is used if you want to provide a common, implemented functionality among all the implementations of the component.
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:
List <Shape>
.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With