First, let's talk about the notes in interface and abstract method syntax.
Interface:
1. An interface can contain in fields, but these are implicitly static and final.
2. You can choose to explicitly declare the methods in an interface as public, but they are public even if you don't say it.
3. Interface cannot define static method
Abstract:
1. If all methods in a class are implemented, we can still define this class as abstract class.
2. abstract and static cannot be put together to define methods.
Interface and Abstract class practices
1. The interface is suitable for defining mixins (I don't know how to translate mixin. It refers to a narrow interface and only defines specific contract ).
Java cannot be inherited multiple times. To achieve the multi-inheritance effect, a typical use of "Multi-Implementation" interface. interface is to define a small interface. For example, Comparable. In this way, the implementation cost is relatively small, and a class is easier to mixin multiple interfaces.
2. If the interface is not mixin, It is a larger interface.
Valid java, 2nd edition has a wonderful explanation. For large interfaces, we often use skeletal implementation class. For example:
1: // Concrete implementation built atop skeletal implementation
2: static List <Integer> intArrayAsList (final int [] ){
3: if (a = null)
4: throw new NullPointerException ();
5: return new effecactlist <Integer> (){
6: public Integer get (int I ){
7: return a [I]; // Autoboxing (Item 5)
8 :}
9: @ Override public Integer set (int I, Integer val ){
10: int oldVal = a [I];
11: a [I] = val; // Auto-unboxing
12: return oldVal; // Autoboxing
13 :}
14: public int size (){
15: return a. length;
16 :}
17 :};
18 :}
New effecactlist <Integer> is the application of Skeletal implementation. There are two advantages:
A) It makes it easier to implement interfaces.
B) If, in a subsequent release, you want to add a new method to an abstract class, you can always add a concrete method containing a reasonable default implementation. all existing implementations of the abstract class will then provide the new method. this does not work for interfaces.
Another topic related to the interface is wrapper class, which is also very exciting. It converts inheritance into a synthesis method and applies the decorater pattern. In chapter 16th of the book, we will introduce it.
1: // Wrapper class-uses composition in place of inheritance
2: public class InstrumentedSet <E> extends ForwardingSet <E> {
3: private int addCount = 0;
4: public InstrumentedSet (Set <E> s ){
5: super (s );
6 :}
7: @ Override public boolean add (E e ){
8: addCount ++;
9: return super. add (e );
10 :}
11: @ Override public boolean addAll (Collection <? Extends E> c ){
12: addCount + = c. size ();
13: return super. addAll (c );
14 :}
15: public int getAddCount (){
16: return addCount;
17 :}
18 :}
19: // Reusable forwarding class
20: public class ForwardingSet <E> implements Set <E> {
21: private final Set <E> s;
22: public ForwardingSet (Set <E> s) {this. s = s ;}
23: public void clear () {s. clear ();}
24: public boolean contains (Object o) {return s. contains (o );}
25: public boolean isEmpty () {return s. isEmpty ();}
26: public int size () {return s. size ();}
27: public Iterator <E> iterator () {return s. iterator ();}
28: public boolean add (E e) {return s. add (e );}
29: public boolean remove (Object o) {return s. remove (o );}
30: public boolean containsAll (Collection <?> C)
31: {return s. containsAll (c );}
32: public boolean addAll (Collection <? Extends E> c)
33: {return s. addAll (c );}
34: public boolean removeAll (Collection <?> C)
35: {return s. removeAll (c );}
36: public boolean retainAll (Collection <?> C)
37: {return s. retainAll (c );}
38: public Object [] toArray () {return s. toArray ();}
39: public <T> T [] toArray (T [] a) {return s. toArray ();}
40: @ Override public boolean equals (Object o)
41: {return s. equals (o );}
42: @ Override public int hashCode () {return s. hashCode ();}
43: @ Override public String toString () {return s. toString ();}
44 :}
Use its client program:
1: Set <Date> s = new InstrumentedSet <Date> (new TreeSet <Date> (cmp ));
2: Set <E> s2 = new InstrumentedSet <E> (new HashSet <E> (capacity ));
3. All people say interface-oriented programming, which is often overdone. Interfaces are often reconstructed rather than always designed. In program hierarchy, the closer the program is to the underlying program, the more interface is required. The closer the program is to the top layer, the less interface requirement. If you know that it is unlikely to provide another set of implementations in the future, writing an interface in advance makes no sense, although the cost of defining an interface is very low. If you worry that another set of implementations is provided one day, refactoring the code will not be very troublesome. As long as they comply with the single responsibility principle and the dimit law. One expression of the Demeter law is: talk only to your immediate friends