12.b: Mastering Inheritance with Doors and Desks

AP Computer Science A Jan 22, 2024

Welcome back coders! Today, we're taking a closer look at how inheritance works in Object-Oriented Programming (OOP) and diving into the concept of overriding—a vital skill that allows subclasses to express their uniqueness. Let’s start our lesson in two familiar places within our school: the Office and the Classroom. 🏫🚪

Understanding Simple Inheritance with the Office

In the vast, interconnected hallways of our school, every room inherits basic traits from the SchoolRoom class. Think of SchoolRoom it as the school building blueprint—it defines the basic structure every room follows: walls, doors, and windows.

The Office: A Subclass Example

The Office is a simple yet perfect example to illustrate basic inheritance. It inherits the foundational features from SchoolRoom, but doesn't need to change or add much. Here's how it looks in code:

class SchoolRoom {
    int numberOfWalls = 4;
    int numberOfDoors = 1;
    int numberOfWindows;
    
    void roomDescription() {
        System.out.println("This room has " + numberOfWalls + " walls, " 
                           + numberOfDoors + " door, and " 
                           + numberOfWindows + " windows.");
    }
}

class Office extends SchoolRoom {
    // Inherits everything from SchoolRoom without any changes
}

The Office, by default, will have 1 door, as defined by its superclass, SchoolRoom. This straightforward inheritance shows how subclasses automatically acquire their superclass's characteristics without extra coding.

Overriding in Action with the Classroom

Now, let's step into the Classroom, where the real magic of overriding comes to life. Unlike the Office, the Classroom has a unique feature: it has two doors instead of one. This is where it starts to differ from the SchoolRoom blueprint, demonstrating the power of overriding.

The Classroom: Overriding the Superclass

To accommodate this difference, the Classroom subclass overrides the numberOfDoors attribute inherited from SchoolRoom. This is how we explicitly define what makes a Classroom unique:

class Classroom extends SchoolRoom {
    // Overriding the numberOfDoors attribute
    int numberOfDoors = 2;
    String subject;

    void subjectInfo() {
        System.out.println("This is a " + subject + " classroom.");
    }

    // Overriding the roomDescription() method to include subject information
    @Override
    void roomDescription() {
        super.roomDescription(); // Calls the superclass method
        System.out.println("This classroom is for " + subject + " and has " + numberOfDoors + " doors.");
    }
}

By setting numberOfDoors to 2, we override the original property from SchoolRoom, tailoring the Classroom to our specific needs. Furthermore, we override the roomDescription() method to include the basic description and add specific information about the subject and the unique number of doors.

This illustrates a crucial aspect of OOP: subclasses can modify inherited properties (attributes) and behaviors (methods) to reflect their specific characteristics, enhancing the versatility and reusability of code.

Bringing It All Together

When we create a Classroom object and call its roomDescription() method, we'll see how it maintains the structure of SchoolRoom but adds its personalized touch, showcasing the concept of overriding in a simple, relatable manner.

public class School {
    public static void main(String[] args) {
        Classroom mathClass = new Classroom();
        mathClass.numberOfWindows = 3;
        mathClass.subject = "Math";
        mathClass.roomDescription();
        // Output will illustrate the overridden number of doors and the added subject description
    }
}

Our journey through the Office and Classroom within our code school has shed light on two pivotal concepts in OOP: inheritance and overriding. Through inheritance, subclasses gain the traits of their superclass, ensuring a consistent foundation across different types of rooms (classes). Overriding allows these subclasses to express their unique features and behaviors, tailoring the inherited blueprint to fit their specific needs.

Just as every room in a school serves a distinct purpose while adhering to the overall architecture, inheritance and overriding enable our code to be both uniform and uniquely specialized. So, next time you're coding, remember the lessons from our school of code. Let the principles of inheritance and overriding guide you to create flexible, reusable, and efficient code structures. Happy coding, and may your code be as organized and adaptable as the (best) planned school!

Tags