Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Object-oriented language basics, Part 4

Inheritance: Build objects in layers

  • Print
  • Feedback
The computer-animated movie Shrek focuses on an ogre's journey to rescue a princess from a dragon so he can get his swamp back from a bunch of fairy-tale squatters. During their journey to the dragon's lair, Shrek and his donkey companion discuss Shrek's attitude towards others, and Shrek tells the donkey that ogres have layers. Ogres aren't the only things that have layers; Java objects also have them -- thanks to the principle of inheritance.

If you follow the Java 101 column, you know that we are currently touring Java's object-oriented language basics. So far, this series has covered class declaration, object creation, field/method (including constructor method) declaration and access, and object layering. Furthermore, I have introduced the specialized topics of enumerated types and singletons.

Read the whole series on object-oriented language basics:



What is inheritance?

We encounter inheritance -- the ability to derive something specific from something generic -- in everyday life. For example, a blue Mazda RX-7 parked next to a fire hydrant (and in danger of being towed) is a specific instance of the generic car category. Continuing with the example, a shiny red Dodge Ram Pickup traveling down the highway is a specific instance of the generic truck category. If you take the car and truck categories to another level, both categories relate to each other by being specific instances of the even more generic vehicle category. In other words, cars and trucks are vehicles. Figure 1 schematizes the relationships between a Mazda RX-7 entity, the car category, a Dodge Ram Pickup entity, the truck category, and the vehicle supercategory.

Figure 1. The relationships between a Mazda RX-7, a Dodge Ram Pickup, and the vehicle supercategory. The arrows point from specific entities to generic categories.

Consider a second example: You deposit some money into a savings account. Later, you write a check from your checking account to pay your Visa bill. At some point, money transfers from your checking account to Visa. What do your savings and checking accounts have in common? Nothing, apart from being bank accounts. In other words, savings and checking accounts inherit state (such as a current amount of money) and behaviors (such as "open the account" and "close the account") from the bank account category. Figure 2 diagrams the relationships between checking account and savings account entities on the one hand and the bank account category on the other.

Figure 2. The relationships between a checking account, a savings account, and the bank account category. As in Figure 1, arrows point from the more specific to the more generic.

Entities are the tangible things with which we interact -- the Mazda RX-7 and your Bank of America savings account, for example. Categories relate entities and other categories in a hierarchy: your Bank of America savings account relates to other savings accounts through the savings account category, and the bank account supercategory relates to the general checking and savings account categories. To use an upside-down tree metaphor (where the root is on top of a hierarchy, and the leaves are on the bottom -- the format of Figures 1 and 2), categories are the tree's branches, and entities are the tree's leaves. The branch hierarchy of categories organizes the tree's general shape (architecture of entities), and the leaves (entities) are instances of the lowest branch (category).

The examples presented thus far illustrate single inheritance. With single inheritance, an entity directly inherits state and behaviors from one (and only one) category. For example, the Mazda RX-7 entity inherits from the car category -- and only the car category. In contrast, multiple inheritance allows an entity to directly inherit state and behavior from two or more categories. For example, Jane Doe is an employee of some firm. To be more specific, Jane is both a manager and an accountant; she inherits the capabilities of both a manager and an accountant, as Figure 3 illustrates.

Figure 3. Jane Doe is both an accountant and a manager.

Extending classes

From Java's perspective, inheritance manifests itself either through the act of extending classes (known as implementation inheritance) or through the act of implementing interfaces (known as interface inheritance). In this section, you'll investigate implementation inheritance. (I'll present interfaces and interface inheritance in a later column.)

According to implementation inheritance, new classes derive capabilities (expressed as fields and methods) from existing classes, which saves development time by encouraging the reuse of proven and debugged classes. The following syntax expresses the concept of extending classes in source code:

'class' classIdentifier1 'extends' classIdentifier2
'{'
   // Fields and methods
'}'


The above syntax reads as follows: classIdentifier1 extends classIdentifier2. In other words, classIdentifier1 inherits (or derives) capabilities (expressed through fields and methods) from classIdentifier2. The classIdentifier1 is known as a subclass, a derived class, or a child class; classIdentifier2 is known as a superclass, a base class, or a parent class.

The extends keyword causes a subclass to inherit all fields and methods declared in a nonfinal superclass (including the superclass's superclasses). The subclass can access all inherited nonprivate fields and methods; it cannot access any inherited private fields and methods (at least not directly). Consider the following example:

class Point
{
   private double x, y;
   Point (double x, double y)
   {
      this.x = x;
      this.y = y;
   }
   double getX ()
   {
      return x;
   }
   double getY ()
   {
      return y; 
   }
}
class Circle extends Point
{
   private double radius;
   Circle (double x, double y, double radius)
   {
      super (x, y); // Call Point (double x, double y).
      this.radius = radius;
   }
   double getRadius ()
   {
      return radius;
   }
}


The code above consists of two classes: Point and Circle. Point describes a point, which is nothing more than an (x, y) coordinate pair (expressed as double-precision floating-point values). Circle describes a circle -- a Circle is a Point with a radius. If you were to create an object from Circle, you would end up with the multilayered object diagrammed in Figure 4.

  • Print
  • Feedback

Resources