next up previous contents
Next: Generic functions Up: Abstract classes Previous: Abstract classes   Contents

Abstract Classes

We may use a class only as a collective ``name'' for a group of related classes. For instance, we might have classes such as

  class Circle{
    private double radius;
     ...
    public double perimeter(){
     ...
    }
     ...
  } 

  class Square{
    private double side;
     ...
    public double perimeter(){
     ...
    }
     ...
  } 

  class Rectangle{
    private double length;
    private double width;
     ...
    public double perimeter(){
     ...
    }
     ...
  }

and combine these all under a class Shape so that

  class Circle extends Shape{...}
  class Square extends Shape{...}
  class Rectangle extends Shape{...}

We don't actually intend to create objects of the parent type Shape, but we can use Shape to enforce some common properties of the classes that extend Shape. For example, we might want to insist that each subclass of Shape define a method with the signature

  public double perimeter();

Though this method can be defined to yield a sensible value in each subclass of Shape, there is no reasonable definition that we can provide for the quantity perimeter() in an ``abstract'' Shape. We could, of course, create a dummy function in Shape, such as

  public double perimeter() { return -1.0; }

that returns an absurd value.

This way, each subclass of Shape will definitely be able to access a method of the required signature, but we want more: we want to insist that the subclass redefines this method to a sensible value.

The way to do this is to specify the signature of perimeter() in Shape, but say it is only a template that has to be implemented in any subclass. We declare a method to be a template by using the word abstract as follows:

  public abstract double perimeter();

If a class contains an abstract method, it makes no sense to create an instance of that class since it is not fully specified. Such a class is itself called abstract. Thus, we have:

  abstract class Shape{
    ...
    public abstract double perimeter();
    ...
  }

If a class has any abstract methods, it must be abstract, but the converse is not true. An abstract class may have concrete instance variables and methods. For instance, we might allow each Shape to have an unique identifier and define this field in common as:

  abstract class Shape{
    private String identifier;

    public Shape(String s){   // Constructor to set private variable
      identifier = s;         // Call with "super(s)" from subclass
    }

    ...
    public abstract double perimeter();
    ...
  }

In fact, technically a class may be declared abstract even though it contains no abstract components!

Let us call a class concrete if it is not abstract: A concrete class is one that we can instantiate as an object. In order for a subclass to be concrete, it must provide an implementation for all abstract methods that it inherits from above. Otherwise, the subclass also becomes abstract.

Though we cannot create instances (objects) of an abstract class, we can declare variables of this class. We can continue to use an array of the higher class to hold a mixed collection of objects from the lower level, as in the example below:

  Shape sarr[] = new Shape[3];

  Circle c = new Circle(...);   sarr[0] = c; 
  Square s = new Square(...);   sarr[1] = s;
  Rectangle r = new Rectangle(...);  sarr[2] = r;

  for (i = 0; i < 2; i++){
    size = sarr[i].perimeter(); // calls the appropriate method
    ...
  }


next up previous contents
Next: Generic functions Up: Abstract classes Previous: Abstract classes   Contents
Madhavan Mukund 2004-04-29