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. [linux]查看linux下端口占用

    netstat netstat -an | grep 23 (查看是否打开23端口) 查看端口占用情况的命令:lsof -i [root@www ~]# lsof -i COMMAND PID USE ...

  2. 利用 ELK系统分析Nginx日志并对数据进行可视化展示

    一.写在前面 结合之前写的一篇文章:Centos7 之安装Logstash ELK stack 日志管理系统,上篇文章主要讲了监控软件的作用以及部署方法.而这篇文章介绍的是单独监控nginx 日志分析 ...

  3. 浅谈Mysql的MyIsam存储类型

    前两年的工作,用NoSql多一些!最近进入了传统的软件开发公司,开始使用Mysql多了!不过对于我这种ABC级别的人来说,还是好好看书吧! 我常常觉得,如果我们不是明白原理,而只是知道一些概念,或者说 ...

  4. dock基本使用

    通过Docker源安装最新版本通过Docker源安装最新版本 要安装最新的 Docker 版本,首先需要安装 apt-transport-https 支持,之后通过添加源来安装.要安装最新的 Dock ...

  5. ASP.NET MVC 5 默认模板的JS和CSS 是怎么加载的?

    当创建一个默认的mvc模板后,项目如下: 运行项目后,鼠标右键查看源码,在源码里看到头部和尾部都有js和css文件被引用,他们是怎么被添加进来的呢? 首先我们先看对应的view文件index.csht ...

  6. 在Linux上安装Oracle RAC 12 c(12.1) 虚拟机,一步一步向导

    Oracle RAC 12 c(12.1)在Linux上安装虚拟机,一步一步向导 今天我们将看到如何安装 12 c版本1 RAC(真正的应用程序集群)数据库2 Linux 64位的虚拟机 使用VMWa ...

  7. WCF 4.0 使用说明

    WCF 4.0开发说明,工具VS2013 ,IIS,使用http协议 打开VS2013,新建项目Visual C#>Web>Asp.NET Web应用程序,添加相关引用: System.S ...

  8. 一个Linq表达式的扩展函数帮助类

    /// <summary> /// Linq表达式的扩展函数 /// </summary> public static class ExpressionExtensions { ...

  9. C#引用C++代码

    现在在Windows下的应用程序开发,VS.Net占据了绝大多数的份额.因此很多以前搞VC++开发的人都转向用更强大的VS.Net.在这种情况下,有很多开发人员就面临了如何在C#中使用C++开发好的类 ...

  10. (旧)子数涵数·C语言——指针

    一.什么是指针? 指针在百度的解释:是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值. 也就是说,指针是用于指向某一内存单元. 简而化之,指针便是地 ...