Java abstract classes and interfaces can implement the separation of functionality and implementation, both of which provide a good support for polymorphism, then we should use the abstract class or interface. In a previous article on the Java Abstract class and interface to talk about their differences in syntax, in the blog through the template method model to understand how to use the Java abstract class in the correct usage of abstract classes, so this time I will from a higher level-design thinking about their differences.
1, abstract class and interface of the abstract level is different
Abstract classes are abstract to class , and interfaces are abstractions of behavior . class contains attributes and behaviors, so interfaces are more specific abstractions.
2, abstract class and interface design level is different
Abstract class is a bottom-up design, the first subclass to extract the common attributes and behavior, abstract the parent class;
Interface is a top-down design, the first set of behavioral methods, as long as they can implement these behaviors, can become the implementation of the interface class.
3. The relationship between an abstract class and its derived class and the interface to its implementation class are different in nature
An abstract class is a "is-a" relationship with its derived class, that is, the conceptual nature of the parent class and the derived subclass is the same (parent-child relationship, kinship, closeness).
interface and its implementation class is a kind of "like-a" relationship, that is, the relationship between interface and implementation class only realizes the behavior of definition, and there is no essential relation (contract relation, indifferent interest relation).
For example: An animal abstract class that defines the method of running, called method, but if a car class can run, can be called, it can inherit animal abstract class? This is unreasonable, the car is not an animal. And if through the interface definition runs the method, called method, the automobile class realizes runs and calls as the realization class, completely OK is reasonable, because has not inherited the relation the restriction.
In order to better illustrate the difference between them, the following will use a good example to illustrate. This example is quoted from the blog post.
We have a door abstract concept that has two behaviors open () and close (), at which point we can define this abstract concept through abstract classes and interfaces:
Abstract class:
Abstract class door{
abstract void Open ();
abstract void Close ();
}
Interface:
Interface door{
void Open ();
void Close ();
}
As for other derived classes, you can pass:
1. Use extends to define door using an abstract class method
2, use the Implements interface method to define door
There is no big difference between the two, but now if we need the door to have the alarm function, then how to achieve it.
Solution One : Add an alarm method to door: alarm ();
Abstract class door{
abstract void Open ();
abstract void Close ();
abstract void alarm ();
}
Or
Interface door{
void Open ();
void Close ();
void alarm ();
}
This approach violates one of the core principles of object-oriented design ISP (Interface segregation principle)-see annotations, in the definition of door, the door concept itself is inherent in the behavior and another concept of the "alarm" behavior method mixed together. One problem with this is that the modules that rely solely on the concept of door will change as the concept of "alarm" changes, and vice versa.
Solution Two :
Since open (), close (), and alarm () are two different concepts, we define them separately in two abstract classes representing two different concepts in terms of the ISP principle, in three ways:
1, two are defined using an abstract class.
2, two are defined using an interface.
3, one uses the abstract class definition, one is uses the interface definition.
Because Java does not support multiple inheritance, the first is not feasible. The following two are all feasible, but choosing what reflects your understanding of the nature of the problem domain.
If the second option is defined by an interface, then two questions are reflected:
1, we may not understand the problem domain, Alarmdoor in the concept is essentially the door also alarm.
2, if we have no problem understanding of the problem domain, for example, we have identified in the analysis of the alarmdoor in the fundamental concept is consistent, then we are not in the design of the correct reflection of our design intent. Because you use two interfaces to define them, the definition of their concepts does not reflect the above meaning.
Third, if our understanding of the problem domain is this: Alarmdoor is inherently door, but it also has the behavioral function of alerting, this time we use a third scenario to illustrate our design intent. The essence of Alarmdoor is that we use abstract classes to define this concept, and Alarmdoor has the function of alerting that it can complete the behavioral functions defined in the alarm concept, so alarm can be defined using interfaces. As follows:
Abstract class door{
abstract void Open ();
abstract void Close ();
}
Interface alarm{
void Alarm ();
}
Class Alarmdoor extends Door implements alarm{Void Open () {} void Close () {}
void Alarm () {}
}
This way of implementation can basically clearly reflect our understanding of the problem area and correctly reveal our design intent. In fact, the abstract class represents a "is-a" relationship, the interface represents the "like-a" relationship, which can be used as a basis when choosing, of course it is based on the understanding of the problem area, for example: if we think that Alarmdoor is essentially an alarm in concept and has door function, So the way this is defined is in turn.
Annotation: ISP (Interface segregation principle): an object-oriented core principle. It shows that using multiple specialized interfaces is better than using a single total interface.
The dependency of a class on another class should be based on the smallest interface.
An interface represents a role and should not be assigned to an interface with different roles. Interfaces that do not have a relationship are merged to form a bloated, large interface that is polluting the roles and interfaces.