Java Inheritance Example

Category: Java   Tags: Java, Java Basic, Java Inheritance

Inheritance is the process by which one object acquires the properties of another object. It supports the concept of hierarchical classification. Inheritance represents encapsulation property of object oriented programming.

Using inheritance an object need to only define attributes that make it unique within its class. It can inherit its general attributes from its parent class. In Java, inheritance has below syntax:

                          class SuperClass {

                          }

                          class SubClass extends SuperClass {

                          }
                        

extends keyword is used to inherit one class to other class. Here is a basic example:

InheritanceBasicExample.java

                          package com.tutorial.javabasic;

                          class A {
                              void a() {
                                  System.out.println("This is a()");
                              }
                          }

                          class B extends A {
                              void b() {
                                  System.out.println("This is b()");
                              }
                          }

                          public class InheritanceBasicExample {

                              public static void main(String s[]) {
                                  B b = new B();
                                  b.a();
                                  b.b();
                              }
                          }
                        

Output:

                          This is a()
                          This is b()
                        

Here class A is a super class, B is sub class that extend parent class A. A subclass like B can access both kind of method: parent class method and its own methods. Here you can see, an object of class B can access both method a() and b().

Member Accessibility in Inheritance

A subclass can access public, protected and default access modifier member of its parent class.

InheritanceAccessibiltyExample.java

                          package com.tutorial.javabasic;

                          class A {

                              private int i;
                              public int j;
                              int k;
                              protected int l;

                              void defaultAccessMethod() {
                                  System.out.println("Default access method");
                              }

                              private void privateMethod() {
                                  System.out.println("Private method");
                              }

                              public void publicMethod() {
                                  System.out.println("Public method");
                              }

                              protected void protectedMethod() {
                                  System.out.println("Protected method");
                              }
                          }

                          class B extends A {

                          }

                          public class InheritanceAccessibiltyExample {

                              public static void main(String s[]) {
                                  B b = new B();
                                  b.j = 10;
                                  b.k = 11;
                                  b.l = 12;
                                  b.defaultAccessMethod();
                                  b.publicMethod();
                                  b.protectedMethod();

                                  /*
                                  A subclass can not access a private method or variable.
                                  */
                                  // b.privateMethod();
                                  // b.i = 1000;
                              }
                          }
                        

Output:

                          Default access method
                          Public method
                          Protected method
                        

As you can see an instance of a subclass B can access all public, protected and default access modifier member of its parent class A.

private member like privateMethod() method and variable i is not accessible from subclass. To know more about Java access control check out Access Control in Java.

A Superclass Variable Can Reference a Subclass Object

In Java, a reference variable of a superclass can be assigned a reference to any subclass derived from that superclass. This is how a method call is decided dynamically. Here is one example:

DynamicRefExample.java

                          package com.tutorial.javabasic;

                          class A {

                              void test() {
                                  System.out.println("test() inside A");
                              }
                          }

                          class B extends A {
                              void test() {
                                  System.out.println("test() inside B");
                              }
                          }

                          class C extends A {
                              void test() {
                                  System.out.println("test() inside C");
                              }
                          }

                          public class DynamicRefExample {

                              public static void main(String s[]) {
                                  B b = new B();
                                  A a = new A();
                                  C c = new C();

                                  a.test();

                                  a = b;
                                  // This will call B's test() method
                                  a.test();

                                  a = c;
                                  // This will call C's test() method
                                  a.test();

                                  /*
                                  This will show compile time error as a child member can not
                                  be accessed using a parent class reference.
                                  */
                                  // a.b();
                              }
                          }
                        

Output:

                          test() inside A
                          test() inside B
                          test() inside C
                        

Here since A is parent class of class B and C, the statement a = b; and a = c; are a valid statement.

a.b() will throw error as you can't call a subclass method from a parent class object reference and this is because that a parent class has no knowledge about its subclass.

Dynamic method dispatch is the mechanism by which a call to an overridden method is resolved at run time, rather than compile time. This is how Java implements run-time polymorphism.

super Keyword

super is used to call superclass constructor and to access a member of the superclass that has been hidden by a member of a subclass.

InheritanceAccessibiltyExample.java

                          package com.tutorial.javabasic;

                          class A {

                              A() {
                                  System.out.println("Default constructor");
                              }

                              A(String str) {
                                  System.out.println(str);
                              }

                              void test() {
                                  System.out.println("test() inside A");
                              }
                          }

                          class B extends A {
                              B() {
                                  super();
                                  super.test();

                                  /*
                                    Error: call to super must be first statement in constructor
                                  */
                                  // super();
                              }

                              B(String str) {
                                  super(str);
                              }
                          }

                          public class InheritanceAccessibiltyExample {

                              public static void main(String s[]) {
                                  B b1 = new B();
                                  B b2 = new B("Hello");
                              }
                          }
                        

Output:

                          Default constructor
                          test() inside A
                          Hello
                        

  • super() will call the default constructor of class A.
  • super.test(); will call the test() method of class A.
  • super(str); will call the parameterized constructor of class A.
  • Call to super must be first statement in constructor.

Why Java Doesn't Support Multiple Inheritance?

The main problem with multiple inheritance is known as The Diamond Problem. From this link:

The "diamond problem" (sometimes referred to as the "deadly diamond of death"[4]) is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?

So to implement multiple inheritance in Java use interface. Here is one example:

MultipleInheritanceExample.java

                          package com.tutorial.javabasic;

                          interface InterfaceA {

                              public void test();
                          }

                          interface InterfaceB {

                              public void test();
                          }

                          interface InterfaceC extends InterfaceA, InterfaceB {

                              public void test();
                          }

                          class A implements InterfaceC {

                              @Override
                              public void test() {
                                  System.out.println("test() implemented inside class A");
                              }

                          }

                          public class MultipleInheritanceExample {

                              public static void main(String s[]) {
                                  A a = new A();
                                  a.test();
                              }
                          }
                        

Output:

                          test() implemented inside class A
                        

In Java interfaces are only declaring the methods and the actual implementation will be done by concrete classes implementing the interfaces. So there is no possibility of any kind of ambiguity in multiple inheritance in java interfaces.