...
An alternative idea is to prefer abstract classes for dealing with constant evolution, but this that comes at the cost of flexibility that interfaces offer (a class may implement multiple interfaces but extend only one class). One notable pattern is for the provider to distribute an abstract skeletal class that implements the evolving interface. The skeletal class can selectively implement a few methods and force the extending classes to provide concrete implementations of the others. If a new method is added to the interface, the skeletal class can provide a nonabstract default implementation that the extending class can optionally override. This noncompliant code example shows such a skeletal class.
| Code Block | ||
|---|---|---|
| ||
public interface User {
boolean authenticate(String username, char[] password);
void subscribe(int noOfDays);
void freeService(); // Introduced after the API is publicly released
}
abstract class SkeletalUser implements User {
public abstract boolean authenticate(String username, char[] password);
public abstract void subscribe(int noOfDays);
public void freeService() {
// Added later, provide implementation and re-release class
}
}
class Client extends SkeletalUser {
// Implements authenticate() and subscribe(), not freeService()
}
|
...