Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 11

Inheritance with extends and super

Recommended resources

Hello! In our last session, we focused on encapsulation and the use of access modifiers to protect an object's data. You learned how making fields private and providing public getters and setters gives a class full control over its state. We also briefly introduced the protected modifier, noting its special role in the relationship between classes.

Today, we will explore that relationship directly by diving into inheritance, one of the most powerful concepts in object-oriented programming. This lesson will show you how to create new classes based on existing ones, promoting code reuse and building logical, hierarchical relationships in your software. We will focus on implementing inheritance using Java's extends and super keywords. For someone aiming to build complex, real-world applications, mastering inheritance is non-negotiable as it's fundamental to frameworks like Spring.

1. What is Inheritance? Reusing Code with extends

At its core, inheritance is a mechanism that allows a new class to inherit the fields and methods of an existing class. This creates a parent-child relationship between classes.

  • Superclass (or parent class): The class whose features are inherited.
  • Subclass (or child class): The class that inherits from another class.

In Java, we use the extends keyword to establish this relationship. If you have experience with Python, this concept is similar to creating a subclass by putting the parent class name in parentheses, like class Child(Parent):. In Java, the syntax is class Child extends Parent { ... }.

The primary benefit of this is code reusability. Instead of copying and pasting code across multiple classes that share common functionality, you can define that functionality once in a superclass and have multiple subclasses inherit it. This adheres to the "Don't Repeat Yourself" (DRY) principle, which is a cornerstone of good software engineering.

Let's start with a quick and practical video that demonstrates how to use extends to create a hierarchy of Animal, Dog, and Cat classes.

Learn Java inheritance in 9 minutes! ๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ

This video from Bro Code provides a clear, concise introduction to the concept of inheritance, the extends keyword, and the benefit of code reuse.

Please watch the following segments: The initial part defines inheritance and shows how a Dog and Cat class can extend an Animal class, inheriting its attributes and methods. The next section explains the advantages of this approach, focusing on the DRY principle and showing how subclasses can also have their own unique fields and methods.

As the video showed, even though the Dog class was initially empty, it could use the eat() method because it inherited it from the Animal class. This is the power of inheritance in action.


2. The "is-a" Relationship

Inheritance should be used to model an "is-a" relationship. This means a subclass should be a more specific type of its superclass. For example, a Dog is an Animal, and a Car is a Vehicle. Using inheritance in this way leads to logical and intuitive class designs.

This diagram illustrates the "is-a" relationship in inheritance. On the left, it shows a generic "Class B" extending "Class A," establishing that B is a type of A. On the right, it provides a concrete example: a "Developer" class extends an "Employee" class, meaning a Developer "is-an" Employee.

To solidify your understanding of the basic syntax and the "is-a" principle, let's look at a textual example.

Java Inheritance (With Examples)

This article from Programiz provides a formal definition and a simple, complete code example demonstrating inheritance.

Please read from the beginning of the article down to the start of the "is-a relationship" section. Focus on the code example. Pay attention to how the Dog object, labrador, can directly access the name field and call the eat() method, both of which are defined in the Animal superclass.

Inheritance and Access Modifiers

Remember our discussion on access modifiers? Inheritance is where they become critically important.

  • public members of the superclass are accessible to the subclass.
  • protected members of the superclass are also accessible to the subclass (even if it's in a different package). This is the primary use case for the protected modifier.
  • private members of the superclass are not accessible to the subclass. They remain hidden, preserving encapsulation.

3. Communicating with the Superclass: The super Keyword

What happens when a subclass needs to refer to its superclass explicitly? For example, what if a subclass has a method with the same name as a method in the superclass? Or how does a subclass constructor ensure the superclass part of the object is initialized correctly?

This is where the super keyword comes in. It is a reference variable that is used to refer to the immediate parent class object. It has two main uses.

Use 1: Calling Superclass Methods and Accessing Fields

If a subclass defines a method with the same signature (name and parameters) as a method in its superclass, it's called method overriding. We'll cover this in detail in the next lesson.

When a method is overridden, calling it on a subclass object will execute the subclass's version. But what if you need to call the superclass's version from within the subclass? You use super.methodName().

Similarly, if a subclass declares a field with the same name as a field in its superclass, the subclass field "hides" the superclass field. You can use super.fieldName to access the superclass's field.

Use 2: Calling Superclass Constructors

This is the most common and critical use of super. When you create an object of a subclass, you are also implicitly creating an object of its superclass as part of it. The superclass portion must be constructed first.

You use super() to call a constructor of the parent class.

There are two crucial rules for using super() in constructors:

  1. The call to super() must be the very first statement in a subclass constructor.
  2. If you do not explicitly call super() in a constructor, the Java compiler will automatically insert a call to the superclass's no-argument constructor (super();).

This second rule can cause a common error. If your superclass does not have a no-argument constructor (e.g., it only has a constructor that takes parameters), the compiler's automatic insertion will fail, and your code won't compile. In that case, you must explicitly call one of the existing superclass constructors with the correct arguments.

Let's watch a detailed video that explains both uses of the super keyword with excellent examples.

Super Keyword in Java Full Tutorial - How to Use "super"

This video from "Coding with John" provides a thorough walkthrough of the super keyword, covering both method calls and constructor chaining.

Please watch the following segments carefully: What is super? A quick introduction to its purpose. Calling overridden methods: This shows a clear example of using super.makeNoise() to call the parent's method from within the child's overridden method. Calling superclass constructors: This is the most important part. It demonstrates how to use super(age, name) to pass arguments to the parent constructor, avoiding code duplication. Constructor rules and pitfalls: This section explains the critical rules, such as super() being the first statement and the implicit call to the no-args constructor.

The video clearly shows how constructor chaining works. When you create a Cat object, the Cat constructor first calls the Animal constructor using super(...) to initialize the age and name fields. This is a fundamental pattern in Java.

This diagram illustrates how a subclass constructor invokes its superclass constructor. When a `dog1` object of the `Dog` class is created, its constructor makes an explicit call to `super()`, which in turn executes the constructor of the `Animal` superclass. This ensures the parent part of the object is initialized before the child part.

To reinforce these concepts and provide you with a handy reference, let's review a written guide that breaks down the uses of super with direct examples.

Super Keyword in Java: With Examples (Updated 2026)

This article from IGM Guru provides clear, isolated examples for each use of super and highlights common mistakes, which is excellent for avoiding errors as you code.

Please read the following sections: "Examples of Using the Java Super Keyword": Review the three distinct examples for calling a superclass constructor, accessing an overridden method, and accessing a hidden field. "Common Mistakes Developers Make with super": This is a very important section. It explains the compiler error you'll get if the parent has no default constructor and you forget to call super() explicitly. "FAQs": Read the first three questions to clarify common points of confusion regarding super.


Conclusion

In this lesson, we have uncovered the mechanics of inheritance in Java, a feature that enables you to write more organized, reusable, and hierarchical code. This is a massive step toward structuring larger applications like the ones you'll build with Spring Boot.

Here are the key takeaways:

  • Inheritance models an "is-a" relationship, allowing a subclass to inherit public and protected members from a superclass.
  • The extends keyword is used to establish an inheritance relationship (class Subclass extends Superclass).
  • The super keyword is a reference to the immediate parent class.
  • Use super.methodName() to call a superclass method from within a subclass, especially when the method is overridden.
  • Use super() or super(arguments) to call a superclass constructor from a subclass constructor. This must be the first statement in the constructor.

We've touched upon method overriding as a motivation for using super. In our next lesson, we will dive deep into method overriding and polymorphism, exploring how Java decides which version of a method to run at runtime. This will unlock one of the most dynamic and flexible features of object-oriented programming.