2.18 Frameworks2.17 Abstract Classes2 Java with Caffeine2.19 Visibility Modifiers

2.18 Frameworks

The only purpose of an abstract class is to serve as a placeholder in a class hierarchy in order to define a minimal interface for its subclasses. Methods may freely use abstract classes as types of parameters and variables.

The attentive reader may notice that in this respect abstract classes serve a purpose similar to interfaces. This is basically true but there are two important differences:

  1. A class may only inherit from one other (abstract) class but it may implement multiple interfaces;
  2. In an interface, all methods are abstracts; in an abstract class, some methods may be not abstract.

As for the second item, we may implement our class Printable also as

   abstract class Printable
   {
     abstract String getString();

     void printNice(Printable o)
     {
       System.out.println("-- begin object ------------------ ");
       System.out.println(getString());
       System.out.println("-- end object -------------------- ");
     }
   }

i.e., the class contains printNice as a dynamic method. This method invokes the (abstract) method getString to determine the actual text representation of the object.

Using this class, we can now declare the subclass MyInteger as shown above and call

   Printable i = new MyInteger(7);
   i.printNice();

The class MyInteger therefore inherits the functionality of printNice from Printable but it provides the functionality of getString.

An abstract class that provides by non-abstract methods functionality but leaves by abstract methods "gaps" to be filled by subclasses is also called a  framework. It provides the skeleton functionality of an application but still needs to be customized: a subclass has to fill the skeleton with "flesh" by providing implementations of the abstract methods.

A framework may also give default implementations for the abstract methods such as in

   class Printable
   {
     String getString()
     {
       return "This object has no string representation."
     }

     void printNice(Printable o)
     {
       System.out.println("-- begin object ------------------ ");
       System.out.println(getString());
       System.out.println("-- end object -------------------- ");
     }
   }

Here we provide a body for getString (such that the method and the class are not abstract any more). Nevertheless, we want a subclass to override this method by a more specific one such as in the class MyInteger shown above.


© Wolfgang Schreiner; February 3, 2005

2.18 Frameworks2.17 Abstract Classes2 Java with Caffeine2.19 Visibility Modifiers