Let's talk about abstract classes in Java.
This is what the simplest abstract class looks like. As you can see, it's nothing special :) Why would we need it? First of all, it describes our required entity, a car, in the most abstract way possible. There's a reason why we're using the word abstract. In the real world, there are no 'abstract cars'. There are trucks, race cars, sedans, coupes, and SUVs. Our abstract class is simply a 'blueprint' we will use later to create car classes.
This is very similar to what we talked about in the lessons on inheritance. But in those lessons, we had a Car class and its methods weren't abstract. But that solution has a number of drawbacks that are fixed in abstract classes. First and foremost, you can't create an instance of an abstract class:
Java's creators specifically designed this 'feature'. Once again, as a reminder: an abstract class is just a blueprint for future 'normal' classes. You don't need copies of the blueprint, right? And you don't create instances of an abstract class :) But if the
Now our program has some sort of incomprehensible car — it's not a truck, not a race car, not a sedan, and it's totally unclear what it is. This is the very 'abstract car' that doesn't exist in nature. We can provide the same example using animals. Imagine if
Console output: “Gas!" As you can see, we've implemented the first method in the abstract class, and not the second. As a result, our
As you can see, both have an
Let's take a look at what we have. The mysterious device simultaneously inherits Toaster and NuclearBomb. Both have
It's your old friend, the
Why classes are called 'abstract'
You probably remember what 'abstraction' is — we've already gone over it. :) If you forgot, fear not. Remember: it's a principle of OOP that says when designing classes and creating objects, we should identify only the entity's main properties and discard the minor. For example, if we're designing aSchoolTeacher
class, we hardly need a 'height' property. Indeed, this property is irrelevant for a teacher. But if we're creating a BasketballPlayer
class, then growth would be an important characteristic.
So listen. An abstract class is as abstract as they come — an unfinished 'blank' for a group of future classes. The blank can't be used as is. It's too 'raw'. But it describes certain state and general behavior that will be possessed by future classes that inherit the abstract class.
Examples of abstract Java classes
Consider a simple example with cars:This is what the simplest abstract class looks like. As you can see, it's nothing special :) Why would we need it? First of all, it describes our required entity, a car, in the most abstract way possible. There's a reason why we're using the word abstract. In the real world, there are no 'abstract cars'. There are trucks, race cars, sedans, coupes, and SUVs. Our abstract class is simply a 'blueprint' we will use later to create car classes.
This is very similar to what we talked about in the lessons on inheritance. But in those lessons, we had a Car class and its methods weren't abstract. But that solution has a number of drawbacks that are fixed in abstract classes. First and foremost, you can't create an instance of an abstract class:
Java's creators specifically designed this 'feature'. Once again, as a reminder: an abstract class is just a blueprint for future 'normal' classes. You don't need copies of the blueprint, right? And you don't create instances of an abstract class :) But if the
Car
class weren't abstract, we could easily create instances of it:
Now our program has some sort of incomprehensible car — it's not a truck, not a race car, not a sedan, and it's totally unclear what it is. This is the very 'abstract car' that doesn't exist in nature. We can provide the same example using animals. Imagine if
Animal
classes (abstract animals). It's unclear what kind of animal it is, what family it belongs to, and what characteristics it has. It would be strange to see that in your program. There are no 'abstract animals' in nature. Only dogs, cats, foxes, moles, etc.
Abstract classes deliver us from abstract objects. They give us basic state and behavior. For example, all cars should have a model, color, and maximum speed, and you should be able to apply the gas and brake. That's it. This is a general abstract plan. Next you design the classes you need.
Note: two methods in the abstract class are also designated as abstract, and they don't have any implementation. The reason is the same: abstract classes don't create default behavior for abstract cars. They just indicate what every car should be able to do.
However, if you do need default behavior, you can implement methods in an abstract class. Java doesn't prohibit this:
Console output: “Gas!" As you can see, we've implemented the first method in the abstract class, and not the second. As a result, our
Sedan
class's behavior is divided into two parts: if you call the gas()
method, the call 'rises' up to the Car
abstract parent class, but we overrode the brake()
method in the Sedan
class. This turns out to be very convenient and flexible.
But now our class isn't so abstract? After all, half of its methods are implemented.
This is actually a very important feature - a class is abstract if at least one of its methods is abstract. One of two methods, or at least one of a thousand methods — it makes no difference.
We can even implement all the methods and leave none of them abstract. Then it would be an abstract class without abstract methods. In principle, this is possible, and the compiler won't generate errors, but it's better to avoid it: The word abstract loses its meaning, and your fellow programmers will be very surprised :/
At the same time, if a method is marked with the word abstract, each child class must implement it or declare it as abstract. Otherwise, the compiler will generate an error.
Of course, each class can inherit only one abstract class, so in terms of inheritance there's no difference between abstract and ordinary classes. It doesn't matter if we inherit an abstract class or an ordinary one, there can be only one parent class.
Why Java doesn't have multiple inheritance of classes
We've already said that Java doesn't have multiple inheritance, but we haven't really explored why. Let's try to do that now. The fact is that if Java had multiple inheritance, child classes wouldn't be able to decide which specific behavior they should choose. Suppose we have two classes —Toaster
and NuclearBomb
:
As you can see, both have an
on()
method. For a toaster, it starts toasting. For a nuclear bomb, it sets off an explosion.
Oops: /
Now imagine that you decided (don't ask me why!) to create something in between. And thus you have a MysteriousDevice
class!
This code, of course, doesn't work, and we only provide it as an example 'but it could be':
Let's take a look at what we have. The mysterious device simultaneously inherits Toaster and NuclearBomb. Both have
on()
methods. As a result, if we call the on()
method, it's unclear which one should be invoked on the MysteriousDevice
object. There's no way the object could ever know.
And to top it all off: The NuclearBomb doesn't have an off()
method, so if we didn't guess right, it will be impossible to disable the device.
It is precisely because of this 'confusion', where the object doesn't know what behavior to exhibit, that Java's creators abandoned multiple inheritance. However, you will recall that Java classes can implement multiple interfaces.
By the way, in your studies, you've already encountered at least one abstract class!
Though maybe you didn't even notice :)
It's your old friend, the
Calendar
class. It's abstract and has several children. One of them is GregorianCalendar
. You already used it in the lessons about dates. :)
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.