A. Introduction
As discussed, the Player class has three subclasses: NFLPlayer, NBAPlayer, and MLBPlayer while the Shape class has three subclasses: Circle, Rectangle, and Triangle. So it is reasonable to write:
Player a = new NFLPlayer("Steven Cohan"); or
Shape tri = new Triangle(3, 4, 5);
As a matter of fact, since any player is either an NFLPlayer, an NBAPlayer, or a MLBPlayer, the above is the most reasonable statement to create a Player object, since there is no such a thing as a Player who is only a Player object, but neither an NFLPlayer, an NBAPlayer nor a MLBPlayer object. For a Player object, there is not enough information to run the annualSalary() method.
Similarly, there is not enough information to run the area() or perimeter() method on a Shape object without knowing if it is a Triangle, a Circle, or a Rectangle.
So for superclasses such as Player or Shape (Employee as well), it is meaningless to create objects of these classes themselves since there is not enough information to run some or all of its methods. Hence these classes are considered "abstract" classes. An abstract class can not be instantiated.
Typically, an abstract class has at least one abstract method, which is supposed to be implemented in its subclasses. For example, there is no suitable default implementation of the area(), perimeter() in the Shape class, or the weeklyPay() in the Employee class because it has to be implemented differently in each subclass. The abstract superclass only includes the method signature to indicate this method will be overridden in all of its subclasses. This method has to be declared "abstract" as shown below:
public abstract class Shape{
private String name; // an instance variable
public abstract double area();
public abstract double perimeter();
public String toStr(){ return "Default Shape(the super class)";} // a concrete method
}
B. A quick summary about abstract classes:
It is meaningless to define perimeter and area methods for Shape—thus, these are declared as abstract methods.
An abstract class can have both instance variables and concrete (nonabstract) methods. See the Shape class above.
Abstract methods are declared with the keyword abstract. There is no method body. The header is terminated with a semicolon.
A concrete (non-abstract) subclass of an abstract superclass must provide implementation code for all abstract methods of the superclass. Therefore the Circle, Triangle, and Rectangle classes implement both the perimeter() and area() methods.
It is possible for an abstract class to have no abstract methods. In this case, declaring the class as abstract prohibits creating objects of the class.
No objects can be created for an abstract class even though the abstract class may have constructors. The constructors can be called by the subclasses.
If a subclass of an abstract superclass does not implement the abstract methods it inherits, the subclass itself has to be declared as abstract. In this case, the abstract methods will be implemented in the grandchild class.
Polymorphism works with abstract classes as it does with concrete classes:
Shape circ = new Circle(10, 1, 1);
Shape tri = new Triangle(3, 4, 5);
Shape s = null;
System.out.println("Which shape: 1-Circle, 3-Triangle, 4-Rectangle?");
int sh = in.nextInt(); //read user input
if (sh==1) s = circ;
else s = tri;
System.out.println("Area is: "+ s.area()); // s.area() is a polymorphic call
C. Try this: Question 16-18 on page 157 on Barron's AP CS A.