Abstract classes

advertisement
Abstract classes
If two modules B and C share methods and/or method headers and/or instance variables, then
abstract classes allow us to avoid repeating common code in the definitions of B and C. The
technique is to first write the common components in a stripped-down or abstract class A:
abstract
...
...
...
...
}
class A {
instance variables ...
constructors ...
methods ...
method headers (each beginning with abstract)...
Then write class B as an extension of A, and similarly for C:
class B extends A {
// Note A’s components automatically included.
... complete code for A’s abstract methods...
... and any extra components ...
}
Classes that are not abstract (which is most classes) are said to be concrete.
Example: avoiding code duplication in class definitions
abstract class Shape {
private String name; // will occur in all extensions
Shape(String name0) {name = name0;}
abstract double area(); // no body, note abstract
abstract double perim();
void put() { // will occur in all extensions
System.out.println(name + " with area " + area()+
" and perimeter " + perim());
// ok to use methods whose bodies not yet written
}
}
class Rectangle extends Shape {
private double width, height; // & name inherited
Rectangle(String s, double w, double h) {
super(s); // use Shape constructor; effect is name=s;
width = w; height = h;
Abstract Classes 1
}
double area() {return(width*height);} // body added
double perim() {return((width+height)*2);} // body added
}
class Triangle extends Shape {
private double a, b, c; // lengths of sides
Triangle(String s, double x, double y, double z) {
super(s);
a = x; b = y; c = z;
}
double area() {
double s = (a+b+c)/2.0;
return Math.sqrt(s*(s-a)*(s-b)*(s-c));
}
double perim() {return(a+b+c);}
}
Abstract classes vs Inheritance
The roles of abstract classes and class inheritance are similar. While you may have a choice as to
which technique you use, usually just one is applicable in a given context. For example, we
could not construct Shape above as a class from which Rectangle and Triangle inherit,
because Shape would not then be able to include put (if you don’t see why, try it!).
Abstract classes and polymorphism
Abstract classes encourage generic coding by allowing variables to be declared to be of type A
where A is an abstract class, and to be assigned objects of any class that extends A, e.g.
Shape s1 = new Rectangle("Rectangle",2.0,3.0);
Shape s2 = new Triangle("Scalene",2.0,3.0,4.0);
Shape[] sn = {new Rectangle("Rectangle",2.0,3.0),
new Triangle("Scalene",2.0,3.0,4.0), ...}
Again, the rule of polymorphism applies: wherever a value of abstract class A is specified, we
may supply an object of a type B that extends A (but we may only refer to the components of A).
Example: writing common code
class Shapes {
Abstract Classes 2
private static Shape biggest(Shape[] w) { // Note param type
// biggest shape in w[0..] according to areas, w not empty
Shape max = w[0]; // note type
for (int i=1; i<w.length; i++) {
if (w[i].area()>(max.area()))
max = w[i];
}
return max;
}
public static void main(String args[]) {
Rectangle[] rs = {new Rectangle("Rectangle",2.0,3.0),
new Rectangle("Square",4.0,4.0)};
biggest(rs).put();
Shape[] figs = {new Rectangle("Rectangle",2.0,3.0),
new Triangle("Scalene",5.0,12.0,13.0),
new Rectangle("Square",4.0,4.0)};
biggest(figs).put();
}
}
Square with area 16.0 and circumference 16.0
Scalene with area 30.0 and circumference 30.0
Technical note: biggest(rs) above returns a Rectangle, but the compiler treats it as of
type Shape as that is the return type of biggest. Nevertheless, biggest(rs).put() is
valid as put is a method in Shape.
Overriding (same-naming) applies just as with inheritance (e.g. Triangle could provide its
own put method to override the put in Shape).
Multilevel inheritance
Classes defined by extension can in turn be extended
class Equilateral extends Triangle {
Equilateral(String s, double x) {
super(s,x,x,x);
}
}
Abstract classes in libraries
Libraries that are designed to facilitate application programmers typically include many abstract
classes. The abstract classes contain general code that is useful in many contexts, but which omit
details that are peculiar to each particular context. The programmer uses abstract classes (which
are in compiled form, note) by extending them to create a concrete class with the missing details
for the context he has in mind.
Abstract Classes 3
Download