Inheritance, Interfaces, and Packages
In Java, inheritance is a fundamental feature of object-oriented programming that allows a class to inherit properties and behaviors (methods) from another class. The class that inherits is called a subclass or derived class, and the class that is being inherited from is called a superclass or base class.
To establish inheritance in Java, you use the extends
keyword in the class declaration. Here’s a basic example:
// Superclass or Base class
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
// Subclass or Derived class
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // inherited from Animal class
dog.bark(); // method of Dog class
}
}
In this example, the Dog
class inherits from the Animal
class. So, Dog
inherits the eat()
method from Animal
, and Dog
also has its own method bark()
. When you create an instance of Dog
and call eat()
or bark()
, it will execute the respective methods.
Inheritance promotes code reusability and helps in building a hierarchical structure of classes where common properties and behaviors can be defined at higher levels and specialized behavior can be added at lower levels.
Some more examples of packages in Java:
Employee Hierarchy:
// Superclass
class Shape {
void draw() {
System.out.println("Drawing a shape");
}
}
// Subclass
class Circle extends Shape {
void draw() {
System.out.println("Drawing a circle");
}
}
// Subclass
class Rectangle extends Shape {
void draw() {
System.out.println("Drawing a rectangle");
}
}
public class Main {
public static void main(String[] args) {
Circle circle = new Circle();
circle.draw(); // Output: Drawing a circle
Rectangle rectangle = new Rectangle();
rectangle.draw(); // Output: Drawing a rectangle
}
}
Employee Hierarchy:
// Superclass
class Vehicle {
void move() {
System.out.println("Vehicle is moving");
}
}
// Subclass
class Car extends Vehicle {
void move() {
System.out.println("Car is moving on the road");
}
}
// Subclass
class Boat extends Vehicle {
void move() {
System.out.println("Boat is moving on the water");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.move(); // Output: Car is moving on the road
Boat boat = new Boat();
boat.move(); // Output: Boat is moving on the water
}
}
Employee Hierarchy:
// Superclass
class Employee {
String name;
int employeeId;
Employee(String name, int employeeId) {
this.name = name;
this.employeeId = employeeId;
}
void displayInfo() {
System.out.println("Name: " + name);
System.out.println("Employee ID: " + employeeId);
}
}
// Subclass
class Manager extends Employee {
String department;
Manager(String name, int employeeId, String department) {
super(name, employeeId);
this.department = department;
}
void displayInfo() {
super.displayInfo();
System.out.println("Department: " + department);
}
}
public class Main {
public static void main(String[] args) {
Manager manager = new Manager("John", 1001, "Engineering");
manager.displayInfo();
}
}
In each of these examples, subclasses inherit properties and behaviors from their respective superclasses, demonstrating the concept of inheritance in Java.
Inheritance is one of the most crucial concepts in object-oriented programming, and it has a very direct effect on how you design and write your Java classes. Inheritance is a powerful mechanism that means when you
write a class you only have to specify how that class is different from some other class; inheritance will give you automatic access to the information contained in that other class.
At the top of the Java class hierarchy is the class Object; all classes inherit from this one superclass. Object is the most general class in the hierarchy; it defines behavior inherited by all the classes in Java. Each class
further down in the hierarchy adds more information and becomes more tailored to a specific purpose. In this way, you can think of a class hierarchy as defining very abstract concepts at the top of the hierarchy and those
ideas becoming more concrete the farther down the chain of superclasses you go.
Most of the time when you write new Java classes, you’ll want to create a class that has all the information some other class has, plus some extra information. For example, you may want a version of a Button with its
own built-in label. To get all the Button information, all you have to do is define your class to inherit from Button. Your class will automatically get all the behavior defined in Button (and in Button’s superclasses), so
all you have to worry about are the things that make your class different from Button itself. This mechanism for defining new classes as the differences between them and their superclasses is called subclassing.
Subclassing involves creating a new class that inherits from some other class in the class hierarchy. Using subclassing, you only need to define the differences between your class and its parent; the additional behavior is all
available to your class through inheritance.
What if your class defines an entirely new behavior and isn’t really a subclass of another class? Your class can also inherit directly from Object, which still allows it to fit neatly into the Java class hierarchy. In fact, if you
create a class definition that doesn’t indicate its superclass in the first line, Java automatically assumes you’re inheriting from Object. The Motorcycle class you created in the previous section inherited from Object.