Brian
Level 41

Inheritance in Java

Published in the Java Developer group
Java is an object-oriented language. This means that everything in Java consists of classes and their objects, and obeys the paradigms of OOP (object-oriented programming). One such paradigm is inheritance, a mechanism in Java by which one class is allowed to inherit the features (fields and methods) of another class. Simply put, in Java, inheritance means creating new classes based on existing ones. Inheritance in Java - 1

Key Actors of Inheritance in Java

  • Inheritance is the concept that a class can partially or completely repeat the properties and methods of its parent (the class from which it inherits).
  • A child class, or subclass, or extended class, or derived class is a class that inherits from another class.
  • A parent class, superclass, or base class is a class that has a number of functions, and these functions can be passed (inherited) by another class (child class).
  • Method overriding is changing the behavior of a derived class method. This is usually more specific, refined behavior. If you override a method in the heir that is already in the parent class, it sort of replaces the parent method.
  • A class can have only one ancestor class, but each class can have many "children".

How it works

The inheritance chain is directed from the most abstract class to the more concrete one. That is, the superclass is the most abstract in the chain of classes. Often it is denoted as abstract (base class that doesn’t require an implementation). All further classes are more specific. For example, there is a class called “Gadget”. It can have a field (or state) “weight” field battery capacity, field charge level and methods (or behavior) “work” and charging. In this case, methods can be abstract, that is, they do not have a specific implementation. While we cannot say what kind of gadget it is, it is absolutely any rechargeable gadget. Let's create a Phone subclass of the Gadget class. It no longer needs to redefine the weight and battery, it simply inherits them from the abstract gadget. But the behavior of the work will need to be clarified. You can also add other fields “screen diagonal”, connectors, and so on. You can add a new method “Update operating system”. Next, we can create two more classes and both will be inherited from Phone, Android and iPhone. Both classes inherit all fields and methods of the Gadget and Smartphone, and the methods can be overridden. The first class needs a "Brand name" field, while the iPhone does not need this field, since only one company produces such smartphones.

class Gadget {
…
}
}
//subclass of Gadget class
class Phone extends Gadget {
…
}
//subclass of Phone class
class IPhone extends Phone {
…
}
//subclass of Phone class
class AndroidPhone extends Phone {
…
}
A child class inherits all public and protected members of the parent class. It doesn't matter what package the subclass is in. If the child class is in the same package as parent class, it also inherits the parent's package-private members. You can use inherited members as is, replace them, hide them, or add new members:
  • You can use Inherited fields directly such as any other fields.
  • You can declare a field in the child class that has the same name as in parent class. It’s hiding it (so better not to do it).
  • You can declare new fields in the child class (ones the parent class doesn’t have).
  • Inherited methods can be used directly without without overriding in the derived class.
  • Also you can write a new instance method in a subclass that has the same signature as a method in the parent class. This procedure overrides it.
  • You can declare new methods in the child class that weren’t declared in the Parent class.
  • You can write a subclass constructor that calls the superclass constructor either implicitly or with the super keyword.

Example

Let's create a base MusicalInstrument class with weight and trademark fields, as well as a work() method. We also define a constructor.

public class MusicalInstrument {
   int weight;
   String tradeMark;

   public MusicalInstrument(int weight, String tradeMark) {
       this.weight = weight;
       this.tradeMark = tradeMark;
   }

   public void work() {
       System.out.println("the instrument is playing...");
   }
}
It is completely unclear what kind of musical instrument it is and how to play it. Let's create a more specific instrument, the violin. It will have the same fields as in the Musical Instrument (they will be called in the constructor using the super keyword. We can also override the work method and create a method for setting the violin string by string.

public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

   @Override
   public void work() {
       System.out.println("THe violin's playing");

   }

   public void violinTuning () {
     System.out.println("I'm tuning 1st string...");
     System.out.println("I'm tuning 2nd string...");
     System.out.println("I'm tuning 3rd string...");
     System.out.println("I'm tuning 4th string...");
}


}
Let's create a Demo class to test the Violin class and see exactly how inheritance works.

public class InheritDemo {

   public static void main(String[] args) {

       Violin violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       violin.violinTuning();
       violin.work();
   }
}
In this case, the output of the program will be as follows:
I'm tuning 1st string... I'm tuning 2nd string... I'm tuning 3rd string... I'm tuning 4th string... THe violin's playing
That is, if there is an overridden method in the child class, then the ancestor method will no longer be called. What if it is not there? That is, the Violin class looks like this:

public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

  // @Override
 

 //  }

   public void violinTuning () {
       System.out.println("I'm tuning 1st string...");
       System.out.println("I'm tuning 2nd string...");
       System.out.println("I'm tuning 3rd string...");
       System.out.println("I'm tuning 4th string...");
   }

}
The output is:
I'm tuning 1st string... I'm tuning 2nd string... I'm tuning 3rd string... I'm tuning 4th string... the instrument is playing...
That is, the ancestor method will be automatically called. By the way, the child class can be defined through the ancestor, that is, to perform upcasting:

Parent parent = new Child()
This initialization is used to access only the members present in the parent class and the overridden methods. In our example it would be:

public class InheritDemo {

   public static void main(String[] args) {

       MusicalInstrument violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       //violin.violinTuning();
       violin.work();
   }
}
In such a case, we are not able to configure the violin method. However at the same time, the work() method of the descendant class will be called, if it exists.

The Java Platform Class Hierarchy

In Java, everything is made up of classes and they are subordinate to a hierarchy. The question arises: is there a class from which all the others are inherited? The answer is yes, indeed such a class exists. And it's called simply Object. The Object class from java.lang package, defines and implements behavior common to all classes, including those you create. In the Java platform, many classes derive directly from Object, other classes derive from some of these classes, and so on, forming a class hierarchy. Inheritance in Java - 2

Types of Inheritance in Java

Let’s highlight a few types of inheritance in Java. 1. Single Inheritance This type is just like in our example above, subclasses inherit the features of one super class. In the image below, class A serves as a base class for the derived class B. 2. Multilevel Inheritance This is just a chain of inheritance, that is, there is a base class A, class B is inherited from it, and class C is inherited from class B. In Java, a class cannot directly access the grandparent’s members. 3. Hierarchical Inheritance In Hierarchical Inheritance, one class serves as a super class (base class) for more than one subclass. Above, we gave an example of the Phone class, which can have two "children" — AndroidPhone and IPhone.

class A {
    public void printA() { 
System.out.println("A");
 }
}
  
class B extends A {
    public void printB() {
 System.out.println(" B"); }
}
  
class C extends A {
    public void printC() { 
System.out.println("C"); 
}
}
  
class D extends A {
    public void printD() { 
System.out.println("D");
 }
}
  
public class Demo {
    public static void main(String[] args)
    {
        B objB = new B();
        objB.printA();
        objB.printB();
  
        C objC = new C();
        objC.printA();
        objC.printC();
  
        D objD = new D();
        objD.printA();
        objD.printD();
    }
}
The output is:
A B A C A D
4. Multiple inheritance, that is, the presence of several ancestors ... but wait, classic multiple inheritance isn’t supported in Java. To some extent, it can be implemented using not classes, but interfaces.

interface A {
   public void printA();
}

interface B {
   public void printB();
}

interface C extends A, B {
   public void print();
}
class InheritDemo implements C {
   @Override
   public void print()
   {
       System.out.println("Print something");
   }
  
   @Override
   public void printA() {      
   }

   @Override
   public void printB() {
   }
}
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION