Introducing Inheritance
- A Java class can inherit fields and methods from another class.
- Each Java class requires its own file, but only one class in a Java package needs a
main()
method. - Child classes inherit the parent constructor by default, but it’s possible to modify the constructor using
super()
or override it completely. - You can use
protected
andfinal
to control child class access to parent class members. - Java’s OOP principle of polymorphism means you can use a child class object like a member of its parent class, but also give it its own traits.
- You can override parent class methods in the child class, ideally using the
@Override
keyword. - It’s possible to use objects of different classes that share a parent class together in an array or
ArrayList
.
When you hear the word “inheritance”, code may not be the first thing that springs to mind; you’re probably more likely to think of inheriting genetic traits, like eye color from your mother or a smile from your grandfather. But inheritance is also an important feature of object-oriented programming in Java.
Suppose we are building a
Shape
class in Java. We might give it some points in 2D, a method for calculating the area, and another method for displaying the shape. But what happens if we want a class for a triangle that has some triangle-specific methods? Do we need to redefine all of the same methods that we created for Shape
?No! (Phew.) Lucky for us, a Java class can also inherit traits from another class. Because a
Triangle
is a Shape
, we can define Triangle
so that it inherits fields and methods directly from Shape
. The object-oriented principle of inheritance saves us the headache of redefining the same class members all over again.There are several terms you’ll encounter frequently:
- Parent class, superclass, and base class refer to the class that another class inherits from (like
Shape
). - Child class, subclass, and derived class refer to a class that inherits from another class (like
Triangle
).
- In Java, it is possible to inherit attributes and methods from one class to another. We group the "inheritance concept" into two categories:
- subclass (child) - the class that inherits from another class
- superclass (parent) - the class being inherited from
To inherit from a class, use theextends
keyword.Inheriting the Constructor
Hang on, you might be thinking if the child class inherits its parent’s fields and methods, does it also inherit the constructor? It does indeed, and sometimes this isn’t quite what we want.Let’s sayShape
has anumSides
the field that is set by passing an integer into the constructor. If we’re instantiating aTriangle
, we would want that number to always be3
, so we’d want to modify the constructor to automatically assignnumSides
with a value of3
.Can we do that?As it happens, Java has a trick up its sleeve for just this occasion: using thesuper()
the method which acts as the parent constructor inside the child class constructor:class Triangle extends Shape { Triangle() { super(3); } // additional Triangle class members }Bypassing3
tosuper()
, we are making it possible to instantiate aTriangle
without passing in a value fornumSides
.Meanwhile,super()
(behaving asShape()
) will shoulder the responsibility of settingnumSides
to3
for ourTriangle
object.
It is also possible to just completely override a parent class constructor by writing a new constructor for the child class:class Triangle extends Shape { Triangle() { this.numSides = 3; } // additional Triangle class members }In the above example,numSides
is just set to3
without leveraging the parent class constructor.Parent Class Aspect Modifiers
You may recall that Java class members useprivate
andpublic
access modifiers to determine whether they can be accessed from outside the class. So does a child class inherit its parent’sprivate
members?Well, no. But there is another access modifier we can use to keep a parent class member accessible to its child classes and to files in the package it’s contained in — and otherwise private:protected
.Here’s whatprotected
looks like in use:class Shape { protected double perimeter; } // any child class of Shape can access perimeterIn addition to access modifiers, there’s another way to establish how child classes can interact with inherited parent class members: using thefinal
keyword. If we addfinal
before a parent class method’s access modifier, we disallow any child classes from changing that method. This is helpful in limiting bugs that might occur from modifying a particular method.
Introducing Polymorphism
In Java, ifOrange
is aFruit
through inheritance, you can then useOrange
in the same contexts asFruit
like this:String makeJuice(Fruit fruit) { return "Apple juice and " + fruit.squeeze(); } // inside main() Orange orange = new Orange(); System.out.println(juicer.makeJuice(orange));Wait, how does that work?This is because Java incorporates the object-oriented programming principle of polymorphism. Polymorphism, which derives from the Greek meaning “many forms”, allows a child class to share the information and behavior of its parent class while also incorporating its own functionality.The main advantages of polymorphic programming:- Simplifying syntax
- Reducing cognitive overload for developers
These benefits are particularly helpful when we want to develop our own Java packages for other developers to import and use.For example, the built-in operator+
can be used for bothdouble
s andint
s. To the computer, the+
means something likeaddDouble()
for one andaddInt()
for the other, but the creators of Java (and of other languages) didn’t want to burden us as developers with recalling each individual method.Note that the reverse situation is not true; you cannot use a generic parent class instance where a child class instance is required. So anOrange
can be used as aFruit
, but aFruit
cannot be used as anOrange
.Method Overriding
One common use of polymorphism with Java classes is something we mentioned earlier — overriding parent class methods in a child class. Like the+
operator, we can give a single method slightly different meanings for different classes. This is useful when we want our child class method to have the same name as a parent class method but behave a bit differently in some way.Let’s say we have aBankAccount
class that allows us to print the current balance. We want to build aCheckingAccount
class that inherits the functionality of aBankAccount
but with a modifiedprintBalance()
method. We can do the following:class BankAccount { protected double balance; public void printBalance() { System.out.println("Your account balance is $" + balance); } } class CheckingAccount extends BankAccount { public void printBalance() { System.out.println("Your checking account balance is $" + balance); } }Notice that in order to properly overrideprintBalance()
, inCheckingAccount
the method has the following in common with the corresponding method inBankAccount
:- Method name
- Return type
- Number and type of parameters
You may have also noticed the@Override
keyword aboveprintBalance()
inCheckingAccount
. This annotation informs the compiler that we want to override a method in the parent class. If the method doesn’t exist in the parent class, we’ll get a helpful error when we compile the program.Child Classes in Arrays and ArrayLists
Usually, when we create an array or anArrayList
, the list items all need to be the same type. But polymorphism puts a new spin on what is considered the same type…In fact, we can put instances of different classes that share a parent class together in an array orArrayList
! For example, let’s say we have aMonster
parent class with a few child classes:Vampire
,Werewolf
, andZombie
. We can set up an array with instances of each:Monster dracula, wolfman, zombie1; dracula = new Vampire(); wolfman = new Werewolf(); zombie1 = new Zombie(); Monster[] monsters = {dracula, wolfman, zombie1};We can even iterate through the list of items — regardless of subclass — and perform the same action with each item:for (Monster monster : monsters) { monster.attack(); }In the code above, we were able to callattack()
on each monster inmonsters
despite the fact that, in the for-each loop,monster
is declared as the parent class typeMonster
.
ReplyDeleteYour blog is very informative. i have learned so many thing from your blog.
https://viitorcloud.com/hire-python-developer
ReplyDeleteyour blog is so informative .I have learned so many things from your blog.
https://viitorcloud.com/hire-python-developer
ReplyDeleteyour blog is so informative .I have learned so many things from your blog.
https://viitorcloud.com/hire-python-developer
ReplyDeleteyour blog is so informative .I have learned so many things from your blog.
https://viitorcloud.com/hire-python-developer
ReplyDeleteYour blog is really good.I have learned so many things from your blog.
https://viitorcloud.com/hire-python-developer
ReplyDeleteYour blog is very informative.I have learned so many things from your blog.
https://viitorcloud.com/hire-python-developer
This comment has been removed by a blog administrator.
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDelete