Saturday 9 May 2015

Class Inheritance in Java

 In Java, every class you declare will be derived from another class. You can specify the class to derive from by using the extendskeyword as follows:
public class ClassicCar extends Car { 

    // member methods and variables
}
As you probably noticed, extendswas left out of all the prior examples in this chapter. This is because if a class is not declared as being derived from a specific class, then it is assumed to be derived from the Java base class, Object. This means that the following two class declarations are equivalent:
public class Car {

    // member methods and variables
}

public class Car extends Object {
    // member methods and variables
}

Because Object is the class from which all other Java classes are ultimately derived, this provides a common set of functionality among all Java classes.

Overriding Member Methods

When you create a subclass, you inherit all of the functionality of its superclass, and then you can add or change this functionality as desired. As an example of this, consider the altered declaration of a Car class in the following code:
public class Car {

    private int year;
    private float originalPrice;

    // calculate the sale price of a car based on its cost
    public double CalculateSalePrice() {
        double salePrice; 
        if (year > 1994)
            salePrice = originalPrice * 0.75;
        else if (year > 1990)
            salePrice = originalPrice * 0.50;
        else
            salePrice = originalPrice * 0.25;
        return salePrice; 
    }

    // a public constructor
    public Car(int year, float originalPrice) {
        this.year = year; 
        this.originalPrice = originalPrice;
    }
}
This version of the Car class holds information about the year and the original purchase price of the car. It has a member method, CalculateSalePrice, that determines the price for which to sell the car based on its age. Depending upon the age of the car, it can sell for either 75%, 50%, or 25% of its original price.
Although very simplistic, this is a good start for most cars. However, it is completely inadequate for classic, old cars. This algorithm would indicate that a 1920 Model T would be worth only 25% of its original 1920 price. A slight improvement on this would be to assume that every ClassicCaris worth $10,000. To do this, ClassicCaris derived from Car, as follows:
public class ClassicCar extends Car { 

    // calculate the sale price of a car based on its cost
    public double CalculateSalePrice() {
        return 10000; 
    }

    // a public constructor
    public ClassicCar(int year, float originalPrice) {
        super(year, originalPrice); 
    }
}
Because ClassicCar is derived from Car, it inherits all of the functionality of Car, including its member variables yearand originalPrice. The function CalculateSalePrice appears in both class declarations. This means that the occurrence of this function in ClassicCaroverrides the occurrence of it in Carfor object instances of ClassicCar. As an example of how this works, consider the following:
ClassicCar myClassic = new ClassicCar(1920, 1400);

double classicPrice = myClassic.CalculateSalePrice();

Car myCar = new Car(1990, 12000);
double price = myCar.CalculateSalePrice();
The variable myClassic is of type ClassicCar and is constructed using that class's constructor, which is passed an original price for the car of $1,400. The sale price of this car is calculated and stored in classicPrice. Because myClassic is a ClassicCar, the sale price will be $10,000. Next, myCaris constructed as a new object of type Carwith an original cost of $12,000. Its sale price is determined and stored in price. Because myCar is a Car, its sale price will be based on the year it was made (1990) and will be 25% of $12,000, or $3,000.

The superVariable

In the preceding declaration for ClassicCar, you may have noticed that the constructor made use of a variable named super. Just as each object has a this variable that references itself, each object (other than those of type Object itself) has a supervariable that represents the parent class. In this case, super(year, originalPrice) invokes the constructor of the superclass Car.

Class Modifiers

Classes that are created in Java can be modified by any of three class modifiers. The Java class modifiers are public, final, and abstract. If no class modifier is used, then the class may only be used within the package in which it is declared. A publicclass is a class that can be accessed from other packages. A class that is declared as finalcannot be derived from, meaning it cannot have subclasses.

Abstract Classes

Sometimes you may want to declare a class and yet not know how to define all of the methods that belong to that class. For example, you may want to declare a class called Mammaland include in it a member method called MarkTerritory. However, you don't know how to write MarkTerritorybecause it is different for each type of Mammal. Of course, you plan to handle this by deriving subclasses of Mammal, such as Dog and Human. But what code do you put in the MarkTerritoryfunction of Mammal itself?
In Java you can declare the MarkTerritoryfunction of Mammal as an abstract method. Doing so allows you to declare the method without writing any code for it in that class. However, you can write code for the method in the subclass. If a method is declared abstract, then the class must also be declared as abstract. For Mammal and its subclasses, this means they would appear as follows:
abstract class Mammal {

    abstract void MarkTerritory();
}

public class Human extends Mammal {
    public void MarkTerritory() {
        // mark territory by building a fence
    }
}

public class GangMember extends Mammal {
    public void MarkTerritory() {
        // mark territory with graffiti
    }
}

public class Dog extends Mammal {
    public void MarkTerritory() {
        // mark territory by doing what dogs do
    }
}
With the preceding declarations, the Mammalclass contains no code for MarkTerritory. The Human class could contain code that would mark territory by building a fence around it, while the GangMember class could contain code that would mark territory by spray-painting graffiti. The Dog class would mark territory by raising the dog's leg and doing what dogs do to mark territory.

Implementing Interfaces

Typically, an abstract class will have some methods that are declared as abstract and some that are not. If you find yourself declaring a class that is entirely abstract, you are probably declaring what is known in Java as an interface. An interface is an entirely abstract class. You can derive subclasses from an interface in a manner completely analogous to deriving a subclass from another class.
As an example, suppose you are building an application that must display the hour of the day. Users will have two options for getting this information. They can get it from either a watch or a cuckoo clock. This could be implemented as follows:
interface Clock {

    public String GetTime(int hour);
}

class Cuckoo implements Clock  {
    public String GetTime(int hour) {
        StringBuffer str = new StringBuffer();
        for (int i=0; i < hour; i++)
            str.append("Cuckoo ");
        return str.toString(); 
    }
}

class Watch implements Clock  {
    public String GetTime(int hour) {
        return new String("It is " + hour + ":00");
    }
}
In this example, Clock is an interface that provides a single function, GetTime. What this means is that any class that is derived from (or, in other words, implements the Clockinterface) must provide a GetTimefunction. Cuckoo is an example of a class that implements Clock, and you'll notice that instead of the class Cuckoo extends Clock syntax that would have been used if Clock were an abstract class, it is instead declared with class Cuckoo implements Clock.
Because Cuckoo implements the Clock interface, it provides a GetTime function. In this case, a string is created that will hold as many Cuckoos as specified by the hourparameter. The class Watchalso implements Clock and provides a GetTime function. Its version is a simple message stating the hour.
Interfaces and superclasses are not mutually exclusive. A new class can be derived from a superclass and one or more interfaces. This could be done as follows for a class that implements two interfaces and has one superclass:
class MySubClass extends MySuperClass implements FirstInterface,

        SecondInterface {
    // class implementation
}
Because it is possible for one class to implement more than one interface, interfaces are a very convenient method for implementing a form of multiple inheritance. 

No comments:

Post a Comment