Inheritance: Reading

Inheritance is the biggest reason that object oriented programming has surpassed other programming styles. It is and remains the most useful tool of OOP. C++ is in many ways considered to be the father of OOP but Java made tremendous advancements in its design.

Very simply, inheritance is the idea that one object can inherit from another. This allows tremendous flexibility as far as reusing code goes. We can simply “inherit” the traits of objects that have already been designed and simply add on whatever other features that we need.

Here’s an example. Suppose you are designing a video game and it’s a platformer. The game is already written but you want to create a brand-new world. However, you don’t want to create this world from the bottom up. Why would you? The physics engine, the scaling, the math has already been done. You’ve already created other worlds. Instead, you will inherit all the data that is already established, and simply add on just the new stuff that’s unique only to that world.

Inheritance works in tandem with the ideas of information hiding and data encapsulation to construct object oriented design.

When a class inherits another class, everything is imported over but the constructor and private data. Constructors are never inherited. Private data is inherited but cannot be accessed directly. Consider the following example:

public class classA
{
private intnum1;
public double num2;
final String s1 = “Hello”;
classA
{
// some code
}
public void method1()
{
// some code
}
} / public class classBextendsclassA
{
// the stuff in green is automatically
// inherited, not declared in classB
private int num1;
public double num2;
final String s1 = “Hello”;
public void method1()
{
// some code
}
classB
{
/* since classB inherits classA, the constructor of classA is automatically summoned. */
}
}
ClassB will inherit all of classA except for its constructor. The constructor for classA will get automatically instantiated whenever a call to classB is made. The private variables from classA are inherited but cannot be accessed by classB directly.

The constructor issue and the super() method. Consider the following situation:

class classA
{
classA(int a, int b)
{
// some code
}
} / class classB extends classA
{
classB
{
// some code
}
}
// this is an error
Since classB inherits classA, an instance of classA is automatically declared the second you created classB. But wait, the default constructor no longer exists in classA since another constructor replaced it. We must deal with this issue.
We must allow the instantiation of classA from classB by calling the correct constructor. In Java, the reserved word super allows us to call your parent’s constructors and methods.
class classA
{
classA(int a, int b)
{
// some code
}
} / class classB extends classA
{
classB
{
super(15, 10);
}
}
// correct way to deal with constructor issue
The super method call to your parent’s constructor must be the first line of code in your new constructor. This cannot come anywhere else.

Polymorphism is the idea that an object can take on many forms. The form of an object can be changed through inheritance. A superclass or parent class can be changed down the line as more and more object inherit it.

You can instantiate a parent class with the constructor of its subclass but you cannot go the other way.

Subclasses that inherit from its superclass can override and overload methods. Let’s take a look at both

class classA
{
public void method1()
{
// some code
}
} / class classB extends classA
{
public void method1()
{
// some code
}
}
In the previous example, classB.method1() overrides classA.method1(). It is overridden because the method definition is the same. Same method name and same parameters. Now look at the following.
class classA
{
public void method1()
{
// some code
}
} / class classB extends classA
{
public void method1(int a)
{
// some code
}
}
In the previous example, method1 is an overloaded method. It is overloaded because the method name is the same but it is differentiated through its parameters. Same name but different parameters.

Using the this reserved word.

Suppose I have a private variable counter declared in a class. I wish to create a method that will assign values to that counter. I wish to create a parameter in the method that is also called counter.

class classA
{
int counter;
public void method1(int counter)
{
counter = counter;
}
}
In the example above, the counter referenced both times is the parameter. It has scope above the counter declared outside the method. To fix this, look at the example to the right. / class classA
{
int counter;
public void method1(int counter)
{
this.counter = counter;
}
}
By using the this reserved word, the reference to the counter on left is from the class itself. The reference to the counter on the right is the parameter.

The protected modifier

As we have seen, private variables cannot be directly accessed by their subclasses. A variable that is private has direct access only in its own class. If you inherit a class with a private variable, the only way you can access or change those private variables is to call its accessor or mutator methods.

Let’s say we want to keep things private but allow full access to the class hierarchy. That means that data cannot be accessed outside of the class hierarchy directly but anything that inherits that class can use that data directly.

This is what the protected modifier does. Like private, it keeps outside access off limits. However, it allows access from another class if that class is defined in the same project file.

Here’s an example

class classA
{
private intcounter;
}
class classB
{
counter = 10;
// this is not allowed, counter is private
} / class classA
{
protectedintcounter;
}
class classB
{
counter = 10;
// this is allowed
}

Protected modifier is specifically used during class hierarchy, otherwise public and private are used persistently. If you write a class without any intentions of inheritance, protected modifier is useless.

Abstract Classes / Object

An abstract class is a class that has been written specifically to inherited. An abstract class on its own cannot be instantiated. Its sole purpose is to be inherited.

Consider this. You are writing a classification system for a database of students and teachers. This database will keep track of all the personal information for both students and teachers. Your first instinct may be to create a class for students and class for teachers. But wait, isn’t there some things that both students and teachers would share?

Let’s create a class called Person. There will be characteristics that both students and teachers share (gender, birth date, address, etc.). That would save us coding time. Then, both students and teachers can inherit Person. However, Person is too abstract. Our choices are only teachers and students. There will not be just a Person type, it’s all just students and teachers. Therefore, Person can be an abstract class. It can only be inherited, never created.

All rules of inheritance apply when you deal with an abstract class.

Methods can be declared abstract as well. However, all abstract methods cannot have bodies of code. They are defined only when they are inherited. Any class containing an abstract method must be abstract as well. If a class inherits an abstract with abstract methods, it must define those methods unless the inheriting class is abstract as well.

The Interface

The top level of abstraction in inheritance hierarchy is the interface. An interface is similar to an abstract class in java, but the body of an interface can only include abstract methods and final fields. Like an abstract class, an interface cannot be instantiated anywhere.

An interface is not a class. An interface does not inherit any classes and classes do not inherit them. They do not contain any constructors and to not get instantiated. All data in an interface is final. All methods in an interface are abstract and do not have a body. Everything in an interface is automatically public and cannot be private.

Classes can implement numerous interfaces.

Why bother using an interface? The interface links and entire hierarchy of classes together. As said before, the interface is the highest level of abstraction. Suppose you are the head of a program design team. Each portion of your team is asked to write a piece of the code. You need to make sure that the code written individually lines up with program specification. As a head of a design team, you would use an interface to create a bridge between different teams. All members of that team need to follow the program specification as defined in the interface. Different parts of the team may develop different parts of the interface.