Background:
Polymorphism is one of the key principles of Object-Oriented Programming (OOP), which has been supported in Java since its inception. It allows an object to behave differently depending on its actual type during the program execution, even when using a reference of a base type.
Problem:
Without polymorphism, the code becomes rigid, often leading to redundant constructions like switch-case or if-else statements to work with objects of different types. This complicates the maintenance and extension of the code. Polymorphism addresses the need to write repetitive code for different types.
Solution:
Polymorphism in Java is implemented through inheritance and interfaces. It allows:
Example code:
class Animal { void speak() { System.out.println("Animal speaks"); } } class Dog extends Animal { @Override void speak() { System.out.println("Dog barks"); } } class Cat extends Animal { @Override void speak() { System.out.println("Cat meows"); } } public class PolyDemo { public static void main(String[] args) { Animal a1 = new Dog(); Animal a2 = new Cat(); a1.speak(); // Dog barks a2.speak(); // Cat meows } }
Key features:
What is the difference between overloading and overriding methods in polymorphism?
Overloading is defining multiple methods with the same name but different signatures in the same class. Overriding is defining a method in a subclass with the same signature as in the parent class.
class Example { void foo(int x) {} void foo(String y) {} // this is overloading } class Base { void foo() {} } class Child extends Base { @Override void foo() {} // this is overriding }
Can there be polymorphism without inheritance?
In the classical sense in Java - no: polymorphism requires the presence of an inheritance hierarchy or an implemented interface.
Can you call subclass methods from a parent class reference?
You can only call methods defined in the parent class or overridden in the subclass. Methods that exist only in the subclass cannot be called without type casting.
Animal a = new Dog(); a.speak(); // can do // a.fetch(); // compilation error, even if Dog has method fetch()
In the project, there are classes Dog, Cat, Cow, but the used code works directly with the types, calling methods through explicit casting and instanceof:
Pros:
Cons:
Inherit Animal with virtual speak(). All interactions through the base type Animal.
Pros:
Cons: