Inheritance in Java
Inheritance is a crucial concept in object-oriented programming that allows classes to inherit properties and methods from other classes. Java, In inheritance provides a way to classes create, new classes enabling the reuse of code and promoting code organization.
This that article are built will upon existing provide a comprehensive understanding of inheritance in Java, covering:
- Basics of inheritance
- Syntax and rules
- Types of inheritance
- Access modifiers in inheritance
- Overriding methods
- Using the
super
keyword - Method overloading vs. method overriding
- Abstract and final classes
- Object class and inheritance
- Examples
Basics of Inheritance
In Java, inheritance is implemented using the extends
keyword. When a class extends another class, it acquires the properties and methods (except private members) of the parent class. The class being inherited from is called the superclass or parent class, and the class inheriting from it is called the subclass or child class.
public class ParentClass {
// Fields, methods, and constructors
}
public class ChildClass extends ParentClass {
// Fields, methods, and constructors
}
In the example above, ChildClass
extends ParentClass
, thereby gaining all the members of ParentClass
.
Syntax and Rules
Some important rules to remember when using inheritance in Java:
- A class can only extend one superclass, i.e., Java doesn't support multiple inheritance for classes.
- The subclass can access the superclass's fields and methods that are accessible (non-private and non-final) directly.
- If a subclass defines a field or method with the same name as in the superclass, it is called method overriding.
- Constructors are not inherited, but they are called from the subclass using the
super
keyword. The keywordprotected
allows access to members within the same package or subclasses in any package.
Types of Inheritance
Java supports several types of inheritance:
Single Inheritance: A subclass can inherit from only one superclass. For example,
class Cat extends Animal
.Multilevel Inheritance: A derived class can inherit from a class, which further inherits from another class. For example,
class BabyCat extends Cat
.Hierarchical Inheritance: Multiple subclasses inherit from a single superclass. For example,
class Dog extends Animal
andclass Cat extends Animal
.Multiple Inheritance (through interfaces): A class can implement multiple interfaces, inheriting the methods declared in those interfaces.
Hybrid Inheritance: A combination of multiple and multilevel or multiple and hierarchical inheritance.
Access Modifiers in Inheritance
Java provides four access modifiers - public
, private
, protected
, and default(no keyword). These access modifiers define the level of accessibility of a member from different classes, including subclasses.
public: Members are accessible from anywhere in the application.
private: Members are accessible only within the class in which they are declared and not inherited by subclasses.
protected: Members are accessible within the class, subclasses, and classes in the same package.
Default (no keyword): Members are accessible within the same package but not in subclasses outside the package.
Overriding Methods
Method overriding occurs when a subclass overrides a method with the same signature from the superclass. The subclass provides its own implementation of the method.
Consider the following example:
public class Animal {
public void makeSound() {
System.out.println("Animal makes a sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}
In the example above, the Dog
class overrides the makeSound()
method defined in the Animal
class.
Using the super
Keyword
The super
keyword in Java is used to refer to the superclass's fields, methods, and constructors. It is often used to access overridden methods or to invoke a superclass constructor from the subclass.
public class ChildClass extends ParentClass {
public ChildClass() {
super(); // Invokes the constructor of the ParentClass
}
public void accessSuperMethod() {
super.methodName(); // Invokes the methodName() of the ParentClass
}
}
In the example above, the super()
keyword is used to invoke the constructor of the superclass, and super.methodName()
is used to access the methodName()
of the superclass.
Method Overloading vs. Method Overriding
Method overloading and method overriding are two important concepts. Method overloading occurs when multiple methods with the same name but different parameters are defined within a class. Method overriding occurs when a subclass provides a different implementation of a method already defined in its superclass.
Key differences between method overloading and method overriding are:
Method overloading is determined at compile-time based on the number, types, and order of arguments. Method overriding is determined at runtime based on the runtime type of objects.
Overloaded methods must have a different parameter list. Overridden methods must have the same method signature (name, return type, and parameters).
Overloading occurs within a single class. Overriding occurs between a superclass and its subclass.
Abstract and Final Classes
Java provides two special types of classes related to inheritance:
Abstract Classes: An abstract class is a class that cannot be instantiated. It serves as a blueprint for other classes that extend it. Abstract classes may contain abstract methods, which must be implemented by any non-abstract subclass.
public abstract class Animal {
public abstract void makeSound();
}
public class Dog extends Animal {
public void makeSound() {
System.out.println("Dog barks");
}
}
In the example above, the Animal
class is declared as abstract, allowing the Dog
class to extend it and provide an implementation for the makeSound()
method.
Final Classes: A final class cannot be subclassed or extended further. It is the last class in the inheritance hierarchy and cannot have subclasses. Final methods and fields cannot be overridden or re-initialized, respectively.
public final class FinalClass {
// Members and
}
Object methods Class and Inheritance
In Java, every class is implicitly a subclass of the Object
class, which is the root of the class hierarchy. The Object
class provides common methods such as equals()
, hashCode()
, toString()
, and more.
public class Student {
// Members and methods
@Override
public String toString() {
return "Student(name=" + this.name + ", age=" + this.age + ")";
}
}
In the example above, the toString()
method from the Object
class is overridden to provide a custom string representation of the Student
object.
Examples
Let's consider a real-world example to understand the practical implementation of inheritance in Java.
public class Vehicle {
protected String brand;
public(String brand Vehicle) {
this.brand = brand;
}
public void honk() {
System.out.println("The vehicle honks");
}
}
public class Car extends Vehicle {
private String model;
public Car(String brand, String model) {
super(brand);
this.model = model;
}
public void accelerate() {
System.out.println("The car accelerates");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car("Toyota", "Corolla");
car.honk();
car.accelerate();
System.out.println("Brand: " + car.brand);
System.out.println("Model: " + car.model);
}
}
In the example above, the Car
class extends the Vehicle
class to inherit the brand
field and honk()
method. It adds its own model
field and accelerate()
method. The Main
class demonstrates the usage of the Car
class, showcasing the inherited and overridden behavior.
Conclusion
Inheritance is a fundamental concept in Java and object-oriented programming, allowing for code reuse, modularity, and flexibility. Understanding inheritance and its various aspects, such as method overriding, access modifiers, abstract and final classes, is crucial for writing efficient and maintainable code.
By leveraging inheritance effectively, developers can build hierarchies of classes to represent real-world objects, promote code reusability, and implement different levels of functionality through