Introduction to Java Method Overriding
Method Overriding is achieved when a subclass overrides non-static methods defined in the superclass, following which the new method implementation in the subclass that is executed.
The new method definition must have the same method signature (i.e., method name and parameters) and return type. Only parameter types and return type are chosen as criteria for matching method signature. So if a subclass has its method parameters as final it doesn’t really matter for method overriding scenarios as it still holds true. The new method definition cannot narrow the accessibility of the method, but it can widen it. The new method definition can only specify all or none, or a subset of the exception classes (including their subclasses) specified in the throws clause of the overridden method in the super class
A program to explain the different concepts of Java Method Overridding
class CustomException extends Exception {
}
class SuperClassWithDifferentMethods {
protected int field1 = 10;
protected static int field2 = 20;
public void method1() {
System.out.println("SuperClassWithDifferentMethods.method1()");
}
public final void method2() {
System.out.println("SuperClassWithDifferentMethods.method2()");
}
private void method3() {
System.out.println("SuperClassWithDifferentMethods.method3()");
}
private final void method4() {
System.out.println("SuperClassWithDifferentMethods.method4()");
}
public static void method5() {
System.out.println("SuperClassWithDifferentMethods.method5()");
}
public void method6() throws Exception {
System.out.println("SuperClassWithDifferentMethods.method6()");
}
private void method7() {
System.out.println("SuperClassWithDifferentMethods.method7()");
}
private void method8(int x) {
System.out.println("SuperClassWithDifferentMethods.method8()");
}
public static void method9() {
System.out.println("SuperClassWithDifferentMethods.method9()");
}
}
class OverridingClass extends SuperClassWithDifferentMethods {
public int field1 = 30;
public static int field2 = 40;
public void method1() {
System.out.println("OverridingClass.method1()");
}
//We can't override a public final method
/* public final void method2(){
System.out.println("OverridingClass.method2()");
}*/
private void method3() {
System.out.println("OverridingClass.method3()");
}
private final void method4() {
System.out.println("OverridingClass.method4()");
}
public static void method5() {
System.out.println("OverridingClass.method5()");
}
public void method6() throws CustomException {
System.out.println("OverridingClass.method6()");
}
public void method7() {
System.out.println("OverridingClass.method7()");
}
public void method8(final int x) {
System.out.println("OverridingClass.method8()");
}
//A static method cannot be overridden to be non-static instance method
/*public void method9() {
System.out.println("OverridingClass.method9()");
}*/
}
public class MethodOverridingDemo {
public static void main(String[] args) {
OverridingClass oc1 = new OverridingClass();
SuperClassWithDifferentMethods sc3 = new OverridingClass();
oc1.method1();
oc1.method2();
// Since its private, the below 2 methods are not visible
/* oc1.method3();
oc1.method4();*/
oc1.method5();
try {
oc1.method6();
} catch (CustomException e) {
e.printStackTrace();
}
oc1.method7();
oc1.method8(100);
System.out.println("oc1.field1 : " + oc1.field1);
System.out.println("oc1.field2 : " + oc1.field2);
System.out.println("sc3.field1 : " + sc3.field1);
System.out.println("sc3.field2 : " + sc3.field2);
sc3.method5();
OverridingClass overClass = new OverridingClass();
SuperClassWithDifferentMethods supClass = (SuperClassWithDifferentMethods) overClass;
supClass.method5();
supClass.method1();
}
}
Output
OverridingClass.method1()
SuperClassWithDifferentMethods.method2()
OverridingClass.method5()
OverridingClass.method6()
OverridingClass.method7()
OverridingClass.method8()
oc1.field1 : 30
oc1.field2 : 40
sc3.field1 : 10
sc3.field2 : 20
SuperClassWithDifferentMethods.method5()
SuperClassWithDifferentMethods.method5()
OverridingClass.method1()
SuperClassWithDifferentMethods.method2()
OverridingClass.method5()
OverridingClass.method6()
OverridingClass.method7()
OverridingClass.method8()
oc1.field1 : 30
oc1.field2 : 40
sc3.field1 : 10
sc3.field2 : 20
SuperClassWithDifferentMethods.method5()
SuperClassWithDifferentMethods.method5()
OverridingClass.method1()
Download MethodOverridingDemo.java
The new method definitions in the subclass OverridingClass have the same signature and the same return type as the methods in the superclass SuperClassWithDifferentMethods. The new overridden method6 definition specifies a subset of the exceptions (CustomException). The new overridden method7 definition also widens the accessibility to public from private. The overriding method8 also declares the parameter to be final, which is not a part of the method signature and Method Overriding holds good. A static method cannot be overridden to be non-static instance method as shown in the overridden method declaration of method9. A static method is class-specific and not part of any object, while overriding methods are invoked on behalf of objects of the subclass. There are no such restrictions on the fields, as for fields only the field names matter. A final method cannot be overridden, an attempt to which will result in a compile-time error. A private method is not accessible outside the class in which it is defined; therefore, a subclass cannot override it.
A subclass must use the ‘super’ keyword in order to invoke an overridden method in the superclass. A subclass cannot override fields of the superclass, but it can hide them. Code in the subclass can use the keyword super to access members, including hidden fields.
The following distinction between invoking instance methods on an object and accessing fields of an object must be noted. When an instance method is invoked on an object using a reference, it is the class of the current object denoted by the reference, not the type of the reference, that determines which method implementation will be executed. When a field of an object is accessed using a reference, it is the type of the reference, not the class of the current object denoted by the reference, that determines which field will actually be accessed. This is demonstrated in the above program
No comments:
Post a Comment