Inheritance is another fundamental concept in Object-Oriented Programming(OOP)in Java.It allows a new class(called a subclass or child class)to inherit the properties and behavior(fields and methods)of an existing class(called a superclass or parent class).This promotescode reuseand establishes a natural hierarchy between classes.
Key Points of Inheritance:1.Superclass(Parent Class):The
class whose properties and methods are inherited.2.Subclass (Child Class): The class that inherits from the superclass.
extends
Keyword: Used by a subclass to inherit from a superclass.- Single Inheritance: In Java, a class can inherit from only one superclass (Java does not support multiple inheritance directly).
- Multilevel Inheritance: A class can inherit from another subclass, forming a chain of inheritance.
Types of Inheritance in Java:
- Single Inheritance: One class inherits from another class.
- Multilevel Inheritance: A class is derived from a class that is also derived from another class.
- Hierarchical Inheritance: Multiple classes inherit from a single class.
Java doesn’t support multiple inheritance (where a class inherits from multiple classes) to avoid the diamond problem, but it can be achieved using interfaces.
Example 1: Basic Inheritance Example
// Superclass (Parent class)
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}
// Subclass (Child class)
class Dog extends Animal {
void bark() {
System.out.println("The dog barks.");
}
}
public class InheritanceExample1 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Inherited from Animal class
dog.bark(); // Defined in Dog class
}
}
Example 2: Single Inheritance
// Superclass
class Vehicle {
void start() {
System.out.println("Vehicle is starting...");
}
}
// Subclass
class Car extends Vehicle {
void drive() {
System.out.println("Car is driving...");
}
}
public class InheritanceExample2 {
public static void main(String[] args) {
Car car = new Car();
car.start(); // Inherited from Vehicle class
car.drive(); // Defined in Car class
}
}
Example 3: Multilevel Inheritance
// Superclass
class Animal {
void sleep() {
System.out.println("Animal is sleeping...");
}
}
// Intermediate class
class Mammal extends Animal {
void feedMilk() {
System.out.println("Mammal is feeding milk...");
}
}
// Subclass
class Human extends Mammal {
void speak() {
System.out.println("Human is speaking...");
}
}
public class InheritanceExample3 {
public static void main(String[] args) {
Human human = new Human();
human.sleep(); // Inherited from Animal
human.feedMilk(); // Inherited from Mammal
human.speak(); // Defined in Human
}
}
Example 4: Hierarchical Inheritance
// Superclass
class Shape {
void draw() {
System.out.println("Drawing a shape...");
}
}
// Subclass 1
class Circle extends Shape {
void draw() {
System.out.println("Drawing a circle...");
}
}
// Subclass 2
class Square extends Shape {
void draw() {
System.out.println("Drawing a square...");
}
}
public class InheritanceExample4 {
public static void main(String[] args) {
Circle circle = new Circle();
circle.draw(); // Calls the Circle's draw method
Square square = new Square();
square.draw(); // Calls the Square's draw method
}
}
Example 5: Constructor Chaining in Inheritance
// Superclass
class Animal {
Animal() {
System.out.println("Animal constructor called");
}
}
// Subclass
class Dog extends Animal {
Dog() {
super(); // Calls the constructor of the superclass (Animal)
System.out.println("Dog constructor called");
}
}
public class InheritanceExample5 {
public static void main(String[] args) {
Dog dog = new Dog();
// Output will show the Animal constructor being called first, then the Dog constructor.
}
}
Example 6: Using the super
Keyword
// Superclass
class Animal {
String name = "Animal";
void display() {
System.out.println("This is an animal.");
}
}
// Subclass
class Dog extends Animal {
String name = "Dog";
void display() {
System.out.println("This is a dog.");
}
void showNames() {
System.out.println(name); // Refers to Dog's name
System.out.println(super.name); // Refers to Animal's name
}
}
public class InheritanceExample6 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.display(); // Calls Dog's display method
dog.showNames(); // Demonstrates the use of 'super' to access Animal's name
}
}
Example 7: Method Overriding
// Superclass
class Animal {
void sound() {
System.out.println("Animals make different sounds");
}
}
// Subclass
class Cat extends Animal {
@Override
void sound() {
System.out.println("The cat meows");
}
}
public class InheritanceExample7 {
public static void main(String[] args) {
Animal animal = new Animal();
animal.sound(); // Calls Animal's sound method
Cat cat = new Cat();
cat.sound(); // Calls Cat's overridden sound method
}
}
Example 8: Upcasting and Downcasting
// Superclass
class Animal {
void sound() {
System.out.println("Animal makes sound");
}
}
// Subclass
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
void fetch() {
System.out.println("Dog is fetching...");
}
}
public class InheritanceExample8 {
public static void main(String[] args) {
Animal animal = new Dog(); // Upcasting (Animal reference to a Dog object)
animal.sound(); // Calls Dog's sound method (polymorphism)
Dog dog = (Dog) animal; // Downcasting (Converting Animal reference back to Dog)
dog.fetch(); // Now Dog-specific method can be called
}
}
Example 9: Final Classes and Methods (Preventing Inheritance)
// Superclass
class Animal {
final void sound() {
System.out.println("Animal makes sound");
}
}
// Subclass
class Dog extends Animal {
// The following would result in a compile-time error because sound() is final:
// void sound() {
// System.out.println("Dog barks");
// }
}
public class InheritanceExample9 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound(); // Calls Animal's sound method
}
}
Example 10: Inheritance with Interfaces
interface Animal {
void eat();
}
class Dog implements Animal {
public void eat() {
System.out.println("Dog eats meat.");
}
}
class Cat implements Animal {
public void eat() {
System.out.println("Cat eats fish.");
}
}
public class InheritanceExample10 {
public static void main(String[] args) {
Animal dog = new Dog();
dog.eat(); // Calls Dog's eat method
Animal cat = new Cat();
cat.eat(); // Calls Cat's eat method
}
}
Example 11: Abstract Classes in Inheritance
// Abstract superclass
abstract class Animal {
abstract void sound(); // Abstract method with no body
void sleep() {
System.out.println("Animal is sleeping");
}
}
// Subclass
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
}
public class InheritanceExample11 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound(); // Calls Dog's implementation of the sound method
dog.sleep(); // Calls inherited sleep method from Animal
}
}
Example 12: Multiple Inheritance via Interfaces
interface Swimmer {
void swim();
}
interface Runner {
void run();
}
class Triathlete implements Swimmer, Runner {
public void swim() {
System.out.println("Triathlete is swimming");
}
public void run() {
System.out.println("Triathlete is running");
}
}
public class InheritanceExample12 {
public static void main(String[] args) {
Triathlete athlete = new Triathlete();
athlete.swim(); // Calls swim method
athlete.run(); // Calls run method
}
}
Example 13: Overriding toString()
Method (Inheritance from Object
Class)
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Name: " + name + ", Age: " + age;
}
}
public class InheritanceExample13 {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
System.out.println(person.toString()); // Calls overridden toString method
}
}
Example 14: Protected Access Modifier in Inheritance
class Animal {
protected void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
void eat() {
System.out.println("Dog is eating");
}
}
public class InheritanceExample14 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Calls Dog's eat method
}
}
Example 15: Inheritance and Exception Handling
class Animal {
void sound() throws Exception {
System.out.println("Animal makes sound");
}
}
class Dog extends Animal {
@Override
void sound() throws Exception {
System.out.println("Dog barks");
}
}
public class InheritanceExample15 {
public static void main(String[] args) {
try {
Animal animal = new Dog();
animal.sound(); // Calls Dog's sound method
} catch (Exception e) {
e.printStackTrace();
}
}
}
Inheritance in Java allows for the design of more modular, reusable, and hierarchical systems by extending the functionality of existing classes without having to rewrite the code. This is essential for code reuse, polymorphism, and maintaining the DRY (Don't Repeat Yourself) principle.