Java. Inheritance. Overriding and overloading inherited methods. Polymorphism. Dynamic methods dispatching




Inheritance. Overriding and overloading inherited methods. The super keyword. Examples. Dynamic dispatch of methods. Polymorphism


Contents


Search other websites:

1. What is an overriding of method?

Method overriding is a case in which the subclass and superclass contain methods that have the same name and type signature (Figure 1). Overriding of a method occurs when classes form an inheritance hierarchy. 

Java. Inheritance. Example of overriding the method of superclass A in subclass B

Figure 1. An example of overriding the method() method of superclass A in subclass B

In Figure 1, class B inherits (extends) class A. Class A is a superclass for class B. In subclass B, a method is declared with the same name as in superclass A. So, in this case, the method named method() of superclass A is overridden in subclass B.

 

2. What is the difference between overriding and method overloading?

In the inheritance hierarchy, superclass and subclass methods can be overridden and overloaded.

There are the following differences between overriding and overloading a method:

  • when overridden, superclass and subclass methods have the same name and the same parameters type signature (see Figure 1);
  • when overloaded, the methods of the superclass and subclass have the same name but different signatures of parameters types. Figure 2 shows the method overload in the inheritance hierarchy.

Java. Inheritance. An example of a method overload in classes A, B, C which form a hierarchy

Figure 2. An example of a method overload named method() in classes A, B, C which form a hierarchy

Figure 2 shows 3 classes with the names A, B, C which form the inheritance hierarchy. Class B inherits class A. Class C inherits class B. All classes have different methods that have the same name method(). The method parameters in each class are different. This means that the method() method is overloaded.

 

3. The rule of interaction between superclass and subclass methods that have the same name and signature. Example

If methods are implemented in the superclass and subclass that have the same name and parameter type signature, the following rule applies:

  • the method from the subclass overrides the method of the superclass.

Figure 3 schematically shows the rule of interaction between the methods of the same superclass and subclass of the same name.

Java. Inheritance. Demonstration of overriding a superclass method in a subclass method

Figure 3. Demonstration of overriding a superclass method in a subclass method

Figure 3 shows an example of overriding a superclass method in a subclass. Three classes are declared with the names A, B, C. In each class, a method is implemented with the name method() without parameters. This method has the same signature in all classes.

Each class object (instance) calls the class method for which it was declared. From the objB instance, the method() method is called, which is implemented in class B. From the objC instance, the method() method is called, which is implemented in class C.

Below is the text of the program demonstrating the redefinition of the methods shown in Figure 3.

// superclass
class A {
    void method() {
        // a method of class A
        System.out.println("Method A");
    }
}

// subclass of class A
class B extends A {
    void method() {
        // class B method
        System.out.println("Method B");
    }
}

// subclass of class B
class C extends B {
    void method() {
        // class C method
        System.out.println("Method C");
    }
}

public class Train01 {

    public static void main(String[] args) {
        A objA = new A();
        B objB = new B();
        C objC = new C();

        obj.method(); // invoke the method() of class A
        obj.method(); // invoke the method() of class B
        obj.method(); // invoke the method() of class C
    }
}

The result of the program

Method A
Method B
Method C

 

4. Getting access from a subclass method to a superclass method in the case when the names of the methods and the signatures of their parameters match. Keyword super. Example

Sometimes you need to gain access from a subclass method to a superclass method that has the same name and parameters signature. In this case, the super keyword is used.

Figure 4 shows access to the superclass A method from subclass B. In subclass B there is a method with the same name and a list of parameters, therefore, this method overrides the method of the superclass. To access the superclass A method in the subclass B method, the keyword super is used.

Java. Inheritance. Calling a superclass method from a subclass method using the super keyword

Figure 4. Calling a superclass method from a subclass method using the super keyword

The text of the program that demonstrates Figure 4 next

// superclass
class A {
    void method() {
        // method of class A
        System.out.println("Method A");
    }
}

// subclass of class A
class B extends A {
    void method() {
        // class B method, overrides class A method
        System.out.println("Method B");
    }

    void method2() {
        System.out.println("Method2 - B");
        super.method(); // call to superclass A method
    }
}

public class Train01 {
    public static void main(String[] args) {
        B obj = new B(); // an instance of class B
        objB.method2();
    }
}

The result of the program

Method2 - B
Method A

 

5. An example that demonstrates the overloading of methods in classes that form the inheritance hierarchy

If classes form a hierarchy by inheritance, then in these classes the names of the methods may coincide.

A method is considered to be overloaded (not overrided) if:

  • in different classes there is a method with the same name;
  • the signature of the method parameters in each class is different.

Thus, methods with different signatures are considered overloaded and not overrided.

Figure 5 shows an example of method overloading with the name method().Three classes are declared with the names A, B, C which form a hierarchy. In class A, a method named method() is implemented without parameters. In class B, the method named method() is implemented with one parameter of type int. In class C, the method named method() is implemented with one parameter of type double.

Java. Inheritance. Overloading a method in classes that form a hierarchy

Figure 5. Overloading a method named method() in classes that form a hierarchy

The text of the program that shows Figure 5 is as follows

// superclass
class A {
    void method() {
        // method of class A
        System.out.println("Class A. Method without parameters.");
    }
}

// subclass of class A
class B extends A {
    void method(int t) {
        // method of class B
        System.out.println("Class B. Method with 1 parameter of type int: "+t);
    }
}

// subclass of class B
class C extends B {
    void method(double x) {
        // method of class C
        System.out.println("Class C. Method with 1 parameter of type double: "+x);
    }
}

public class Train01 {

    public static void main(String[] args) {
        C obj = new C(); // instance of class C

        obj.method(); // calling a method without parameters of class A
        obj.method(5); // calling a method of class B
        obj.method(9.75); // calling a method of class C
    }
}

The result of the program

Class A. Method without parameters.
Class B. Method with 1 parameter of type int: 5
Class C. Method with 1 parameter of type double: 9.75





 

6. What is a dynamic dispatch of methods? An example of the implementation of polymorphism in Java

Dynamic method dispatch is one of the most effective principles of object-oriented programming.

Dynamic dispatch of methods is a special mechanism that allows you to call an overridden method during runtime and not at compile time. Dynamic method dispatching is important when implementing polymorphism.

Figure 6 demonstrates dynamic dispatch of methods. Implemented 3 classes with names A, B, C which form a hierarchy. Each class has a method named method(). The method signature in all classes is the same.

Java. Inheritance. Demonstration of dynamic dispatching of methods for three classes that form a hierarchy

Figure 6. Demonstration of dynamic dispatching of methods for three classes that form a hierarchy

At the beginning of the demonstration code (Figure 6) the refA reference to the base class A is declared.

A refA;

Now this reference can be assigned the value of a reference to a subclass of class A.

Thus, using the reference refA, you can call methods of instances of classes A, B, C which form a hierarchy. If refA refers to an instance of class A, then the line

refA.method();

will call a method with the name method() of class A.

Similarly, if the refA reference refers to an instance (object) of class B, then

refA.method();

will call the appropriate class B method.

The above applies to class C.

As can be seen from Figure 6, the corresponding variant of the method() method is determined by the type of the object referenced by the refA reference, and not by the type of this reference at the time of its declaration.

Below is the program code that demonstrates the dynamic dispatching of methods, shown in Figure 6.

// superclass
class A {
    void method() {
        // method of class A
        System.out.println("Class A");
    }
}

// subclass of class A
class B extends A {
    void method() {
        // method of class B
        System.out.println("Class B");
    }
}

// subclass of class B
class C extends B {
    void method() {
        // method of class C
        System.out.println("Class C");
    }
}

public class Train01 {

    public static void main(String[] args) {
        // instances of classes A, B, C
        A objA = new A();
        B objB = new B();
        C objC = new C();

        // reference to superclass A
        A refA; // reference refA can be assigned to objA, objB, objC

        //
        refA = objA; // refA refers to an instance of class A
        refA.method(); // calling method() of class A

        //
        refA = objB; // refA -> objB
        refA.method(); // objB.method()

        //
        refA = objC; // refA -> objC
        refA.method(); // objC.method()
    }
}

The result of the program

Class A
Class B
Class C

 

7. An example demonstrating ways to implement polymorphism (dynamic method dispatch)

In programs, polymorphism can be implemented in two ways:

  • when assigning (=) a reference to the base class of an instance of any derived class. In this case, using a reference (through the ‘ . ‘ symbol), the overridden method of the instance that this reference is currently pointing to is called;
  • when implementing a method that receives as a parameter a reference to the base class. In this case, in the body of the method, the overridden method is called by reference (the method has a common name and signature in all classes of the hierarchy). Which overridden method will be called depends on the instance of which class the reference points to.

The following example demonstrates these two cases using the example of a hierarchy of three classes A, B, C. All classes have a Print() method without parameters.

// Some class hierarchy.
// All classes have a Print() method.
class A {
  public void Print() {
    System.out.println("A.Print()");
  }
}

class B extends A {
  public void Print() {
    System.out.println("B.Print()");
  }   
}

class C extends B {
  public void Print() {
    System.out.println("C.Print()");
  }
}

public class TrainPoymorphism {
  // A method that gets a reference to the base class A
  public static void CallPrint(A ref) {
    // call the Print() method of some class from the hierarchy by reference
    ref.Print();
  }

  public static void main(String[] args) {
    // Demonstration of polymorphism by the example 
    // of passing a parameter to the CallPrint() method

    // 1. Create instances of classes A, B, C
    A objA = new A();
    B objB = new B();
    C objC = new C();

    // 2. Create a reference to the base class in the hierarchy A <- B <- C
    A refA;

    // 3. Demonstration of polymorphism
    // 3.1. Demonstration of polymorphism via assignment =
    refA = objA;  // refA -> objA
    refA.Print(); // A.Print()

    refA = objB;  // refA -> objB
    refA.Print(); // B.Print()

    refA = objC;  // refA -> objC
    refA.Print(); // C.Print()

    System.out.println("-------------------");

    // 3.2. Demonstration of polymorphism by passing a reference 
    //      to the base class to the CallPrint method (A ref)
    refA = objA;     // refA -> objA
    CallPrint(refA); // A.Print()

    refA = objB;     // refA -> objB
    CallPrint(refA); // B.Print()

    refA = objC;     // refA -> objC
    CallPrint(refA); // C.Print()       
  }
}

Program result

A.Print()
B.Print()
C.Print()
-------------------
A.Print()
B.Print()
C.Print()

 


Related topics