Implement Polymorphism
Key Concepts
Polymorphism is a fundamental concept in object-oriented programming (OOP) that allows objects of different classes to be treated as objects of a common superclass. It enables a single interface to represent different types of objects, providing flexibility and extensibility in code design.
1. Method Overriding
Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. This allows the subclass to modify or extend the behavior of the inherited method. The overridden method in the subclass must have the same method signature (name, return type, and parameters) as the method in the superclass.
2. Method Overloading
Method overloading allows a class to have multiple methods with the same name but different parameters. The methods must differ in the number, type, or order of their parameters. Java determines which method to call based on the arguments provided during the method call.
3. Dynamic Method Dispatch
Dynamic method dispatch is the mechanism by which a call to an overridden method is resolved at runtime rather than compile time. This allows Java to determine the correct method to execute based on the actual object type, not the reference type. This is a key aspect of runtime polymorphism.
Detailed Explanation
Method Overriding
Consider a scenario where you have a superclass Animal
with a method makeSound()
. Each subclass, such as Dog
and Cat
, can override this method to produce different sounds. When you call makeSound()
on an object of type Animal
, the actual method executed depends on whether the object is a Dog
or a Cat
.
Method Overloading
Imagine a class Calculator
with multiple methods named add()
. One method might take two integers and return their sum, while another might take two doubles. The compiler can distinguish between these methods based on the types of arguments provided, allowing you to write more flexible and readable code.
Dynamic Method Dispatch
Consider a situation where you have a reference of type Animal
pointing to an object of type Dog
. When you call the makeSound()
method on this reference, Java uses dynamic method dispatch to determine that the makeSound()
method of the Dog
class should be executed, not the one in the Animal
class.
Examples
Method Overriding Example
class Animal { void makeSound() { System.out.println("Animal sound"); } } class Dog extends Animal { @Override void makeSound() { System.out.println("Woof"); } } class Cat extends Animal { @Override void makeSound() { System.out.println("Meow"); } } Animal myDog = new Dog(); myDog.makeSound(); // Output: Woof Animal myCat = new Cat(); myCat.makeSound(); // Output: Meow
Method Overloading Example
class Calculator { int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } } Calculator calc = new Calculator(); System.out.println(calc.add(5, 10)); // Output: 15 System.out.println(calc.add(5.5, 10.5)); // Output: 16.0
Dynamic Method Dispatch Example
Animal myAnimal = new Dog(); myAnimal.makeSound(); // Output: Woof myAnimal = new Cat(); myAnimal.makeSound(); // Output: Meow
Conclusion
Polymorphism is a powerful tool in Java that enhances code reusability and flexibility. By understanding and implementing method overriding, method overloading, and dynamic method dispatch, you can create more dynamic and maintainable applications. These concepts are essential for mastering Java programming and passing the Oracle Certified Professional Java SE 8 Programmer exam.