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.
Object
class is concrete, but may have an abstract subclass like GeometricObject
.
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); ...