ProgrammingJava Developer

What is polymorphism in Java, how is it implemented and why is it needed?

Pass interviews with Hintsage AI assistant

Answer.

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:

  • a reference of the parent type to point to an object of the child type;
  • calling overridden methods without knowing the specific type of the object at compile time.

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:

  • Allows expanding and modifying systems without changing existing code.
  • Provides loose coupling between components.
  • Design patterns (such as Strategy, Command) are implemented through polymorphism.

Tricky questions.

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()

Common mistakes and anti-patterns

  • Overriding methods without the @Override annotation - the compiler will not catch signature mismatch errors.
  • Type casting without checking via instanceof, which causes ClassCastException.
  • Using polymorphism where composition would be simpler.

Real-life example

Negative case

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:

  • Quick implementation of new types of animals.

Cons:

  • Growth of if-else.
  • Violation of OOP principles.
  • Complexity of scaling.

Positive case

Inherit Animal with virtual speak(). All interactions through the base type Animal.

Pros:

  • Flexibility when adding new types.
  • Ease of testing.

Cons:

  • More complicated if the objects are completely unrelated, sometimes composition would be preferable.