Section 12.2 Subclasses and Inheritance
One option is to make it so that every
Course
object is also a Grade
object. We can do this by making a subclass, also sometimes called a derived class.A subclassB
of a classA
makes it so that its objects inherit all the properties and methods of objects of classA
. Objects of the subclass are also objects of the superclass. We sayB
extendsA
, or thatB
is derived fromA
. To accomplish this, classB
needs to indicate that it extends classA
, and its constructor must call classA
’s constructor.
For example, we can create a
Course
class as follows:public class Course extends Grade {
String prefix;
int number;
Course(String prefix, int number, String letterGrade) {
super(letterGrade);
this.prefix = prefix;
this.number = number;
}
}
So the first thing that you see is the phrase
extends Grade
. We have seen implements ...
before, and this works similar but for classes. That actually makes a huge difference, because classes have implementations of behavior, and by extending a class we are burdened by those implementations. Also unlike with interfaces, of which you can implement many, you can only ever extend one class.You may not have known or really care about this before, but there is always an implicit
extends Object
present in every class, if we don’t make it extend some other class instead. Thus the Object
class is the ancestor for all classes in Java.The next thing you will notice is the
super(letterGrade)
call. This is the call that reaches to the constructor of Grade
, so that that constructor can do its thing. This is important, as a Course
object is supposed to be a fully functioning Grade
object, on top of whatever else it is, and in order to ensure that we need to run the Grade
class’ constructor. And it must be the first thing in the subclass’ constructor.Now let’s take a look at a piece of code that uses a
Course
object:Course c = new Course("CS", 121, "B+");
c.prefix; // c is a Course
c.getCredits(); // c is also a Grade!
Once we make a
Course
object, we can access any properties and methods of the Course
class that we should have access to, like prefix
above, but we can also access anything that we could access if we had a Grade
object: Every Course
object is a bona fide Grade
object and can be used as such. Objects of a subclass can act as objects of its superclass. And we can do that without having to add any extra code, beyond the extends ...
line.This may sound strange at first, but let’s consider an analog for a second. I am going to assume that you are a student enrolled at a college or university. You are also a person, and we could say in a way that your
Student
status extends that of your Person
status, as every student is in fact a person. As a person we can ask you for your first and last name, or your gender and preferred pronouns; if we are your parents we can tell you to brush your teeth or wash your hands, and so on. You don’t lose any of these properties because you are a student, but you gain some new ones, like a student ID number and credentials, a list of courses you are enrolled in, your financial aid record, meal plan, what have you. There are things that every person has, and things only students have. We might represent this situation in code by having two classes, one called Student
and one called Person
, and the Student
class extends/derives from the Person
class.This is the essence of our first mechanism for object behavior extension, namely inheritance:
Inheritance is the feature of a programming language that allows objects of a subclass to inherit all the properties and methods of the superclass.Inheritance provides a very strong compile time binding of these properties to the object. Every object of the superclass will be having this relation to the objects of the superclass and that cannot change without a recompilation of the program. In an inheritance setting we have one object that has two classes and therefore has acquired the behavior of both classes.