For some applications we might want a generic base class that we
will never instantiate. Instead we will only create instances of
subclasses of that base class that add specific attributes.
In the following frequently used type of example, we create a
base class Shape
to provide a method to return the area of 2-D shapes represented
by various subclasses.
public
class Shape {
double
getArea ()
{ return 0.0;}
}
public
class Rectangle extends
Shape {
double ht = 0.0;
double
wd = 0.0;
public double
getArea ()
{ return (ht*wd);
public void
setHeight(double
ht)
{ this.ht = ht;
}
public void
setWidth (double
wd)
{ this.wd = wd;
}
}
public
class Circle extends
Shape {
double
r = 0.0;
public double
getArea ()
{ return (3.14
* r * r); }
public void
setRadius (double
r)
{ this.r = r;
}
}
|
The subclasses Rectangle
and Circle
extend Shape
and each overrides the getArea()
method. We could define similar subclasses for other shapes
as well. Each shape needs a unique area calculation so we do
not include a default area calculation in the base class.
The capability to reference instances of Rectangle
and Circle
as Shape
types brings the advantage of treating a set of different types
of shapes as one common type. For example, in the following code,
a Shape
array passed in the argument list contains references to different
types of subclass instances.
void
double aMethod (Shape []
shapes)
{ areaSum = 0.0;
for (int
i=0; i < shapes.length; i++)
{
areaSum += shapes.getArea();
}
}
|
We calculate the sum of the areas of the array
objects with a simple loop that calls the getArea()
method for each instance.
This polymorphic
aspect of OOP means that the subclass's overriding version of
getArea()
will execute, not that of the base class.
Abstract Class
By declaring a method and a class abstract,
we make it explicit that the user of our classes must override
the method and must never instantiate the Shape
class
In the above case, we can redefine our Shape
class and the getArea()
method as abstract as shown here:
abstract
class Shape {
abstract int
getArea();
}
|
Note that if any method is declared abstract, the class must
be declared abstract as well or the compiler will give an error
message.
An abstract class can include concrete methods and fields.
In fact, an abstract class does not need to include any abstract
methods. The abstract modifier simply indicates that the class
cannot be instantiated.
Note that an abstract method has no code body, no braces
{}.
All of the abstract methods must be overridden by methods
in the concrete subclasses.