Skip to main content

6.5 Modeling Object Behavior with Interfaces

Extending a Class with Another Class, Creating Abstract Classes

1. Introducing the Module and Its Agenda

In this module, we will dive into two core concepts of Object-Oriented Programming (OOP): extending classes and creating abstract classes. These concepts allow for code reuse, specialization, and modular design. By the end of this module, you will understand how inheritance works and how to create abstract classes to enforce structure in your code.


2. Extending a Class with Another Class

Inheritance is one of the pillars of OOP. It allows a class (subclass) to inherit fields and methods from another class (superclass). The subclass can also introduce new fields and methods or override the methods of the superclass to provide specialized behavior.

Example:

class Animal {
public void makeSound() {
System.out.println("Animal makes a sound");
}
}

class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}

In this example, the Dog class extends the Animal class and overrides its makeSound() method.


3. Accessing the Content of a Super Class from an Extending Class

A subclass can access fields and methods of its superclass using the super keyword. This is particularly useful when you want to call the parent class's constructor or methods within the subclass.

Example:

class Animal {
public void makeSound() {
System.out.println("Animal makes a sound");
}
}

class Dog extends Animal {
@Override
public void makeSound() {
super.makeSound(); // Calls the superclass method
System.out.println("Dog barks");
}
}

Here, the Dog class calls the makeSound() method from the Animal class before adding its own behavior.


4. Overriding a Method and Using Polymorphism

Polymorphism allows an object to take on many forms. When a method in a subclass overrides a method in its superclass, the subclass’s method will be called at runtime, even if the object is referenced as the superclass.

Example:

Animal myDog = new Dog();
myDog.makeSound(); // Outputs: Dog barks

Though the object is of type Animal, the Dog's version of makeSound() is executed.


5. Getting to Know the Methods from the Object Class

In Java, every class implicitly extends the Object class if no other superclass is specified. The Object class provides several useful methods such as toString(), equals(), and hashCode().

Example:

public class MyClass {
@Override
public String toString() {
return "This is my class!";
}
}

By overriding the toString() method, you can customize the output when an instance of your class is printed.


6. Live Demo: Seeing Overriding in Action

In this demo, we’ll override methods in a subclass and see how polymorphism works in Java.

Example:

class Animal {
public void makeSound() {
System.out.println("Animal makes a sound");
}
}

class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}

public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal();
Animal myDog = new Dog();

myAnimal.makeSound(); // Outputs: Animal makes a sound
myDog.makeSound(); // Outputs: Dog barks
}
}

7. Creating Abstract Classes with Abstract Methods

Abstract classes cannot be instantiated directly. They can contain abstract methods—methods without a body—that must be implemented by subclasses. This enforces a structure for subclasses while allowing them to provide specific implementations.

Example:

abstract class Animal {
public abstract void makeSound();
}

class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}

The Animal class is abstract, and the Dog class provides the concrete implementation of the makeSound() method.


8. Live Demo: Seeing Abstract Classes and Static Methods in Action

In this demo, we’ll see how abstract classes and static methods work in Java. While abstract methods must be implemented by subclasses, static methods belong to the class itself and can be accessed without creating an instance.

Example:

abstract class Animal {
public abstract void makeSound();

public static void printMessage() {
System.out.println("This is a static method in an abstract class");
}
}

class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}

public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.makeSound();
Animal.printMessage(); // Calling the static method
}
}

9. Preventing Extension and Overriding with the Final Keyword

The final keyword is used to prevent a class from being extended or a method from being overridden. This is useful when you want to enforce certain behaviors and prevent changes in the subclass.

Example:

final class Car {
// This class cannot be extended
}

class Animal {
public final void makeSound() {
System.out.println("Animal makes a sound");
}
}

The Car class is marked as final, meaning no class can extend it, and the makeSound() method in the Animal class cannot be overridden by subclasses.


10. Module Wrap-Up

In this module, we have explored the concepts of inheritance, method overriding, abstract classes, and the final keyword. These features enable you to create flexible and maintainable object-oriented code. By understanding how to extend classes, override methods, and enforce rules using abstract and final classes, you will be able to design robust Java applications.