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. UWP开发入门(十六)——常见的内存泄漏的原因

    本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏>中提到过,即使有 ...

  2. 【第三课】ANR和OOM——贪快和贪多的后果(下)

    Out of Mana,法力耗尽. 内存就像法力,耗尽了就什么都不能做了.有时候一个应用程序占用了太大的内存,超过了Android系统为你规定的限制,那么系统就会干掉你,以保证其他app有足够的内存. ...

  3. Winform基础

    1.显示窗口的两种方式: 非模态(Modaless):Show 模态(Modal),阻塞主窗口:ShowDialog() 2.主窗口和对话框之间传递参数,在对话框中申明属性,主窗口给对话框传递值通过参 ...

  4. LRU Cache

    LRU Cache 题目链接:https://oj.leetcode.com/problems/lru-cache/ Design and implement a data structure for ...

  5. Microsoft Visual Studio 2012 文档 下载地址 vs2012 中文帮助文档

    https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=34794 下载地址: http://download.microsoft. ...

  6. JS Date.Format

    // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 个占 ...

  7. Mysql主从备份和SQL语句的备份

    MySQL服务器的主从配置,本来是一件很简单的事情,无奈不是从零开始,总是在别人已经安装好的mysql服务器之上 ,这就会牵扯到,mysql的版本,启动文件,等一些问题. http://www.cnb ...

  8. SQL 日期转换(阳历转阴历)

    --步骤:创建日期表,放初始放初始化资料 --因为农历的日,是由天文学家推算出来,到现在只有到年,以后的有了还可以加入! if object_id('SolarData') is not nulldr ...

  9. asp.net mvc UpdateModel 更新对象后出现null

    在用asp.net mvc 4.0做项目的时候遇到的这种情况 在填写表单的时候,有一些表单没有填写,留空,然后直接post 提交表单,action中用UpdateModel 来更新model, 结果发 ...

  10. Fluent NHibernate example

    http://www.codeproject.com/Articles/26466/Dependency-Injection-using-Spring-NET http://stackoverflow ...