Witscale Test Center

2.3 Implementing three basic principles of OOP in Java > 2.3.2 Classes and inheritance


2.3.2 Classes and inheritance


Inheritance is another structuring principle for objects besides the classes. With inheritance, you can specify that a class is a special kind of another class. By doing so, it can reuse some generic behavior of that class. Let us try to understand inheritance with a simple animal taxonomy. In figure 2.3, simple animal taxonomy[**] is illustrated. Animals are classified by increasing degree of specialization.

Figure 2.3 Animal taxonomy

 

 When you say that a butterfly is a special kind of winged insect, you are establishing a connection that helps you reuse the knowledge you already have about winged insects. Everything you know about the winged insects is also true about butterflies.

Now let us apply this idea to the banking application we are discussing. Assume that you need to define different types of accounts such as the checking account, savings account, etc. You may decide to write separate classes for these account types, say for instance, the CheckingAccount and SavingsAccount class. These classes would be very similar to Account class and will be implementing most of the functionality, which Account already has. Java has a way of avoiding this duplication of efforts. You can declare the   CheckingAccount and SavingsAccount classes being inherited[††] from the Account class.  By doing so these classes can reuse its implementation. Figure 2.4 shows the class hierarchy of the Account class.

 


Figure 2.3 Inheriting the Account class functionality for reuse

 

 

CheckingAccount and SavingsAccount can reuse the implementation because they inherit it from their superclass Account.

 

As a rule of thumb, you can use the inheritance principle when the class-in-question is a kind-of (AKO or IS-A) another class. For example, the classes CheckingAccount and SavingsAccount establish the AKO(a-kind-of) relationship with the Account class (i.e. ‘CheckingAccount is a-kind-of Account’) and therefore can be inherited from it.

 

Advantages of inheritance

Inheritance is used to reuse the implementation in general. This reuse has multifaceted advantages. Primarily it cuts the redundancy in implementation. Common behavior is separated and placed in superclass and subclasses only need to implement the specialized behavior. The advantage is that whenever you need to make any changes in the common behavior, you only need to do it in one place in superclass. Since subclasses inherit it, they will automatically inherit the modified implementation. 

Another way of code reuse: Composition

Composition is another technique for reusing the class functionality besides inheritance. In this technique, a class simply places an object of another class (whose-functionality-it-wants-to-use) inside itself. This is like “creating a member object”.  Often you will find that you may need functionality of several other objects. Hence your new class can very well be composed of several objects of different types. For example, A Car class may be declared to be composed several other objects such as carEngine, tyres, stereo etc. Because you are composing a new class from existing classes, this concept is called composition.

Both inheritance and composition are for reusing the implementation. However, you are not always free to use whichever you want. You need to make a right choice based on the objects in your problem domain and their relationship. For example, let us discuss the concept with three classes, Car, Automobile and CarEngine. The Car class is probably inherited from the Automobile class as a Car is a-kind-of Automobile. On the other hand, the relation between the Car and the CarEngine is not a AKO
(a-kind-of) relation. A Car is not a-kind-of engine or vice versa. Think a bit and you will notice that “A car has an engine”. Therefore, the Car class would have an engine object as its member. In other words a Car would be composed of an engine and other objects. This way it can sill use the functionality of the engine object without making any incorrect assumptions about their relationship. Figure 2.4 illustrates the iheritance (IS-A) relationship between Car and Automobile class. It also show the HAS-A relationship beween the Car and Engine classes using the UML notation.


Figure 2.4 The IS-A and HAS-A relationship of Car class with the Automobile & Engine class respectively

 

Figure 2.4 uses UML notation to illustrate inheritance and composition. The arrow head touching Automobile class represents inheritance. The black diamond represents composition. It is placed on the Car class because it is the Car HAS-A Engine. The arrowhead on the other end of the relationship denotes that the relationship is navigable in only one direction. That is, Engine does not (need not) know about the Car. In UML relationships are assumed to be bidirectional unless the arrowhead is present to restrict them.