Review:    generalizing classes with common properties and/or actions

  • A circle is-a geometric shape --- A rectangle is-a geometric shape

  • The generalization of circles and rectangles are "geometric shapes":

      • Geometric shapes are closed figures created using points, line segments, circles, and curves.

Review:    generalizing classes with common properties and/or actions

        

  public class GeometricObject
  {
     private String color;
     public double getArea() { return 0; }  // Dummy body.
                                            // Important for polymorphism
  }

  public class Circle extends GeometricObject  // "inherits"
  {
     private double radius; // Add more properties...
  }

  public class Rectangle extends GeometricObject  // "inherits"
  {
     private double width;  // Add more properties...
     private double height;
  }

Review:    Polymorphism

  • A superclass variable can reference to a subclass object:

        GeometricObject a;
    
        a = new Circle("red", 2);
        a = new Rectangle("blue", 1, 2);  

  • Because the GeometricObject class contains the getArea() method, we can use a GeometricObject (reference) variable to invoke getArea():

        a = new Circle("red", 2);
        a.getArea();   // Invokes Circle's    getArea() 
    
        a = new Rectangle("blue", 1, 2); 
        a.getArea();   // Invokes Rectangle's getArea()  

  • Polymorphism is the ability to invoke different methods using a superclass variable

Review:    Application of polymorphism

  • We wrote the selectionSort() method on an array of GeometricObject 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]
    	       ----------------------------------------------- */
                int minIndex = findSmallest(list, i );
      
    	    /* ------------------------------------------------------
                   Swap list[i] with list[minIndex] if necessary;
    	       ------------------------------------------------------ */
    	    if ( minIndex != i ) 
    	    {   // Swap list[minIndex] and list[i]
    	        GeometricObject help = list[minIndex];
                    list[minIndex] = list[i];
    		list[i] = help;
                }
            }
        } 

Review:    Application of polymorphism

  • This selectionSort() method can sort Circle objects

        public static void main(String[] args)
        {
            GeometricObject[] myList = new GeometricObject[4];
                                       // Array of GeometricObjects objs
    
            myList[0] = new Circle("red", 2);   // Allowed !
            myList[1] = new Circle("blue", 1);  // Allowed !
            myList[2] = new Circle("white", 5); // Allowed !
            myList[3] = new Circle("black", 3); // Allowed !
     
            selectionSort(myList);
    
            for ( int i = 0; i < myList.length; i++)
               System.out.println(myList[i]);
        }
      

Review:    Application of polymorphism

  • This selectionSort() method can also sort Rectangle objects

        public static void main(String[] args)
        {
            GeometricObject[] myList = new GeometricObject[4];
                                       // Array of GeometricObjects objs
    
            myList[0] = new Rectangle("red", 2, 1);   // Allowed !
            myList[1] = new Rectangle("blue", 1, 1);  // Allowed !
            myList[2] = new Rectangle("white", 5, 1); // Allowed !
            myList[3] = new Rectangle("black", 3, 2); // Allowed !
     
            selectionSort(myList);
    
            for ( int i = 0; i < myList.length; i++)
               System.out.println(myList[i]);
        }
      

Methods with dummy body are neccesary for polymorphism

Defining the getArea() method in the superclass is neccessary for the polymorphism mechanism:

                  

  public class GeometricObject
  {
     private String color;
     public double getArea() { return 0; }  // Neccesary for polymorphism
  }

  public class Circle extends GeometricObject  // "inherits"
  {
     private double radius; // Add more properties...
  }

  public class Rectangle extends GeometricObject  // "inherits"
  {
     private double width;  // Add more properties...
     private double height;
  }

However, having meaningless dummy body code can be very confusing....

Abstract methods

  • Abstract method:

      • An abstract method is a method without an associated method body

  • Syntax to define an abstract method:

       AccessModifier abstract returnType methodName( parameters ) ;  

  • Example: we can define the getArea() method as an abstract method as follows:

          public abstract double getArea() ;  

  • Note:

      • An abstract method is incomplete !!!

      • A class that contains an abstract method must be a special kind of class: an abstract class

Abstract classes

  • Abstract class:

      • An abstract class is a class defined using the keyword abstract

  • Syntax to define an abstract class:

       public abstract class className
       {
          ... 
      
          // May contain an abstract method...
       } 

  • Rule:

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

      • An abstract class do not need to contain an abstract method !

A better way to write the GeometricObject class (as an abstract class)   the subclasses

public class Circle extends GeometricObject
{
    private double radius;

    Circle(String col, double r)
    {
        super(col);
        radius = r;
    }

    public double getRadius()         
    { 
        return radius;
    }

    public double getArea()
    {
        return 3.14159*radius*radius;
    }

    public String toString()
    {
        return "Color = " + getColor() + ":"
                + "radius = " + radius;
    }
}
 
public class Rectangle extends GeometricObject
{
    private double width;
    private double height;

    Rectangle(String col, double w, double h)
    {
        super(col); width = w; height = h;
    }

    public double getWidth()          { return width;}
    public void   setWidth(double r)  { width = r; }
    public double getHeight()         { return height;}
    public void   setHeight(double r) { height = r; }

    public double getArea()       
    {
        return width*height;
    }
    
    public String toString()
    {
        return "Color = " + getColor() + ":"
                + "width = " + width
                + " height = " + height;
    }
}

A better way to write the GeometricObject class (as an abstract class)   Before using abstract class

public class GeometricObject
{
    private String color;

    GeometricObject( String col ) 
    {
        color = col;
    }

    public String getColor()          
    { 
        return color; 
    }

    public void   setColor(String c)  
    { 
        color = c; 
    }   

    public double getArea() 
    {
        return 0;   // Dummy method body     
    }
} 
public class myProg
{
    public static void main(String[] args)
    {
        GeometricObject a;
        
        a = new Circle("red", 2);
        System.out.println(a.getArea());
                // Invokes Circle's getArea()

        a = new Rectangle("blue", 1, 2); 
        System.out.println(a.getArea()); 
               // Invokes Rectangle's getArea()  
    }
}









A better way to write the GeometricObject class (as an abstract class)   After using abstract class

public abstract class GeometricObject
{
    private String color;

    GeometricObject( String col ) 
    {
        color = col;
    }

    public String getColor()          
    { 
        return color; 
    }

    public void   setColor(String c)  
    { 
        color = c; 
    }   

    public abstract double getArea() ;       
 
 
 
} 
public class myProg
{
    public static void main(String[] args)
    {
        GeometricObject a;
        
        a = new Circle("red", 2);
        System.out.println(a.getArea());
                // Invokes Circle's getArea()

        a = new Rectangle("blue", 1, 2); 
        System.out.println(a.getArea()); 
               // Invokes Rectangle's getArea()  
    }
}









An important restriction on abstract classes

  • Restriction imposed on abstract classes:

      • You cannot create objects using an abstract class

    I.e.: the new operator cannot be used with an abstract class:

        new abstractClass( )  // Illegal   

  • Example: this is illegal with the last example:

        GeometricObject a = new GeometricObject("red")  // Illegal   

More information on abstract classes

Inheriting abstract methods:

  • Abstract methods are inherited !!!

  • If a class (Circle) inherits some abstract methods (getArea()), it must be defined as an abstract class

    .... unless all inherited abstract method (getArea()) have been overridden

  • Example:

    public class Circle extends GeometricObject
    {
        ....
    
        public double getArea() // Override abstract method
        {
            return 3.14159*radius*radius;
        }
    } 

More information on abstract classes

Constructors in abstract classes:

  • Abstract classes can have private instance variables:

    public abstract class  GeometricObject
    {
        private String color;
    
        GeometricObject(String col)
        {
            color = col; // Initial private variable
        }
        ....
    } 

    Therefore:

      • Abstract classes can have constructors (used to initialize the private instance variables !)

  • The constructors are used by a subclass to initialize private variables in the abstract superclass

More information on abstract classes

There is no relationship between abstract classes and concrete classes in the inheritance hierarchy:

  • An abstract class can extend a concrete class:

    public abstract class GeometricObject
                          // It extends Object which is concrete
    {
        ...
        public abstract double getArea() ;       
    } 

  • An concrete class can extend an abstract class:

    public class Circle extends GeometricObject
    {
        ....
    
        public double getArea() // Override abstract method
        {
            return 3.14159*radius*radius;
        }
    }
    

Summary

  • An abstract class is defined with the abstract keyword

          public abstract class ClassName
          {
              ....
          } 

  • If a class contains an abstract method, then the class must be defined as an abstract class

  • An abstract class behaves exactly like a concrete class....

    Except:

      • You cannot use the new operator with an abstract class to instantiate objects