It's not useless at all. It allows you to write code that relies on the object being a Car
without knowing anything about the specific type of Car
.
public abstract class Car {
public abstract void tootHorn();
public abstract void swerve();
. . .
}
public class Driver {
private Car car;
public Driver(Car car) {
this.car = car;
}
public void dealWithDanger() {
car.tootHorn();
car.swerve();
}
. . .
}
In the above code as posted, Car
could just as easily have been an interface
. By making it a class, though, it is possible to implement some methods directly in the Car
class that depends on the (as-yet unspecified) behavior of abstract methods that are specified by subclasses.
The key point of abstract classes is that you never have an instance of the abstract class itself; code can only create instances of some concrete subclass. Nevertheless, lots of application logic can be written to be independent of the specific class of an object.