HTML Markup | JavaScript | Java | Home & Links

Tutorial 4 - Inheritance & Polymorphism

This tutorial discusses the second and third fundamental object oriented programming principles of inheritance and polymorphism. The first fundamental principle, encapsulation, was discussed in the previous tutorial.

Inheritance

Inheritance is the capability of a class to use the properties and methods of another class while adding its own functionality. An example of where this could be useful is with an employee records system. A generic employee class with states and actions that are common to all employees could be created. Then more specific classes could be defined for salaried, commissioned and hourly employees. The generic class is known as the parent (or superclass or base class) and the specific classes as children (or subclasses or derived classes). The concept of inheritance greatly enhances the ability to reuse code as well as making design a simpler and cleaner process.

The Object class is the highest superclass (ie. root class) of Java. All other classes are subclasses (children or descendants) inherited from the Object class. The Object class methods include: clone(), copy(Object src), equals(), finalize(), getClass(), hashCode(), notify(), notifyAll(), toString() and wait()

Java uses the extends keyword to set the relationship between a parent class and a child class. As an example using the previously defined Box class:

public class GraphicsBox extends Box

The GraphicsBox class assumes or inherits all the properties of the Box class and can now add its own properties and methods as well as override existing methods. Overriding means creating a new set of method statements for the same method signature (name, number of parameters and parameter types). For example:

When extending a class constructor, the superclass constructor and overridden superclass methods can be reused by using the reserved word super. Note that this reference must come first in the subclass constructor. The reserved word this is used to distinguish between the object's property and the passed in parameter.

The reserved word this can also be used to reference private constructors which are useful in initializing properties.

Special Note: final methods, methods in final classes, private methods or static methods can't be overridden.

Abstract Classes

As seen from the previous example, the superclass is more general than its subclass(es). The superclass contains properties and methods common to all of the subclasses. The previous example was of a concrete superclass that instance objects can be created from. Often, the superclass will be set up as an abstract class which does not allow objects of its prototype to be created. In this case, only objects of the subclass are used. To do this the reserved word abstract is included in the class definition.

Abstract methods are methods with no body specification. Subclasses must provide the method statements for their specific meaning. If the method was one provided by the superclass, it would require overriding in each subclass. And if one forgot to override, the applied method statements may be inappropriate.

Abstract classes and methods force prototype standards to be followed (ie. they provide templates).

Interfaces

Interfaces are similar to abstract classes but all methods are abstract and all properties are static final. Interfaces can be inherited (ie. a sub-interface can exist). As with classes the extends keyword is used for inheritence.Java does not allow multiple inheritance for classes (ie. a subclass being the extension of more than one superclass). An interface is used to tie elements of several classes together. Interfaces are also used to separate design from coding as class method headers are specified but not their bodies. This allows compilation and parameter consistency testing prior to the coding phase. Interfaces are also used to set up unit testing frameworks.

As an example, a Working interface for the subclasses of Animal is created. Since this interface has the method called work(), that method must be defined in any class using the Working interface.

When a class that uses an interface is created, reference the interface with the phrase implements Interface_list. Interface_list is one or more interfaces as multiple interfaces are allowed. Any class that implements an interface must include code for all methods in the interface. This ensures commonality between interfaced objects.

Polymorphism

Polymorphism is the ability of an object to take on many forms. In programming languages polymorphism is the capability of an action or method to do different things based on the object that it is acting upon. This is the third basic principle of object oriented programming. The three types of polymorphism are: ad-hoc (overloading and overriding), parametric (ie generic typing) and dynamic method binding.

Overloaded methods are methods with the same name signature but either a different number of parameters or different types in the parameter list. For example 'spinning' a number may mean increase it, 'spinning' an image may mean rotate it by 90 degrees. By defining a method for handling each type of parameter one controls the desired effect.

Overridden methods are methods that are redefined within an inherited or subclass. They have the same signature and the subclass definition is used.

Dynamic (or late) method binding is the ability of a program to resolve references to subclass methods at runtime. For example assume that three subclasses (Cow, Dog and Snake) have been created based on the Animal abstract class, each having their own speak() method. Although each method reference is to an Animal (but no animal objects exist), the program is will resolve the correct method reference at runtime.

Managing Objects

Once a class has been specified, a datatype exists with the same name. Specific instances or discrete copies of a class such as the Box class defined in the last tutorial can be created by using the assignment operator and the new memory allocation operator as in:

Box redBox=new Box(3,4,5);

To reference object variables and methods use dot notation. Use class_name.variable or class_name.method_name(args) for static variables or methods. Use instance_name.variable or instance_name.method_name(args) for instance objects declared with new.

redBox.getLength();

An object does not need to be destroyed or removed when it is no longer needed. Java automatically flags unused objects and applies garbage collection when appropriate. However the finalize() method can be used to insure that a non-Java resource such as a file handle or a window font character is released first. The general form is:

void finalize()
{
  //cleanup code goes here
  super.finalize() //parent too!
}

Project: Circle Class

This small project tests the ability to create a class and then use it to create an object that does something! Circle is a class with property radius and methods setRadius(), showDiameter(), showArea(). Use double precision and 3.14 for π. The math class constant Math.PI should be used once the class libraries tutorial is covered.

Since this is a small project use only one file, say doCircle.java that contains both the main (or driver) class and the Circle class. The driver creates an instance of the Circle class and then displays the diameter and area. Test with radius=3.0 The diameter should read as 6.0 and the area as 28.25999 Once it is working, try to factor it into two files (Circle and doCircle) and compile separately, (the Circle class file first). As an enhancement, try adding a command line argument to set the radius.

Arrays of Objects

As with arrays of primitive types, arrays of objects allow much more efficient methods of access. Note in this example that once the array of Animals has been structured, it can be used to store objects of any subclass of Animal. By making the method speak() abstract, it can be defined for each subclass and any usage will be polymorphic (ie. adapted to the appropriate object type at runtime). It now becomes very easy to rehearse the speak() method for each object by object indexing.

Casting Objects

One of the difficulties of using a superclass array to hold many instances of subclass objects is that one can only access properties and methods that are in the superclass (ie. common to all). By casting an individual instance to its subclass form, one can refer to any property or method. But first take care to make sure the cast is valid by using the instanceof operator. Then perform the cast. As an example using the above Animal class:

Casts to subclass can be done implicitly but explicit casts are recommended. Casts to superclass must be done explicitly. Casts cannot be made between sibling classes.



JR's HomePage | Comments [jatutor4.htm:2014 07 17]