Method Overriding In Java | Rules, Use-Cases & More (+Examples)
Table of content:
- What Is Method Overriding In Java?
- Example Of Method Overriding In Java
- Ideal Use Cases Of Method Overriding In Java
- Rules For Method Overriding In Java
- Super Keyword & Method Overriding In Java
- Constructor & Method Overriding In Java
- Exception Handling In Method Overriding In Java
- Access Modifiers In Method Overriding In Java
- Advantages & Disadvantages Of Method Overriding In Java
- Difference Between Method Overloading Vs. Method Overriding In Java
- Conclusion
- Frequently Asked Questions
Imagine you have an old family recipe passed down for generations. And while you follow most of it, you like to add a few of your own touches—a pinch of spice here, a twist in flavor there—to make it uniquely yours. This is what method overriding in Java is about, but for methods/functions.
In technical terms, you inherit a method from a superclass (like the recipe) but redefine it in your subclass (your own version) to suit specific needs. In this article, we will discuss method overriding in Java in detail, including its rules, implementations, use cases, pitfalls, and more, with proper code examples.
What Is Method Overriding In Java?
Method overriding is a powerful concept in Java that allows a subclass (or child class) to redefine a method inherited from its superclass (or parent class). This is especially useful when the implementation of the inherited method doesn’t fully serve the subclass's needs.
- By overriding, the subclass provides its own implementation of a method that already exists in the superclass, customizing its behavior as required.
- In method overriding, both the superclass and the subclass contain a method with the same name/ identifer, return type, and parameters (signature).
- When the subclass redefines this method, it effectively "overrides" the version in the superclass, replacing the inherited behavior with its own.
This allows objects to exhibit different behaviors based on their runtime types—a concept known as runtime polymorphism or dynamic method dispatch. With runtime polymorphism, the method that gets executed is chosen at runtime, depending on the object’s actual type.
Syntax For Method Overriding In Java:
class Superclass {
// Superclass method
returnType methodName() {
// Method implementation in superclass
}
}class Subclass extends Superclass {
// Subclass method overriding the superclass method
@Override
returnType methodName() {
// Method implementation in subclass
}
}
Here,
- The Superclass is the base class containing the method to be overridden.
- The Subclass is the child class that extends the superclass and provides a custom implementation.
- The returnType specifies the type of value returned, like int or String.
- methodName is the identifier or name of the method, matching the one in the superclass.
- The @Override annotation signals that the method in the subclass is intended to override one in the superclass, ensuring the method signatures match exactly.
In the syntax above, the superclass method provides default behavior, while the subclass method customizes it to meet specific needs.
Example Of Method Overriding In Java
Now that we've got some idea about the syntax of method overriding in Java, let’s look at an example that showcases how method overriding works in real code scenarios.
Code Example:
Output:
Inside Parent's display method.
Inside Child's display method.
Inside Child's display method.
Explanation:
In the simple Java code example,
- We begin by defining a parent/ base class called Parent, containing a simple void method, display().
- The method uses println() method to display the string/ message– "Inside Parent's display method" when called.
- Then, we create a child/ subclass called Child that extends the Parent class. Inside:
- We override the display() method from the Parent class.
- First, we use the annotation/ keyword @Override to indicate that this function must override another one.
- Then, we define the display() method, which prints the message– "Inside Child's display method." when called on a Child object instead of the parent's version.
- Next, we define the Main class, which serves as the entry point for executing our program. Inside, we create objects for both classes, i.e., Parent (parent) and Child (child), using the new operator with respective constructors.
- We then call the display() method using the parent object, which invokes the method defined in the Parent class and prints the respective message.
- Then, we call the display() method using the child object, which invokes the overridden method in the Child class, printing the child-specific message.
- This is a direct demonstration of method overriding in Java, where the child class provides a specific implementation for a method that is already defined in the parent class.
- Now, we introduce polymorphism, for which we create a reference of type Parent but assign it an object of type Child.
- This is allowed because Child is a subclass of Parent, meaning a Child object can be referred to by a Parent reference.
- Then, when we call the display() method using the polymorphicRef reference, it might seem like the display() method of the Parent class should be called.
- However, due to dynamic method dispatch, Java determines at runtime which method to call based on the actual object type, not the reference type. Since polymorphicRef points to an instance of Child, the overridden display() method in Child is called, and it prints the child's message.
Want to expand your knowledge of Java programming? Check out this amazing course and become the Java developer of your dreams.
Ideal Use Cases Of Method Overriding In Java
Method overriding can be ideal in scenarios where we want to provide a specific implementation of a method in a subclass that is different from the implementation in the respective superclass. Following are some of the specific use cases where method overriding in Java can prove to be beneficial:
- Implementing Runtime Polymorphism: Method overriding is a core mechanism behind runtime polymorphism in Java. It allows a subclass to provide its own implementation of a method that exists in its superclass. This makes it possible for objects of different types to respond to the same method call in different ways, depending on their actual type at runtime.
- Customizing Behavior: Method overriding enables customization of behavior inherited from a superclass. If a subclass needs to alter or extend the functionality of an inherited method, it can simply override the method with a more specialized implementation suited to its requirements.
- Enhancing Reusability: Method overriding in Java allows us to reuse the same method name and signature (from superclass) across subclasses. This promotes code reusability by allowing subclasses to retain the same method interface but customize the functionality, reducing code duplication.
- Implementing Abstract Methods: If a class extends an abstract class or implements an interface, it must provide concrete implementations for all abstract methods defined in the superclass. Method overriding in Java helps implement these abstract methods, making the subclass a concrete class.
- Enabling Dynamic Dispatch: With method overriding, Java achieves dynamic dispatch, where the JVM determines which method implementation to invoke based on the actual type of the object at runtime. This flexibility is essential in scenarios where you manipulate objects of different subclasses via a common superclass or interface reference.
- Framework and Library Extensions: Method overriding in Java is commonly used in frameworks and libraries to extend or customize the behavior of existing classes without modifying their source code. By overriding methods in these predefined classes, we can create custom components or behaviors that fit the specific needs of our application.
In short, method overriding enables customization, extensibility, and polymorphism in Java applications, making the codebase more flexible, scalable, and easier to maintain.
Rules For Method Overriding In Java
Method overriding is essential for creating flexible, large-scale programs, enabling subclasses to modify inherited methods to meet specific needs. While the concept is crucial, it's also vital to understand the rules that govern how a subclass can override a method from its superclass.
These rules provide a structure for modifying inherited methods without breaking functionality, ensuring that your code remains adaptive and cohesive. Here are key rules you must note when working with method overriding in Java:
1. Access Modifiers & Method Overriding In Java
When overriding a method, we cannot reduce the visibility of the method in the subclass. The order of access modifiers from most restrictive to least restrictive is:
private < default (package-private) < protected < public.
This means you can increase the visibility (e.g., from protected to public) but not decrease it (e.g., from public to protected). We will discuss this in detail in a later section.
2. Method Signature For Superclass & Subclass Must Be Same For Method Overriding In Java
The method signature (name, return type, and parameter list) in the subclass must be identical to the one in the superclass.
3. Exceptions & Method Overriding In Java
When a subclass method overrides a parent method, it can throw unchecked exceptions (like RuntimeException), even if the parent method doesn’t throw any exceptions. However, it should not throw new checked exceptions (like IOException) or exceptions that are more general than those thrown by the parent method. The overriding method can throw fewer or more specific exceptions than the parent, which allows the subclass to limit the types of exceptions it throws compared to the parent.
4. Constructors Cannot Be Overridden
In Java, constructors are not inherited by subclasses, so they cannot be overridden. Each class must define its own constructor, and while a subclass can call a superclass constructor using super(), it doesn’t override it.
5. Final Methods Cannot Be Overridden In Java
The final keyword can be used to mark a method as final, meaning it cannot be overridden in any subclass. This ensures that the method’s implementation remains consistent across all subclasses.
Suppose you have a superclass Shape with a final method calculateArea(), to calculate the area of the shape. Let’s see what happens when we try to override this method in a subclass.
Code Example:
Output:
Main.java:17: error: calculateArea() in Circle cannot override calculateArea() in Shape
public double calculateArea() {
^
overridden method is final
1 error
Explanation:
The method calculateArea() in the Shape class is marked as final, which prevents any subclass from overriding it. Trying to override it in the Circle subclass results in a compilation error.
6. Static Methods Cannot Be Overridden
Static methods are resolved at compile time and are tied to the class, not the instance of the class. As a result, static methods cannot be overridden. If a subclass defines a static method with the same signature as a static method in its superclass, it's considered method hiding, not overriding.
Say a superclass Animal has a static method eat() that represents a general eating behavior for all animals. We then have a subclass Dog that attempts to override eat() with a non-static method eat() to represent a specific eating behavior for dogs. The Java program example below highlights how this works.
Code Example:
Output:
Main.java:10: error: eat() in Dog cannot override eat() in Animal
public void eat() {
^
overridden method is static
1 error
Explanation:
In the example above, the Dog class tries to override the static method eat(), which is not allowed in Java. Static methods belong to the class itself and do not support polymorphism. The error message indicates that we can't override static methods with instance methods.
7. Private Methods Can Not Be Overridden
Private methods, that is, methods defined with the private access specifier, are not visible to subclasses. So, they cannot be overridden. If a subclass defines a method with the same signature as a private method in the superclass, it’s treated as a new, separate method, not an override. The simple Java program example below illustrates this concept.
Code Example:
Output:
Private method in superclass.
Explanation:
Even though Subclass has a method privateMethod() that has the same signature as the one in Superclass, it doesn't override it because private methods are inaccessible to subclasses. When calling callPrivateMethod(), the method from Superclass is executed, as private methods in Superclass are not overridden.
8. The Overriding Method Must Have the Same Return Type (or Subtype)
The return data type of the overriding method in Java subclasses must be the same as, or a subtype of, the return type of the overridden method in the superclass. This feature, known as the covariant return type, was introduced in Java 5.0.
Code Example:
Output:
Dog
Explanation:
In this example, the method getAnimal() in Dog returns a Dog object, which is a subtype of Animal. This is a valid example of covariant return types, where the overriding method can have a more specific return type than the overridden method in the superclass.
Here is your chance to top the leaderboard while practising your coding skills: Particiapte in the 100-Day Coding Sprint at Unstop.
Super Keyword & Method Overriding In Java
In Java, the super keyword is used to refer to the superclass of the current object, allowing a subclass to access superclass members directly. This can include calling superclass methods ( despite overriding the same method), accessing superclass variables, and invoking superclass constructors.
Syntax:
super.methodName(); // Calling superclass method
super.variableName; // Accessing superclass variable
super(); // Calling superclass constructor
Use Cases Of super Keyword In Method Overriding In Java
The primary use cases of super keyword include the following three situations:
1. Invoking Immediate Parent Class Method
When a subclass overrides a method, the super keyword can be used to call the overridden method from the parent class. This is particularly useful if you want to extend or modify the behavior of the parent method while still retaining access to its original functionality.
Code Example:
Output:
Parent class method
Child class method
Explanation:
In the Java example code,
- We first define a base class Parent with a method display() that simply prints the message– "Parent class method" to the console.
- Then, we define a child class, Child that extends the Parent class and overrides the display() method.
- Inside this overriding method, we use the super keyword to call the display() method from Parent (via super.display()), the immediate parent class of Child.
- In the Main class, we first create an instance of Child using the new operator with constructor and then use it to call the display() method.
- As a result, the display() method inside Child first invokes the display() method from the parent, printing the message– ‘Parent class method’.
- It then prints the message– ‘Child class method’ as this is part of the method’s own definition.
This demonstrates the use of the super keyword to invoke the method of the immediate parent class. In this case, it allows the Child class to call and augment the behavior of the Parent class method.
2. Invoking The Parent Class Constructor
The super() keyword can also be used to call the parent class's constructor. This is particularly useful if the parent class does not have a no-argument constructor or if you want to ensure proper initialization of inherited members. If the parent class lacks a no-argument constructor and you don't explicitly call another constructor with super(), the code will not compile.
Code Example:
Output:
Parent class constructor
Child class constructor
Explanation:
In the Java code example,
- We define the base class Parent with a constructor Parent() that prints "Parent class constructor" when invoked.
- Then, we define a child class, Child that extends the Parent class, which means it inherits from Parent.
- The Child class has its own constructor, Child(), inside which–
- We use the super() keyword to explicitly call the constructor of the immediate parent class (Parent class in this case).
- This is necessary if you want to explicitly call a specific constructor in the parent class (especially a parameterized one), as Java does not automatically call it if it’s not the default (no-argument) constructor.
- Without an explicit super() call, Java will only attempt to call the no-argument constructor in the parent class.
- After calling super(), the child class constructor continues its execution and prints "Child class constructor".
- In the Main class, we create an instance of Child, using the new operator with the Child() constructor.
- This triggers the constructor chain starting from the Parent class constructor and then the Child class constructor.
- The output demonstrates the use of the super keyword to invoke the immediate parent class constructor explicitly, ensuring proper initialization of the parent class before the child class constructor executes.
3. Referring To Immediate Parent Class Instance Variable
Although not directly related to method overriding, super can also refer to variables in the parent class. This is handy when the subclass has a variable with the same name, and you want to clarify which one to use.
Constructor & Method Overriding In Java
As discussed in the rules section above, constructors are special methods used to initialize new objects. They share the class name and don’t return any value, not even void. Constructors differ from other methods because they aren’t inherited and therefore cannot be overridden in subclasses.
- However, constructors in a parent class still play a role when creating a subclass object.
- When a subclass object is instantiated, Java ensures that a parent constructor is called first.
- This can be done either implicitly (via Java’s default constructor call if no specific constructor is defined) or explicitly using super() in the subclass constructor.
- If no constructor is defined in the subclass, Java automatically calls a no-argument constructor of the superclass using super(). If the superclass lacks a no-argument constructor, we must manually call one of its parameterized constructors using super().
To provide different constructors in a subclass, we can define constructors with various parameters and explicitly call specific superclass constructors. This approach ensures that we can initialize inherited members correctly, using the parent class’s initialization logic when necessary.
Exception Handling In Method Overriding In Java
In Java, exception handling allows subclasses to either maintain, restrict, or expand the exceptions thrown by an overridden method from the superclass. This control is governed by rules that help ensure subclasses don't introduce unexpected checked exceptions. Let's break down how exceptions, particularly checked and unchecked, interact with method overriding in Java language.
Checked Exceptions In Method Overriding In Java
When a method in a superclass throws a checked exception (like IOException), any overriding method in a subclass must adhere to certain rules:
- Same Exception: The subclass can throw the exact same checked exception.
- Subclass Exception: The subclass can throw a more specific (subclass) checked exception.
- No Exception or Broader Exception: Alternatively, the subclass can choose not to throw any checked exception or throw an unchecked exception instead.
Example: Checked Exception Handling with Method Overriding in Java
Let’s consider a scenario where we have a superclass FileProcessor with a processFile() method that reads files and may throw an IOException. In a subclass TextFileProcessor, we override processFile() to add specific behavior, such as verifying if the file is a text file, while handling potential file-related exceptions.
Code Example:
Output:
File not found: example.txt (No such file or directory)
Explanation:
In the example Java code,
- We first define a superclass FileProcessor containing a method processFile() that takes a File object and reads its contents.
- By definition, this method can throw an IOException, if needed. It includes error handling for FileNotFoundException to handle cases where the file is not found.
- We then define a subclass TextFileProcessor that extends FileProcessor. It overrides the processFile() method to provide additional processing specific to text files.
- In the overriding method, we first call the overridden method from superclass using the super() keyword to perform the default file processing.
- We use an if-statement to add specific behavior by checking if the filename ends in the extension ‘.txt’. If it does not, we throw an IOException with a message indicating invalid format for text files.
- In the Main class, we first create a File object for ‘example.txt’ and an instance of TextFileProcessor to process the file.
- Since the processFile() method in the superclass FileProcessor throws an IOException, the overriding method in TextFileProcessor must also declare that it throws IOException or a superclass of IOException, which is done using the throws IOException clause in its method signature.
- The output of the program (when ‘example.txt’ does not exist) demonstrates the error message ‘File not found: example.txt (No such file or directory)’ indicating that the FileNotFoundException was caught in the superclass method.
This is how if the example.txt file doesn’t exist or doesn’t match the expected format, an exception is thrown and handled, ensuring the program doesn’t crash unexpectedly. It demonstrates how the subclass respects the checked exception IOException and builds on it without introducing new exceptions outside what the superclass declared. This preserves compatibility with the superclass’s exception handling while extending functionality.
Unchecked Exceptions In Method Overriding In Java
The Java language is much more lenient when it comes to unchecked exceptions in method overriding. These exceptions, which are subclasses of RuntimeException (such as IllegalArgumentException), don’t need to be declared or handled by the superclass. This allows the subclass to introduce or omit any unchecked exceptions in its overridden methods, giving it more flexibility for cases where runtime issues may arise.
Example: Unchecked Exception Handling with Method Overriding in Java
In the Java example below, we modify processFile to throw an unchecked IllegalArgumentException if the file path is invalid.
Code Example:
Output:
Processing the text file...
Explanation:
In the example Java program,
- We define a superclass FileProcessor with a method processFile() that validates the file path and throws an IllegalArgumentException if the path is null or empty.
- Then, we define a subclass TextFileProcessor class that extends FileProcessor and overrides the processFile() method to additional checks specific to text files.
- In the overriding method, we first call the superclass method using super to ensure the original validation for null or empty file paths is performed.
- It then uses an if-else statement to check if the file path ends with ‘.txt’. If it does, then it prints a message indicating that the text file is being processed.
- If not, then it throws another IllegalArgumentException.
- Since IllegalArgumentException is an unchecked exception, there are no restrictions on its use. The subclass can freely add checks without the need for the superclass to account for this exception, as it doesn't require a declaration in the method signature (because it’s unchecked).
- In the Main class, we create an instance of TextFileProcessor and call its processFile() method with a valid text file path.
- As shown in the output, since the file path is valid, the program prints a message indicating that the text file is being processed.
This approach allows TextFileProcessor to handle runtime-specific cases more flexibly while retaining the original method’s validation.
Access Modifiers In Method Overriding In Java
As mentioned in the rules section, one crucial point to remember when method overriding in Java is that we cannot reduce the visibility of the method in the subclass. That is, the access modifier of the method in the subclass must be equal to or more permissive than the access modifier of the method in the superclass.
In other words, we can increase the visibility (e.g., from protected to public), but we cannot decrease it (e.g., from public to protected). The hierarchy of access modifiers, from the most restrictive to the least restrictive, is as follows:
private < default (package-private) < protected < public
This rule ensures that subclasses don't inadvertently restrict access to functionality that is accessible in the parent class. Let's explore this with two examples—one demonstrating reduced visibility and another showing increased visibility with method overriding in Java.
Example 1: Reducing Visibility (Not Allowed) In Method Overriding In Java
Consider a superclass Animal with a method makeSound() declared as public. The subclass Dog tries to override makeSound() with a more restrictive access modifier, protected. This is not allowed in Java, as it violates the rule of reducing visibility.
Code Example:
Output:
Main.java:10: error: makeSound() in Dog cannot override makeSound() in Animal
protected void makeSound() {
^
attempting to assign weaker access privileges; was public
1 error
Explanation:
In the Java example,
- The method makeSound() in the Animal class is public, meaning it is accessible everywhere.
- In the Dog class, the method is overridden with protected visibility, which is less permissive than public. Java does not allow this because it would reduce the method's visibility from what was declared in the superclass.
- This results in a compilation error indicating that we are trying to assign weaker access privileges.
Example 2: Increasing Visibility (Allowed) In Method Overriding In Java
Now, let's consider increasing the visibility of the overridden method. In this example, we have a superclass Animal with a protected method makeSound(). The subclass Dog overrides this method with a public access modifier, which is allowed.
Code Example:
Output:
Dog barks
Explanation:
In the example,
- The method makeSound() in the Animal class is protected, meaning it is accessible within the same package and by subclasses.
- In the Dog class, the method is overridden with public visibility, which is more permissive. This is allowed because the method in the subclass is more accessible than the method in the superclass.
- This results in the program running without errors, and the output is "Dog barks", demonstrating that the subclass method is invoked.
Advantages & Disadvantages Of Method Overriding In Java
Method overriding is a key feature in Java, enabling subclasses to provide their own implementation of a method inherited from a superclass. While this powerful feature offers several benefits, it also comes with its set of challenges.
Advantages Of Method Overriding In Java
- Polymorphic Behavior: Method overriding enables polymorphism, allowing objects of different classes to be treated as objects of a common superclass. This promotes code reusability and enhances the flexibility of design by enabling dynamic method invocation based on the object type at runtime.
- Enhanced Flexibility: Subclasses can customize inherited methods to meet their specific needs, offering greater control over functionality. This flexibility of method overriding in Java allows for specialization while still maintaining the foundation provided by the superclass.
- Improved Readability and Maintainability: By overriding methods, subclasses focus only on their custom behavior without altering the superclass. This separation of concerns results in cleaner, more modular code, which is easier to read and maintain.
- Code Reusability: With method overriding in Java, subclasses can reuse the superclass method's structure, reducing the need to duplicate code. This increases efficiency and ensures consistency, making the codebase easier to maintain.
- Run-Time Polymorphism: Method overriding is resolved at runtime based on the actual type of the object, enabling dynamic method dispatch. This allows Java to choose the appropriate method to call based on the object that invokes the method, making the application more flexible.
Disadvantages Of Method Overriding In Java
While method overriding offers many benefits, it also has some limitations and challenges that we should be aware of.
- Complexity and Overhead: While method overriding brings flexibility, it can also introduce complexity, especially in large class hierarchies. This is because managing interactions between superclass and subclass methods requires careful planning to avoid unexpected behavior or bugs.
- Fragility: Changes to the superclass method (e.g., modifying the method signature or behavior) can inadvertently affect the behavior of overridden methods in subclasses. This can lead to fragile code where a small change in the superclass has far-reaching consequences on the subclasses.
- Potential for Misuse: When used incorrectly, method overriding in Java programs can violate the principle of encapsulation, leading to hard-to-understand and poorly maintained code. Overriding methods unnecessarily or inappropriately can confuse developers and make the codebase harder to manage.
- Performance Impact: The use of dynamic method dispatch in method overriding introduces a slight performance overhead compared to static method invocation. While this impact is usually minimal and typically not noticeable in most applications, it can be a concern in performance-sensitive scenarios.
- Limitations in Constructors: Constructors cannot be overridden in Java, limiting the flexibility of subclass initialization logic. While constructors can be overloaded, they cannot be overridden like regular methods, which can be a constraint in some cases.
Difference Between Method Overloading Vs. Method Overriding In Java
Method overloading and method overriding are two important concepts in Java that involve the declaration and use of methods. While both concepts involve redefining methods, they are used in different contexts and have distinct characteristics. The table below highlights the difference between method overloading and method
Feature |
Method Overloading |
Method Overriding |
Definition |
Defining multiple methods with the same name but different parameters in the same class. |
Redefining a method in a subclass with the same signature as in the superclass. |
Purpose |
To allow a method to perform different tasks based on different parameters. |
To provide a new implementation of an inherited method. |
Resolution |
Resolved at compile-time based on method signature. |
Resolved at runtime based on the object's actual type. |
Return Type |
May or may not match the original method's return type. |
Must have the same return type as the overridden method. |
Exceptions |
No restrictions on thrown exceptions. |
Cannot throw broader checked exceptions than the superclass method. |
Inheritance |
Not related to inheritance. Methods are in the same class. |
Requires inheritance; method must exist in the superclass. |
Static Methods |
Can be overloaded. |
Cannot be overridden, but can be hidden. |
Final Methods |
Can be overloaded. |
Cannot be overridden. |
Private Methods |
Can be overloaded. |
Cannot be overridden. |
Need more guidance on how to become a Java developer? You can now select an expert to be your mentor here.
Conclusion
Method overriding in Java is a powerful feature that allows subclasses to provide their own implementation of methods inherited from the superclass. This ability to override methods makes code more adaptable, as it tailors inherited behaviors to meet specific needs.
- In this article, we covered the essential rules governing method overriding, such as the importance of method signatures, the role of access modifiers, and the use of the super keyword.
- We also explored the unique case of constructors, which cannot be overridden, and delved into the relationship between method overriding and exception handling.
- Specifically, we discussed the importance of preserving exception hierarchies when overriding methods that throw checked exceptions.
Ultimately, method overriding empowers developers to create new behaviors in subclasses while maintaining compatibility with their parent class. By enhancing code flexibility and simplifying maintenance, method overriding is an invaluable tool in a Java developer's toolkit.
Also read: Top 100+ Java Interview Questions And Answers (2024)
Frequently Asked Questions
Q. How does method overriding in Java relate to the Liskov Substitution Principle (LSP)?
Method overriding is closely tied to the Liskov Substitution Principle (LSP), which is one of the five SOLID principles of object-oriented design. The LSP states that objects of a superclass should be replaceable with objects of its subclasses without affecting the correctness of the program. In other words, a subclass should be able to substitute for its superclass without changing the behavior expected by the client code.
- Method overriding ensures compliance with LSP by allowing subclasses to provide specific implementations of superclass methods while maintaining the same interface.
- A subclass must adhere to the expected behavior of the superclass’s method, ensuring that client code remains unaffected when a subclass instance replaces a superclass instance.
Q. Can a subclass declare a method to throw a checked exception that the superclass method doesn't declare?
No, a subclass cannot declare a method to throw a checked exception that isn’t declared by the superclass method it overrides.
This rule ensures consistency with the superclass's contract, preventing subclasses from introducing new exceptions that the superclass does not handle. The compiler enforces this, ensuring that any exception handling remains predictable and adheres to the superclass’s specifications.
Q. What is dynamic method dispatch? How is it related to method overriding in Java?
Dynamic method dispatch is a mechanism in Java that determines which method to invoke at runtime based on the actual type of the object, not the reference type. This mechanism is a core feature of polymorphism (object-oriented programming) and is directly related to method overriding in Java programming.
- When a subclass overrides a method, dynamic dispatch ensures that the correct version of the method is called at runtime based on the object's type.
- This allows subclasses to provide specialized behavior for inherited methods and have the correct implementation called based on the type of the object.
This is how dynamic method dispatch is achieved through method overriding in Java.
Q. What is the role of the @Override annotation in method overriding in Java? When should it be used?
The @Override annotation indicates that a method is overriding a method from its superclass.
- While optional, it is a best practice to use it because it helps the compiler check for errors, such as mismatched method signatures.
- If the method signature does not match a method in the superclass, the compiler will generate an error.
- Using @Override also improves code readability, making it clear to other developers that the method is meant to override a superclass method, thereby improving maintainability and reducing potential bugs.
Q. Can a subclass define an overloaded method that is also a valid override of a superclass method?
Yes, a subclass can define an overloaded method that also overrides a superclass method. Method overloading and method overriding are independent concepts in Java, so it is possible for a subclass to overload a method with the same name but different parameter lists, while still overriding the original method. Let’s understand it through the following example:
Code Example:
Output:
Dog barks
The dog's bark is loud.
Here, we have a class Animal with a method named makeSound(), which is both overloaded and overridden in the child class Dog. The overloaded method expects an argument of String type, and the overridden method re-implements the logic according to the dog class.
Q. Explain the concept of method hiding in Java. How does it differ from method overriding?
Method hiding occurs when a subclass defines a static method with the same signature as a static method in the superclass. Unlike method overriding, which happens at runtime with instance methods, method hiding involves static methods and is determined at compile-time.
The table below highlights the difference between method hiding and method overriding in Java.
Feature |
Method Hiding |
Method Overriding |
Definition |
Defining/ declaring a static method in a subclass with the same signature as a static method in the superclass. |
Redefining an instance method in a subclass with the same signature as an instance method in the superclass. |
Resolution |
Compile-time |
Runtime |
Purpose |
Provide a new implementation of a static method in a subclass that hides the static method in its superclass. |
Provide a new behavior for an instance method, already defined in the superclass. |
Inheritance |
Not influenced by inheritance |
Requires inheritance (subclassing) |
Access Control |
Can change visibility |
Cannot reduce visibility |
Final Methods |
Can hide final methods |
Cannot override final methods |
Private Methods |
Can hide private methods |
Cannot override private methods |
Q. Can a subclass call the overridden method from within the overriding method?
Yes, a subclass can call the overridden method from the subclass using the super keyword. This allows the subclass to augment or extend the functionality of the method in the superclass rather than completely replacing it.
For example, a subclass can call the superclass method within its own overridden method, allowing additional behavior to be added without losing the original method's functionality.
Code Example:
Output:
Parent class method
Child class method
In this example, the Child class overrides the display() method from the Parent class. Inside this method, we use the super keyword to call the display() method of the Parent class before executing the additional logic in the Child class's display() method. As shown in the output, when we call the display() method from the Child class, it successfully invokes the called method and the overridden method from the superclass.
This compiles our discussion on method overriding in Java. Here are a few more topics you must explore:
- Difference Between Java And JavaScript Explained In Detail
- Advantages And Disadvantages of Java Programming Language
- Top 15+ Difference Between C++ And Java Explained! (+Similarities)
- List Of 50 Core Java Interview Questions With Answers
- 90+ Java Collections Interview Questions (+Answers) You Must Know
Login to continue reading
And access exclusive content, personalized recommendations, and career-boosting opportunities.
Comments
Add comment