Java Inheritance Example
In this tutorial, we will discuss the inheritance in Java. The most fundamental element of Java is the class. A class represents an entity and also, defines and implements its functionality. In Java, classes can be derived from other classes by using the extends keyword, in order to create more complex relationships.
You can also check this tutorial in the following video:
1. Introduction
A class that is derived from another class is called subclass and inherits all fields and methods of its superclass. In Java, only single inheritance is allowed and thus, every class can have at most one direct superclass. A class can be derived from another class that is derived from another class and so on. Finally, we must mention that each class in Java is implicitly a subclass of the Object
class.
Suppose we have declared and implemented a class A. In order to declare a class B that is derived from A, Java offers the extends keyword that is used as shown below:
1 2 3 4 5 6 7 8 | class A { //Members and methods declarations. } class B extends A { //Members and methods from A are inherited. //Members and methods declarations of B. } |
Java supports only public inheritance and thus, all fields and methods of the superclass are inherited and can be used by the subclass. The only exception is the private members of the superclass that cannot be accessed directly from the subclass. Also, constructors are not members, thus they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass. In order to call the constructor of the superclass Java provides the keyword super, as shown below:
01 02 03 04 05 06 07 08 09 10 11 12 | class A { public A() { System.out.println( "New A" ); } } class B extends A { public B() { super (); System.out.println( "New B" ); } } |
A sample example to present the inheritance in Java is shown below:
Animal.java
01 02 03 04 05 06 07 08 09 10 11 12 13 | public class Animal { public Animal() { System.out.println( "A new animal has been created!" ); } public void sleep() { System.out.println( "An animal sleeps..." ); } public void eat() { System.out.println( "An animal eats..." ); } } |
Bird.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | public class Bird extends Animal { public Bird() { super (); System.out.println( "A new bird has been created!" ); } @Override public void sleep() { System.out.println( "A bird sleeps..." ); } @Override public void eat() { System.out.println( "A bird eats..." ); } } |
Dog.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | public class Dog extends Animal { public Dog() { super (); System.out.println( "A new dog has been created!" ); } @Override public void sleep() { System.out.println( "A dog sleeps..." ); } @Override public void eat() { System.out.println( "A dog eats..." ); } } |
MainClass.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | public class MainClass { public static void main(String[] args) { Animal animal = new Animal(); Bird bird = new Bird(); Dog dog = new Dog(); System.out.println(); animal.sleep(); animal.eat(); bird.sleep(); bird.eat(); dog.sleep(); dog.eat(); } } |
In this example, we created three distinct classes, Animal
, Dog
and Bird
. Both Dog
and Bird
classes extend the Animal
class by using the java extends keyword and thus, they inherit its members and methods. Moreover, as we can see below, each class overrides the methods of Animal
and thus, both the Dog and Bird classes redefine the functionality of Animal’s
methods.
A sample execution is shown below:
A new animal has been created! A new animal has been created! A new bird has been created! A new animal has been created! A new dog has been created! An animal sleeps... An animal eats... A bird sleeps... A bird eats... A dog sleeps... A dog eats...
A nested class has access to all the private members of its enclosing class, both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.
As already mentioned, a subclass inherits all of the public and protected members of its superclass. If the subclass is in the same package as its superclass, it also inherits the package-private members of the superclass. The inheritance in Java provides the following features:
- You can declare a field in the subclass with the same name as the one in the superclass thus, hiding it. This is called shadowing.
- You can declare new fields in the subclass that are not in the superclass.
- You can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it.
- You can declare new methods in the subclass that are not in the superclass.
Final abstract classes can exist in a hierarchy of types. For more information about abstract classes and how they are used in Java, please refer to the Java abstract tutorial here.
2. Inheritance and Casting
In Java, When class B extends a class A, then an instance of the B class is of type B, but also of type A. Thus, such an instance can be used in all cases where a class B or class A object is required. However, the reverse is not true! An instance of the class A is of course of type A, but it is not of type B.
Thus, we can use casting between the instances of classes. The cast inserts a runtime check, in order for the compiler to safely assume that the cast is used properly and is correct. If not, a runtime exception will be thrown.
A simple example that demonstrates the usage of casting is shown below:
1 2 3 4 5 6 7 8 9 | Animal a1 = new Dog(); Animal a2 = new Bird(); a1.eat(); a2.sleep(); // The following statements are incorrect. // Dog d = new Animal(); // Bird b = new Animal(); |
A sample execution is shown below:
A dog eats... A bird sleeps...
3. The instanceof operator
The instanceof operator can be used, in order to determine if an object is a valid instance of a specific type. It can be used to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface. A simple example is shown below:
1 2 3 4 5 6 | Dog d = new Dog(); if (d instanceof Animal) { Animal a = (Animal) d; a.sleep(); } d.sleep(); |
4. Interfaces
An interface in Java is an abstract type that is used to declare and specify a set of public methods and members. An interface can be implemented by a class. In this case, the class must provide an implementation for every method defined in the interface. A significant advantage of using interfaces is the fact that in Java, multiple interfaces can be implemented by a single class.
A sample example that uses both classes and multiple interfaces are shown below:
BasketballTeam.java
1 2 3 | public interface BasketballTeam { public void printBasketballName(); } |
FootballTeam.java
1 2 3 | public interface FootballTeam { public void printFootballName(); } |
Team.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class Team implements BasketballTeam, FootballTeam { private String name = null ; public Team(String name) { this .name = name; } @Override public void printFootballName() { System.out.println( "Football Team: \"" + name + " F.C.\"" ); } @Override public void printBasketballName() { System.out.println( "Basketball Team: \"" + name + " B.C.\"" ); } public static void main(String[] args) { Team t = new Team( "Team A" ); t.printBasketballName(); t.printFootballName(); } } |
A sample execution is shown below:
Basketball Team: "Team A B.C." Football Team: "Team A F.C."
5. Single inheritance
A java class can be subclassed from a parent class. The subclass can use the methods and properties of the parent class. The example below shows how the parent class Employee
is implemented.
Employee
public class Employee { private String name; private String id; private int age; public Employee() { } public Employee(String name, String id, int age) { this.name = name; this.id = id; this.age = age; } public int getAge() { return age; } public String getName() { return name; } public String getId() { return id; } public void setAge( int age) { this.age = age; } public void setName(String name) { this.name = name; } public void setId( String id) { this.id = id; } }
SalariedEmployee
class is subclassed from Employee
. SalariedEmployee
class has empSalary
property. The implementation of the SalariedEmployee
class is shown below.
Salaried Employee
public class SalariedEmployee extends Employee { private double empSalary; public SalariedEmployee(String name, String id, int age, double empSalary) { super(name, id, age); setEmpSalary(empSalary); } public double getEmpSalary() { return empSalary; } public void setEmpSalary(double empSalary) { if(empSalary >= 0.0) { this.empSalary = empSalary; } } }
6. Multilevel inheritance
In Multilevel Inheritance, inheritance is implemented at multiple levels.For example, a class Person
serves as a base class for the derived class Employee
. Employee
class serves as a base class for the derived class Manager
.
You can look at the implementation of the Person
class which is the base class. Person
class has attributes name
, id
, and age
.
Person
/** * @author bhagvan.kommadi * */ public class Person{ private String name; private String id; private int age; public Person() { } public Person(String name, String id, int age) { this.name = name; this.id = id; this.age = age; } public int getAge() { return age; } public String getName() { return name; } public String getId() { return id; } public void setAge( int age) { this.age = age; } public void setName(String name) { this.name = name; } public void setId( String id) { this.id = id; } }
Now, we look at the Employee
which is the derived class of the Person
base class. Employee
class has attributes department
and designation
.
Employee
public class Employee extends Person{ private String department; private String designation; public Employee() { } public Employee(String name, String id, int age,String department,String designation) { super(name,id,age); this.department = department; this.designation = designation; } /** * @return the department */ public String getDepartment() { return department; } /** * @param department the department to set */ public void setDepartment(String department) { this.department = department; } /** * @return the designation */ public String getDesignation() { return designation; } /** * @param designation the designation to set */ public void setDesignation(String designation) { this.designation = designation; } }
Below is the implementation of the Manager
class which is derived from the Employee
class. The Manager
class has the attribute reports who are the employees working under the manager and the java extends keyword is used to .
Manager
/** * @author bhagvan.kommadi * */ public class Manager extends Employee { private Employee[] reports; public Manager() { } /** * @return the reports */ public Employee[] getReports() { return reports; } /** * @param reports the reports to set */ public void setReports(Employee[] reports) { this.reports = reports; } }
7. Hierarchical Inheritance
In Hierarchical Inheritance, A single class has multiple derived classes. For example, the class Employee
serves as a base class for the derived class SalariedEmployee
, ContractEmployee
and VendorEmployee
.
You can see below the Employee
class implementation. Employee
class has attributes name
, id
, and age
.
Employee
public class Employee { private String name; private String id; private int age; public Employee() { } public Employee(String name, String id, int age) { this.name = name; this.id = id; this.age = age; } public int getAge() { return age; } public String getName() { return name; } public String getId() { return id; } public void setAge( int age) { this.age = age; } public void setName(String name) { this.name = name; } public void setId( String id) { this.id = id; } }
Now we look at PermanentEmployee
implementation. PermanentEmployee
derives from Employee
class. PermanentEmployee
has an attribute salary
.
PermanentEmployee
/** * @author bhagvan.kommadi * */ public class PermanentEmployee extends Employee { private int salary; /** * @return the salary */ public int getSalary() { return salary; } /** * @param salary the salary to set */ public void setSalary(int salary) { this.salary = salary; } }
ContractEmployee
class is derived from Employee
. class. ContractEmployee
has attributes contractAmount
and contract
period. The implementation is shown below:
ContractEmployee
/** * @author bhagvan.kommadi * */ public class ContractEmployee extends Employee{ private int contractPeriod; private int contractAmount; /** * @return the contractPeriod */ public int getContractPeriod() { return contractPeriod; } /** * @return the contractAmount */ public int getContractAmount() { return contractAmount; } /** * @return the contractPeriod */ public int getContractPeriod() { return contractPeriod; } /** * @param contractPeriod the contractPeriod to set */ public void setContractPeriod(int contractPeriod) { this.contractPeriod = contractPeriod; } }
Now, we see at the implementation of the VendorEmployee
class. VendorEmployee
class has an attribute Vendor
name.
VendorEmployee
/** * @author bhagvan.kommadi * */ public class VendorEmployee extends Employee { private String vendor; /** * @return the vendor */ public String getVendor() { return vendor; } /** * @param vendor the vendor to set */ public void setVendor(String vendor) { this.vendor = vendor; } }
8. Download the Source Code
You can download the Eclipse project of this example: Java Inheritance Example
Last updated on Mar. 03rd, 2020
Don’t forget to check out our Academy premium site for advanced Java training!
Inheritance facilitates Reusability and is an important concept of OOPs. Many thanks for sharing this concept in brief.
thank you….Its more usable