Effective Java-Interface or abstract class

Source: Internet
Author: User

There are two mechanisms for Java to provide multiple implementations of an abstraction-Interface and abstract class.


Interface and abstract class,
In addition to the obvious differences (i.e., the ability to provide a basic implementation),
The important difference is that the implementation class for an interface can be at any point in the class hierarchy, and the subclass of the abstract class is subject to this limitation.

Existing classes can is easily retrofitted to implement a new interface.

That is, if a class is to implement an interface, simply add the implements statement and method implementation.
Inheriting an abstract class can break the class hierarchy, for example, when classes belonging to two different classes want the behavior of an abstract class, we need to reorganize the class hierarchy.

Interfaces is ideal for defining mixins.

(The word "mixin" does not know how to translate, translated into "mixed type" looks very stiff.) )
Personally, this article and the first article almost illustrate the same problem.
As for Mixin, the author uses comparable as an example, and its implementation class shows that his instances have the ability to compare with each other.
Abstract classes cannot be arbitrarily updated into existing classes, and, given the class hierarchy, it is more appropriate to provide a class with an abstract-time interface for a behavior.

Interfaces allow the construction of nonhierarchical type frameworks.

In fact, class hierarchies are not useless, but we need to think about whether they need to be organized into a strict hierarchy.
For example, do singers and composers need hierarchies? Obviously they have no hierarchical relationship.

That

public interface Singer{    AudioClip sing(Song s);}public interface Songwriter{    Song compose(boolean hit);}


If it is a creative singer, he needs to expand both singer and songwriter.
Fortunately, both of the above are interface, so we can:

public interface SingerSongwirter extends Singer, Songwriter{    AudioClip strum();    void actSensitive();}


If you try to use an abstract class to solve this problem,
Perhaps we can use the object of one class as the field of another class,
Perhaps we can also organize them into class-level relationships.
But if the number of classes is increasing and more combinations appear, the structure becomes more and more bloated (PS: called "Combinatorial Explosion").


In addition, to say that the interface is more obvious "disadvantage", that is, can not provide any implementation.
However, it is important to note that this feature does not replace the abstract class with an interface.
A good way to combine the two is that this usage is common.
For example, Apache Shiro's Defaultsecuritymanager class level (of course, Shiro is still being perfected ...) :

That is, provide an abstract skeleton implementation (skeletal implementation) for the definition in the interface, combining the advantages of the interface and the abstract class.

Typically, an abstract class has such naming conventions for interfaces that provide skeletal implementations, such as Abstractset and set, Abstractcollection, and collection.

If I use this skeletal to achieve, would not be subject to the class level of trouble?
That's true, but skeletal's meaning is not flexibility.
To give a sample of the code in the book, Static factory methods use the skeletal class to return an integer list (PS: Excessive use of automatic unpacking ...) :

public class IntArrays {    static List<Integer> intArrayAsList(final int[] a) {        if (a == null)            throw new NullPointerException();        return new AbstractList<Integer>() {            public Integer get(int i) {                return a[i];             }            @Override            public Integer set(int i, Integer val) {                int oldVal = a[i];                a[i] = val;                 return oldVal;             }            public int size() {                return a.length;            }        };    }}


Another example of Apache Shiro, in the Org.apache.shiro.realm.Realm interface, has a description:

Most users would not be implement the Realm interface directly, but would extend one of the subclasses, {@link Org.apa Che.shiro.realm.AuthenticatingRealm Authenticatingrealm} or {@link Org.apache.shiro.realm.AuthorizingRealm}, Greatly reducing the effort requird to implement a realms from scratch.


That is, the direct implementation of an interface is a tedious task. We also recommend using its subclasses (not necessarily, of course), such as:

org.apache.shiro.realm.CachingRealm CachingRealmorg.apache.shiro.realm.AuthenticatingRealm AuthenticatingRealmorg.apache.shiro.realm.AuthorizingRealm

Of course, there are also simple implementation, such as:

org.apache.shiro.authc.pam.ModularRealmAuthenticator


Here is an example of writing a skeletal in the book:

Public abstract class Abstractmapentry<k, v> implements Map.entry<k, v> {//Primitive operations Public    Abstract K GetKey ();    Public abstract V GetValue (); Entries in modifiable maps must override this method public V SetValue (v value) {throw new Unsupportedoperat    Ionexception ();  }//Implements The contract of Map.Entry.equals @Override public boolean equals (Object o) {if (O        = = this) return true; if (! (        o instanceof Map.entry)) return false;        map.entry<?,? > arg = (map.entry) o;    Return Equals (GetKey (), Arg.getkey ()) && equals (GetValue (), Arg.getvalue ());    } private static Boolean Equals (object O1, Object O2) {return O1 = = null? o2 = = Null:o1.equals (O2); }//Implements The contract of Map.Entry.hashCode @Override public int hashcode () {return Hashco    De (GetKey ()) ^ hashcode (GetValue ()); } private static INT Hashcode (Object obj) {return obj = = null? 0:obj.hashcode (); }}


There are some limitations to writing a skeletal implementation relative to providing an implementation class.
First you must understand which of the interfaces is the most basic behavior and leave it to the subclass implementation, and skeletal is responsible for the other methods in the interface (or none) or its feature-related implementations.
In addition, the value of the skeletal class is inherited, and a little attention may break encapsulation because of inheritance.
Classes designed for inheritance also need to provide documentation, such as which methods are self-use, classes implement Serializable, or clonnable ...


In addition to providing the "advantage" of the basic implementation, the abstract class has an advantage: the change of the abstract class is easier than the change of the interface.
That is, adding methods to abstract classes in subsequent releases is easier than adding methods to the interface.
It is not possible to add a method in a public interface without destroying the implementation class (even if the following is the skeletal class, there will always be an implementation class in the Detect).
Therefore, the design of the interface is a technical work, once it is decided not to change.


The choice between an abstract class and an interface can be said to be a choice between scalability and flexibility in some ways.

Effective Java-Interface or abstract class

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.