Java Basics

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:

Java Inheritance Tutorial – 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 EmployeeSalariedEmployee 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

Download
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!

Sotirios-Efstathios Maneas

Sotirios-Efstathios (Stathis) Maneas is a PhD student at the Department of Computer Science at the University of Toronto. His main interests include distributed systems, storage systems, file systems, and operating systems.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Priya
6 years ago

Inheritance facilitates Reusability and is an important concept of OOPs. Many thanks for sharing this concept in brief.

Naveenkanth
Naveenkanth
5 years ago

thank you….Its more usable

Back to top button