Method Overriding in JAVA
Method Overriding in JAVA
Method overriding in Java is a feature that allows a subclass to provide a specific implementation of a method that is already defined in its superclass. When a subclass overrides a method, it provides its own version of the method with the same name, return type, and parameters as the method in the superclass. This allows the subclass to customize the behavior of the method while maintaining a common interface defined by the superclass.
overriding and Access Modifier
Final methods can not be overridden
Private methods can not be overridden
The overriding method must have the same return type
Invoking overridden method from sub-class
1.Overriding and Access Modifier
In Java, access modifiers play an essential role in method overriding. Access modifiers control the visibility and accessibility of methods in classes. When you override a method in a subclass, the rules regarding access modifiers are as follows:
Access Cannot Be More Restrictive: When you override a method in a subclass, you cannot reduce the visibility of the method compared to the method in the superclass. In other words, you cannot override a method with a more restrictive access modifier.
If the superclass method is public, the overriding method in the subclass can only be public.
If the superclass method is protected, the overriding method in the subclass can be protected or public.
If the superclass method has default (package-private) access, the overriding method in the subclass can have default or broader access (protected or public).
If the superclass method is private, it cannot be overridden at all because it is not visible in the subclass.
Return Type and Exceptions: The return type of the overriding method must be the same as or a subtype of the return type of the overridden method. Additionally, the overriding method can throw the same exceptions or subclasses of the exceptions thrown by the overridden method.
Here's an example demonstrating these rules:
class Animal {
public void eat() {
System.out.println("Animal eats.");
}
protected void sleep() {
System.out.println("Animal sleeps.");
}
void makeSound() {
System.out.println("Animal makes a sound.");
}
private void move() {
System.out.println("Animal moves.");
}
void jump() throws Exception {
System.out.println("Animal jumps.");
}
}
class Dog extends Animal {
// Correctly overrides the public method in the superclass
@Override
public void eat() {
System.out.println("Dog eats.");
}
// Correctly overrides the protected method in the superclass
@Override
protected void sleep() {
System.out.println("Dog sleeps.");
}
// Correctly overrides the default (package-private) method in the superclass
@Override
void makeSound() {
System.out.println("Dog barks.");
}
// This method cannot be overridden because it is private in the superclass
// @Override
// private void move() { }
// Correctly overrides the method with exceptions in the superclass
@Override
void jump() throws ArithmeticException {
System.out.println("Dog jumps.");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.eat();
myDog.sleep();
myDog.makeSound();
myDog.jump();
}
}
Output:-
Dog eats.
Dog sleeps.
Dog barks.
Dog jumps.
2.Final methods can not be overridded
In Java, the final keyword is used to mark a method, class, or variable as "final," which means it cannot be overridden or modified in any way by subclasses or derived classes. When a method is declared as final, it essentially serves as a constant and cannot be changed or overridden in any subclass.
Here's an example demonstrating the use of the final keyword for a method
class Parent {
// Can not be overridden
final void show() {}
}
class Child extends Parent {
// This would produce error
void show() {}
}
Output:-
13: error: show() in Child cannot override show() in Parent
void show() { }
^
overridden method is final
3.Static methods can not be overridden(Method Overriding vs Method Hiding
static methods in Java cannot be overridden in the same way as instance methods. Instead, they are subject to a concept called "method hiding" or "static method hiding." This behavior is different from method overriding, which is used for instance methods.
Here's a brief explanation of the differences between method overriding and method hiding in Java:
Method Overriding (Instance Methods):
Occurs when a subclass provides a specific implementation for an instance method that is already defined in its superclass.
The subclass method must have the same method signature (name, return type, and parameters) as the superclass method.
Dynamic method dispatch allows the appropriate method to be called at runtime based on the actual object type.
Example of method overriding:
class Animal {
void makeSound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Dog barks");
}
}
Animal myAnimal = new Dog();
myAnimal.makeSound(); // Calls Dog's makeSound method at runtime
Output:-
Dog barks
Method Hiding (Static Methods):
Occurs when a subclass defines a static method with the same name as a static method in its superclass.
The subclass method does not have to have the same method signature as the superclass method; it just needs the same name.
Method hiding is resolved at compile-time, based on the reference type (not the actual object type), and does not involve dynamic dispatch.
Example of method hiding:
class Parent {
static void staticMethod() {
System.out.println("Static method in Parent");
}
}
class Child extends Parent {
static void staticMethod() {
System.out.println("Static method in Child");
}
}
Parent parentReference = new Child();
parentReference.staticMethod(); // Calls Parent's staticMethod at compile-time
Output:-
Static method in Parent
4.Private methods can not be overridden
In Java, private methods cannot be overridden because they are not accessible outside the class in which they are declared. Method overriding is a mechanism that allows a subclass to provide a specific implementation for a method that is already defined in its superclass. However, for overriding to occur, the subclass method must have the same method signature as the superclass method and be accessible to the subclass.
Here's why private methods cannot be overridden:
Access Control: Private methods are declared with the private access modifier, which means they are only accessible within the class in which they are defined. They are not visible to subclasses or external classes.
Method Signature: For method overriding to take place, the subclass method must have the same method signature (name, return type, and parameters) as the superclass method. However, since private methods are not visible outside the class where they are declared, a subclass cannot access or override them.
Here's an example to illustrate this:
class Parent {
private void privateMethod() {
System.out.println("This is a private method in the Parent class.");
}
public void callPrivateMethod() {
privateMethod();
}
}
class Child extends Parent {
// Attempt to override a private method, which is not allowed
// @Override
// private void privateMethod() {
// System.out.println("This is an attempt to override a private method.");
// }
}
public class Main {
public static void main(String[] args) {
Parent parent = new Parent();
parent.callPrivateMethod(); // Calls the private method indirectly
Child child = new Child();
child.callPrivateMethod(); // Calls the private method indirectly from the Parent class
}
}
Output:
This is a private method in the Parent class.
This is a private method in the Parent class.
5.The overriding method must have the same return type
In Java, when you override a method, the overriding method must have the same method signature, which includes the same method name and parameter types. However, there is an exception to this rule when it comes to the return type. The return type of the overriding method can be a subtype (a more specific type) of the return type of the overridden method.
Here's the rule for the return type during method overriding:
The return type of the overriding method must be the same as or a subtype of the return type of the overridden method.
This rule allows for more specific return types in the subclass, which is known as covariant return types. Covariant return types were introduced in Java 5 as an enhancement to the language.
Here's an example to illustrate this concept
class Animal {
Animal reproduce() {
System.out.println("Animal reproduces");
return new Animal();
}
}
class Dog extends Animal {
@Override
Dog reproduce() { // Covariant return type
System.out.println("Dog reproduces");
return new Dog();
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Dog();
myAnimal.reproduce(); // Calls Dog's reproduce method
}
}
Output:-
Dog reproduces
6.Invoking overridden method from sub-class
Tinvoke an overridden method from a subclass in Java, you can use the super keyword followed by the method name. The super keyword is used to refer to the superclass and its members. When you use super.methodName(), you are explicitly invoking the method of the superclass, even if it has been overridden in the subclass.
Here's an example to illustrate how to invoke an overridden method from a subclass
class Parent {
void show() { System.out.println("Parent's ()"); }
}
// Inherited class
class Child extends Parent {
// This method overrides show() of Parent
@Override void show()
{
super.show();
System.out.println("Child's ()");
}
}
// Driver class
class Main {
public static void main(String[] args)
{
Parent obj = new Child();
obj.show();
}
}
Output:-
Parent's ()
Child's ()