Feature

Interface

Abstract class

Defining a type that permits multiple implementations

Y

Y

Permitted to contain implementations.

N

Y

The implemented class must reside the class hierarchy.

N

Y

Single inheritance

N

Y

Easy to evolve

N

Y

Advantages of Interfaces

  1. Existing classes can be easily retrofitted to implement a new interface.
  2. Interfaces are ideal for defining mixins.
  3. Interfaces allow the construction of nonhierarchical type frameworks. (Composite)

    public interface Singer {

    AudioClip sing(Song s);

    }

    public interface Songwriter {

    Song compose(boolean hit);

    }

    public interface SingerSongwriter extends Singer, Songwriter {

    AudioClip strum();

    void actSensitive();

    }

  4. Interfaces enable safe, powerful functionality enhancements .
You can combine the virtues of interfaces and abstract classes by providing an abstract skeletal implementation class to go with each nontrivial interface that you export.

// Concrete implementation built atop skeletal implementation

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]; // Autoboxing (Item 05)

}

@Override public Integer set(int i, Integer val) {

int oldVal = a[i];

a[i] = val; // Auto-unboxing

return oldVal; // Autoboxing

}

public int size() {

return a.length;

}

};

}

Simulated multiple inheritance

The class implementing the interface can forward invocations of interface methods to a contained instance of a private inner class that extends the skeletal implementation.

// Skeletal Implementation

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 UnsupportedOperationException();

}

// Implements the general 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 = (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 general contract of Map.Entry.hashCode

@Override

public int hashCode() {

return hashCode(getKey()) ^ hashCode(getValue());

}

private static int hashCode(Object obj) {

return obj == null ? 0 : obj.hashCode();

}

}

Note

  1. Because skeletal implementationsare designed for inheritance, you should follow all of the design and documentation guidelines in Item 17.
  2. A minor variant on the skeletal implementation is the simple implementation. It differs by being not abstract. It's just simplest possible working implementation. You can use it as it stands or subclass it as circumstances warrant.

Summary

If you export a nontrivial interface, you should strongly consider providing a skeletal implementation to go with it. Once an interface is released and widely implemented, it is almost impossible to change. The best thing to do when releasing a new interface is to have as many programmers as possible implement the interface in as many ways as possible before the interface is frozen. Finally, you should design all of your public interfaces with the utmost care and test them thoroughly by writing multiple implementations

Effective Java 18 Prefer interfaces to abstract classes的更多相关文章

  1. Effective Java 53 Prefer interfaces to reflection

    Disadvantage of reflection You lose all the benefits of compile-time type checking, including except ...

  2. Effective Java 20 Prefer class hierarchies to tagged classes

    Disadvantage of tagged classes 1. Verbose (each instance has unnecessary irrelevant fields). 2. Erro ...

  3. Effective Java 69 Prefer concurrency utilities to wait and notify

    Principle Use the higher-level concurrency utilities instead of wait and notify for easiness. Use Co ...

  4. Effective Java 13 Minimize the accessibility of classes and members

    Information hiding is important for many reasons, most of which stem from the fact that it decouples ...

  5. Effective Java 19 Use interfaces only to define types

    Reason The constant interface pattern is a poor use of interfaces. That a class uses some constants ...

  6. Effective Java 35 Prefer annotations to naming patterns

    Disadvantages of naming patterns Typographical errors may result in silent failures. There is no way ...

  7. Effective Java 68 Prefer executors and tasks to threads

    Principle The general mechanism for executing tasks is the executor service. If you think in terms o ...

  8. Effective Java 25 Prefer lists to arrays

    Difference Arrays Lists 1 Covariant Invariant 2 Reified at runtime Erased at run time 3 Runtime type ...

  9. Effective Java 46 Prefer for-each loops to traditional for loops

    Prior to release 1.5, this was the preferred idiom for iterating over a collection: // No longer the ...

随机推荐

  1. Javascript起源...

    Javascript的设计思路是这样的: (1)借鉴C语言的基本语法: (2)借鉴Java语言的数据类型和内存管理: (3)借鉴Scheme语言,将函数提升到"第一等公民"(fir ...

  2. 缓存池扩展 (Buffer Pool Extension)实践

    SQL Server 2014缓存池扩展 (Buffer Pool Extension)功能可以将缓存池扩展到较快的SSD存储上.为内存比较紧张的系统提供了新的扩展途径. Buffer Pool 扩展 ...

  3. ChartDirector应用笔记(三)

    前言 继上篇文章(Simple bar chart)推出之后,本篇文章继续ChartDirector的使用.在这篇Blog中,博主实现的是soft lighting bar.soft lighting ...

  4. CSS浏览器兼容性写法小结

    *        , ie6,ie7可以识别: _和- ,  ie6可以识别: !important  ,表示高优先级,ie7及以上,firefox都支持,ie6认识带!important的样式属性, ...

  5. [转]在SqlServer 中解析JSON数据

      在Sqlserver中可以直接处理Xml格式的数据,但因为项目需要所以要保存JSON格式的数据到Sqlserver中在博客:Consuming JSON Strings in SQL Server ...

  6. LeetCode131:Palindrome Partitioning

    题目: Given a string s, partition s such that every substring of the partition is a palindrome. Return ...

  7. .NET向APNS苹果消息推送通知

    一.Apns简介: Apns是苹果推送通知服务. 二.原理: APNs会对用户进行物理连接认证,和设备令牌认证(简言之就是苹果的服务器检查设备里的证书以确定其为苹果设备):然后,将服务器的信息接收并且 ...

  8. EffectiveJava——复合优先于继承

    继承时实现代码重用的重要手段,但它并非永远是完成这项工作的最佳工具,不恰当的使用会导致程序变得很脆弱,当然,在同一个程序员的控制下,使用继承会变的非常安全.想到了很有名的一句话,你永远不知道你的用户是 ...

  9. 【iOS】Quartz2D绘图路径Path

    一.绘图路径 A.简单说明 在画线的时候,方法的内部默认创建一个path.它把路径都放到了path里面去. 1.创建路径  cgmutablepathref 调用该方法相当于创建了一个路径,这个路径用 ...

  10. Visual Studio 2013下JSON可视化工具

          Visual Studio 2013现在我们有个小工具可以实现JSON可视化,这样给我们调试JSON提供了便利. JSON这种数据格式已经比较流行,在WEB前端随处可见. 在你需要安装VS ...