Explain the concept of inheritance and polymorphism in object-oriented programming. Give an example in Java to demonstrate how inheritance and polymorphism are implemented.
Inheritance is a fundamental concept in object-oriented programming that allows classes to inherit properties and behaviors from other classes. It allows the creation of a hierarchy of classes, where a subclass inherits the characteristics of its superclass.
Polymorphism, on the other hand, refers to the ability of objects of different classes to be treated as objects of a common superclass. This allows objects to be used interchangeably, providing flexibility and code reusability.
Here's an example in Java to illustrate the concept of inheritance and polymorphism:
// Step 1: Create a superclass called Animal
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void makeSound() {
System.out.println("Animal sound");
}
}
// Step 2: Create a subclass of Animal called Dog
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
// Override makeSound() method
@Override
public void makeSound() {
System.out.println("Woof!");
}
public void fetch() {
System.out.println(name + " is fetching.");
}
}
// Step 3: Create a subclass of Animal called Cat
public class Cat extends Animal {
public Cat(String name) {
super(name);
}
// Override makeSound() method
@Override
public void makeSound() {
System.out.println("Meow!");
}
public void climb() {
System.out.println(name + " is climbing.");
}
}
// Step 4: In the main method, demonstrate inheritance and polymorphism
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog("Buddy");
Animal animal2 = new Cat("Whiskers");
animal1.makeSound(); // Output: Woof!
animal2.makeSound(); // Output: Meow!
// The following lines of code demonstrate polymorphism,
// as the objects of Dog and Cat classes are treated as objects of the Animal class.
// Uncomment the following lines to get the additional output.
/*
animal1.fetch(); // Compile error: Animal does not have fetch() method
animal2.climb(); // Compile error: Animal does not have climb() method
*/
// Casting the animal1 object to Dog type to access Dog's specific method
if (animal1 instanceof Dog) {
Dog dog = (Dog) animal1;
dog.fetch(); // Output: Buddy is fetching.
}
// Casting the animal2 object to Cat type to access Cat's specific method
if (animal2 instanceof Cat) {
Cat cat = (Cat) animal2;
cat.climb(); // Output: Whiskers is climbing.
}
}
}
In this example, we have a superclass called Animal
that defines the common properties and behavior of animals. It has a name
field and a makeSound()
method that prints "Animal sound".
We then create two subclasses, Dog
and Cat
, that inherit from the Animal
class. These subclasses extend the functionality of the Animal
class by adding their own specific methods, fetch()
and climb()
, respectively.
In the Main
class, we demonstrate inheritance and polymorphism. We create objects of type Dog
and Cat
and assign them to variables of type Animal
. This allows us to treat these objects interchangeably as objects of the common superclass, Animal
.
The makeSound()
method is overridden in each subclass to provide a specific implementation for each animal type. When we invoke the makeSound()
method on each object, it prints the sound specific to that animal.
To demonstrate polymorphism, we try to invoke the specific methods fetch()
and climb()
on the animal1
and animal2
objects. However, this results in a compilation error because the Animal
class does not have these methods.
To access the specific methods of the subclasses, we can use type casting. We check the type of the object using the instanceof
operator and then cast it to the appropriate subclass type. This allows us to access and invoke the specific methods of that subclass.
In the example, we check the type of animal1
using instanceof
and cast it to the Dog
type to access the fetch()
method. Similarly, we check the type of animal2
using instanceof
and cast it to the Cat
type to access the climb()
method.
This example demonstrates both inheritance and polymorphism in action, showing how objects can inherit properties and behaviors from a superclass and be treated as objects of a common superclass, providing flexibility and code reusability.