Inheritance hierarchy and degree of abstraction

  • In the inheritance hierarchy, classes become more specific and concrete with each new subclass.

  • I.e.:

    • If you move from a subclass towards a superclass, the classes become more general and less specific --- i.e.: more abstract

  • Example:

     

    • You have real life cat and dog "things", but real life "animals" "things"

    • You have real examples of circles, but no concrete "geometric objects"

Intro to abstract classes and abstract methods

  • A superclass contains all the common features of its subclasses

  • A superclass can become so abstract that it is not useful for creating any objects of this type

    Example of classes that are too abstract for creating objects:

    • Animal:   there is no actual animal "thing" in the world

    • GeometricObject:   There is no actual geometric object thing


  • Sometimes, an action (= method) is not well defined

    • You know what the action  is , but you cannot be specific about it

    Example of an abstract action/method:

    • The computation of the area of a geometric object

      There is no formula to compute the area of an arbitrary geometric object

Abstract classes

  • Consider the GeometricObject class:

  • There are no actual GeometricObject things

    (There are only objects that can be categorized as a GeometricObject)

  • Suppose we want to prevent the user from instantiating GeometricObject objects....

    Solution:

    • Define GeometricObject as an abstract class

Abstract classes

  • Abstract class:

    • An abstract class is a class that cannot be instantiated

      I.e.: you cannot create instances of an abstract class using new:

        new GeometricObject() ;   // is not allowed
      

  • Syntax to define an abstract class:

      public abstract class GeometricObject
      {
         ...   // Body of class omitted for brevity
      }

  • Note:

    • Any class can be defined as asbtract !!

DEMO: 14-interfaces/10-abstract-class/Demo.java     (show compile error)

Why have abstract classes if you cannot instantiate objects with them ???

  • You can define (reference) variables of an abstract class type:

      GeometricObject  refVar;
    

  • You can also extend (derive a subclass from) an abstract class:

      public Circle extends GeometricObject
      {
         ...
      }
    

  • Therefore:

    • An abstract class can be used as the superclass for polymorphism !

    Example:

      GeometricObject a;          // GeometricObject is an abstract class
      a = new Circle("red", 10);  // Upcasting
      a.getArea()                 // Polymorphism
    

DEMO: demo/14-interfaces/10-abstract-class/Demo2.java + Circle.java

Using an abstract class to make a method more general

Previously:   we have written the selectionSort() method to sort an array of Circles:

    public static void selectionSort(Circle[] list) 
    {
        for (int i = 0; i < list.length-1; i++)
        {
            /* -----------------------------------------------
               Find the minimum in the list[i..list.length-1]
               ----------------------------------------------- */
           Circle min = list[i];     // Assume first element is min
           int minIndex  = i;           // Index where min is found

           for ( int k = minIndex+1; k < list.length; k++ )
               if ( list[k].getArea() < min.getArea() ) // Sort Circles based by area
               {
                   min      = list[k]; // Update min value
                   minIndex = k;       // Update its index
               }

            /* ------------------------------------------------------
               Swap list[i] with list[minIndex] if necessary
               ------------------------------------------------------ */
            if ( minIndex != i )
            {   // Swap list[minIndex] and list[i]
                Circle help = list[minIndex];  // Standard exchange alg
                list[minIndex] = list[i];
                list[i]        = help;
            }
        }
    } 

 

Using an abstract class to make a method more general

Then we made the selectionSort() method more general by using a superclass data type:

    public static void selectionSort(GeometricObject[] list) 
    {
        for (int i = 0; i < list.length-1; i++)
        {
            /* -----------------------------------------------
               Find the minimum in the list[i..list.length-1]
               ----------------------------------------------- */
           GeometricObject min = list[i];     // Assume first element is min
           int minIndex  = i;           // Index where min is found

           for ( int k = minIndex+1; k < list.length; k++ )
               if ( list[k].getArea() < min.getArea() ) // Sort objects based by area
               {
                   min      = list[k]; // Update min value
                   minIndex = k;       // Update its index
               }

            /* ------------------------------------------------------
               Swap list[i] with list[minIndex] if necessary
               ------------------------------------------------------ */
            if ( minIndex != i )
            {   // Swap list[minIndex] and list[i]
                GeometricObject help = list[minIndex];  // Standard exchange alg
                list[minIndex] = list[i];
                list[i]        = help;
            }
        }
    } 

$64,000 question:   will this solution work if GeometricObject is an abstract class ???

Using an abstract class to make a method more general

Yes:   because we do not need to instantiate any GeometricObject in the program (no new operation used !)

    public static void selectionSort(GeometricObject[] list) // Works without any changes
    {
        for (int i = 0; i < list.length-1; i++)
        {
            /* -----------------------------------------------
               Find the minimum in the list[i..list.length-1]
               ----------------------------------------------- */
           GeometricObject min = list[i];     // Assume first element is min
           int minIndex  = i;           // Index where min is found

           for ( int k = minIndex+1; k < list.length; k++ )
               if ( list[k].getArea() < min.getArea() ) // Sort objects based by area
               {
                   min      = list[k]; // Update min value
                   minIndex = k;       // Update its index
               }

            /* ------------------------------------------------------
               Swap list[i] with list[minIndex] if necessary
               ------------------------------------------------------ */
            if ( minIndex != i )
            {   // Swap list[minIndex] and list[i]
                GeometricObject help = list[minIndex];  // Standard exchange alg
                list[minIndex] = list[i];
                list[i]        = help;
            }
        }
    } 

DEMO: demo/14-interfaces/11-abstract-class/Demo.java + Circle.java + GeometricObject.java

Abtract methods

  • Recall that sometimes, an action (= method) is not well defined

    • You know what the action  is , but you cannot be specific about it

  • An abstract method can be used to describe actions that are not well defined


  • Syntax to define an abstract method:

       public abstract returnType methodName( params );  

    The abstract method definition is used to convey data type information to Java

    The method body is missing because the actions are not well defined

    Example:

       public abstract double getArea( );  


  • Note:   the intension of an abstract method is that it will be override by a subclass!

Example abstract method

  • We can define the getArea() method in GeometricObject class as an abstract method:

    public abstract class GeometricObject
    {
        private String color;
    
        GeometricObject( String col )   // Constructor 2
        {
            color = col;
        }
    
        ...
    
        public abstract double getArea();  // for polymorphism
    }
    

  • The abstract method allow us to avoid the use of dummy methods:

        public double getArea()  // Dummy method defined for polymorphism
        {
            return 0;  // <--- This is an eye sore
                       // Programmers may wonder why we return 0...
        }

DEMO: demo/14-interfaces/12-abstract-method

Relationship between abstract classes and abstract methods

  • Abstract method:

    • An abstract method is an incomplete method

      I.e.:   an abstract method cannot be executed (because it has no body !!)


  • Java rule:

    • A class that contains an abstract method must be defined as an abstract class

    This is to prevent users from instantiating objects that contains incomplete methods !


  • Subclasses of abstract classes:

    • A subclass will inherit the abstract methods in its super class


    • A subclass that do not override all the abstract methods must be defined as an abstract class (because it contains abstract methods)

    • A subclass that override all inherited abstract methods can be defined as a "normal" (= non-abstract) class

  Interaction between the abstract and final qualifiers:   (1) class  

  • Recall that a class can be defined as final:

      public final class myClass
      {
          ...
      }
    

    A class with the final qualifier cannot be extended (i.e., used as a superclass)


  • An abstract class cannot be final:

      public final abstract class myClass      // is not allowed
      {
          ...
      }
    

    because an abstract class must be overriden to be useful

DEMO: demo/14-interfaces/13-final-abstract-class/MyClass.java

  Interaction between the abstract and final qualifiers:   (2) method  

  • Recall that a method can be defined as final:

      public class MyClass
      {
          public final void method1()
          {
             ...    
          }
      }
    

    A method with the final qualifier cannot be overriden


  • An abstract method cannot be final:

      public abstract class MyClass
      {
          public final abstract void method1() ;   // is not allowed
      }
    

    because an abstract method must be overriden to be useful

DEMO: demo/14-interfaces/13-final-abstract-method/MyClass.java

Summary about abstract classes

  • An abstract method cannot be contained in a non-abstract class.

      public abstract class MyClass       // Only abstract classes 
      {                                   // can contain abstract methods
          public abstract void method1() ;   
      }
    

  • It is allowed to define an abstract class that does not contain any abstract methods

      public abstract class MyClass   //prevents user instantiating objects
      {                               
          // Class does not contain any abstract method
      }
    

  • An abstract class cannot be instantiated using the new operator

    But:

    • You can still define its constructors, which are invoked in the constructors of its subclasses.

    • You can define (reference) variables with an abstract class