Abstract Classes and Methods

Abstract Classes and Abstract Methods

Notice, in the previously described GeometricObject class, we can't actually implement a getArea() or getPerimeter() method for a GeometricObject in ANY meaningful way, as those methods depend upon what type of shape is involved (circle, rectangle, etc...).

Instead, the Circle and Rectangle subclasses need to override these methods with a meaningful implementation.

So that we don't have to write an implementation for these methods in the GeometricObject class (where they wouldn't make sense, anyways), we declare them as abstract methods in this class. Think of abstract methods as "placeholders" for methods that will eventually be defined in some subclass of the current class.

In doing this, we acknowledge that the Geometric object is not complete in a certain sense -- and it would be inappropriate to instantiate an object of this class. More generally, classes with abstract methods must themselves be declared abstract. That is to say, an abstract method can't be contained in a non-abstract class.

Likewise, if a subclass of an abstract superclass does not implement all the abstract methods of that superclass, the subclass itself must be declared to be abstract. So if one wishes to extend an abstract class, all of the methods of the superclass must be implemented, even if they are not used in the subclass.

Not surprisingly, since they are "incomplete" in a certain sense, ABSTRACT CLASSES MAY NOT BE INSTANTIATED using the new operator.

However, despite not being able to be instantiated, one can still create constructors for abstract classes, which will be invoked via "constructor chaining" upon calls to the constructors of the related subclasses.

Conditions (or lack thereof) on Abstract Classes and Abstract Methods

  1. Certainly, any class that contains abstract methods must be abstract, however -- it is allowable to declare an abstract class that contains no abstract methods. Here too, the abstract class is not allowed to be instantiated using the new operator Such classes typically serve as base classes for defining new subclasses.
  2. A subclass can be abstract even if its superclass is concrete. For example, the Object class is concrete, but may have an abstract subclass like GeometricObject.
  3. A subclass may override a method from its superclass to declare it abstract. This is rare, but useful when the implementation of the method in the superclass becomes invalid in the subclass. Of course, this requires the subclass itself to be declared abstract.

Abstract Class as Type

You can't create an instance from an abstract class using the new operator, BUT abstract classes can be used as legal data types. For example, we can create a reference variable to a Geometric object that references a Circle object, as seen below:

//The uncommented line below is legal even though 
//GeometricObject myGeoObject = new GeometricObject(); <--Error
//is not.

GeometricObject myGeoObject = new Circle(10);     //<--OK
 

//..and this is legal too!

GeometricObject[] myGeoObjects = new GeometricObject[10];  
 

//Note: myGeoObjects above is an array that contains 
//10 references to geometric objects. Of course, to fill 
//the array, you will need to call on the constructors of 
//the subclasses...

myGeoObjects[0] = new Circle(10);
myGeoObjects[1] = new Rectangle(3,4);
myGeoObjects[2] = new Rectangle(5,8);
myGeoObjects[3] = new Circle(7);
...