OOP: Inheritance

​This article is the third article in the series of Object Oriented Programming tutorials, explaining the OOP concept - Inheritance. The same problem used in the Encapsulation tutorial is used here to explain Inheritance. The ABC book shop needs a software to maintain its billing procedures and stock management. This book shop sells books, magazines, newsletters and DVDs. In the last tutorial, we have developed a Book class.
public class Book {
    private String title;
    private String author;
    private double price;

    public String getTitle() {
        return this.title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return this.author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public void setPrice(double price) {
        if (price > 0) {
            this.price = price;
        } else {
            System.out.println("Invalid price");
        }
    }

    public double getPrice() {
        return this.price;
    }

    public void sell(int qty) {
        System.out.println("Total: $" + (qty * price));
    }
}
This time we are going to create a Magazine class with the following attributes and behaviors. Do not forget to use encapsulation when creating the class.
Attributes of Magazine
  • Title: String
  • Issue: String
  • Price: double
Behaviors related to Magazine
  • Sell: void sell(int qty)
public class Magazine {
    private String title;
    private String issue;
    private double price;

    public String getTitle() {
        return this.title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getIssue() {
        return this.issue;
    }

    public void setIssue(String issue) {
        this.issue = issue;
    }

    public void setPrice(double price) {
        if (price > 0) {
            this.price = price;
        } else {
            System.out.println("Invalid price");
        }
    }

    public double getPrice() {
        return this.price;
    }

    public void sell(int qty) {
        System.out.println("Total: $" + (qty * price));
    }
}
Compare the Magazine class with the Book class. Book has a unique attribute author and the Magazine has a unique attribute issue. Other than those properties all other properties and methods are common for both of them. So we have duplicate codes in these classes. If Newsletters also have similar attributes, what should be the code? It is fine, just copy and paste the code to the Newsletter class. For DVDs… why not? Again copy and paste the code to the DVD class. So if you have Book, Magazine, Newsletter and DVD, you will end up with the same code in four different places. Assume that, there is a bug identified in the sell() method; now we need to debug the same code in four different places, it is not cool. If you have debugged a code, then you need to retest the entire class to make sure that you have not introduced any new bugs. It increases the testing cost. We already increased the coding cost (with an assumption that Ctrl, C & V keys are disabled in your keyboard). Now the problem is, how can we eliminate the code duplication?

Welcome To Inheritance
Nature is a great inspiration for all the inventions in science. That’s true for Object Oriented Programming as well. My siblings and I have almost same behaviors because we have the same parents. This is called inheritance. In the same way, we are going to create a parent class (In OOP we call it as super class) and children classes (call them sub classes), where children can inherit the parent's features. Think about Book and Magazine; they can have a common parent Publication. Now find out the common variables and methods for Book and Magazine, and move them to the Publication class.
public class Publication {
    // Title of the publication.
    private String title;
    // Price of the publication.
    private double price;

    public String getTitle() {
        return this.title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setPrice(double price) {
        if (price > 0) {
            this.price = price;
        } else {
            System.out.println("Invalid price");
        }
    }

    public double getPrice() {
        return this.price;
    }

    public void sell(int qty) {
        System.out.println("Total: $" + (qty * price));
    }
}
Then modify the class declaration of Book and Magazine as shown below.
Highlight: Book extends Publication & Magazine extends Publication
public class Book extends Publication {
    // Author of the book.
    private String author;

    public String getAuthor() {
        return this.author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}
public class Magazine extends Publication {
    // Author of the magazine.
    private String issue;

    public String getIssue() {
        return this.issue;
    }

    public void setIssue(String issue) {
        this.issue = issue;
    }
}

Note
Inheritance is not applied to private and static members. The reason for private variables is very simple; private variables/methods are visible only to their own class. If inheritance is allowed, the sub classes also can access them. Therefore, no inheritance for private members. Inheritance for static members usually confuse the developers. Again I want to repeat “NO INHERITANCE FOR STATIC MEMBERS”. However, the following code prints the output “Publication” without any errors.
public class StaticInheritance {
    public static void main(String[] args) {
        Book.print();
    }
}

class Publication {
    public static void print() {
        System.out.println("Publication");
    }
}

class Book extends Publication {

}
In this code we call the print() method using a sub class. If it is possible, doesn't it mean static members are inherited to sub classes? Lets do a trick and check the output. At this point I want to refresh the static initialization block here.
Static initialization blocks are guaranteed to execute at the class loading time. In other words when Java Virtual Machine loads the class into the memory, it searches for static initialization blocks and execute them.

In the following code there is a static initialization block in the Publication class, which is used to print a message “Load Publication to memory.”. Another static initialization block is there in the Book class to print "Load Book to memory.". If inheritance is applied Java must load both classes and execute the method from the Book class, so the output should be "Load Publication to memory", "Load Book to memory" and "Publication".
public class StaticInheritance {
    public static void main(String[] args) {
        Book.print();
    }
}

class Publication {
    static {
        System.out.println("Load Publication to memory.");
    }

    public static void print() {
        System.out.println("Publication");
    }
}

class Book extends Publication {
    static {
        System.out.println("Load Book to memory.");
    }
}
But, the output is “Load Publication to memory.” and “Publication” only. “Load Book to memory” is not printed; it means Book class is not loaded to the memory. Now we can confirm that there are no inheritance for static members. In fact Java renames the Book.print() as Publication.print() in background.

IS-A and HAS-A Relationship
OOP defines two relationships which are IS-A and HAS-A relationships. IS-A relationship, refers the inheritance between two classes. In our example, Book is a sub class of Publication. It can be referred as Book IS-A Publication. In the same manner Magazine IS-A Publication also true.
If a class has a reference of another class, it is a HAS-A relationship. For example, in the following code the relationship between Computer and Mouse is: Computer HAS-A Mouse.
public class Computer {
    private Mouse mouse;
}

public class Mouse {

}

Sample Problem
In the Encapsulation tutorial, we enhanced the VeterinaryDoctor code by introducing encapsulation. The encapsulated code is provided here and there is code duplication in the Cat and Dog classes. Find out a suitable class name for a super class of Cat and Dog and apply the inheritance to the Cat and Dog classes.

To compare your solution click on this link.

Find the source codes at Git Hub.

The complete Object Oriented Programming article series are available here:
Object Oriented Programming:
            Encapsulation
            Inheritance
            Polymorphism
            Abstraction
Previous
Next Post »

Contact Form

Name

Email *

Message *