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. js-异常处理语句

    程序运行过程中难免会出错,出错后的运行结果往往是不正确的,因此运行时出错的程序通常被强制中止.运行时的错误统称为异常,为了能在错误发生时得到一个处理的机会,JavaScript提供了异常处理语句.包含 ...

  2. UWP开发入门(二十)——键盘弹起时变更界面布局

    UWP APP在键盘弹起或隐藏时,并不会自动处理界面布局.有时会出现键盘遮挡了下一个需要填写的文本框,或是下一步按钮的情况.本篇我们以登录界面做例子,用一种巧妙简单的方式在键盘弹起和隐藏时更改界面的布 ...

  3. mysql 查看当前登陆用户匹配原则及权限user()与current_user()

    Mysql在进行登陆时,会去匹配mysql库中的user表,并赋予相应的权限,但是怎么知道我们当时的登陆的用户名及相应的权限呢? 在Mysql中,有两个函数,一个是user(),一个是current_ ...

  4. margin的使用方法与技巧

    1.margin还可以用来做平移,作用类似translate哈哈.将元素设成absolute后就可以用margin随便平移他了,既不像relative那样要霸占空间,又不用为父元素设置relative ...

  5. 轻量级的移动 webapp 框架Jingle

    一大早爬起来,发现这样的一个东东,国产,感觉实用性很强,试着用用. 1.28补记: 试着用jingle做了一个网站的移动版,感觉如果在布局上要求不高的话 - 目前支持的布局只有list,还是挺不错,做 ...

  6. Visual Studio中设置默认VC++路径

    菜单"View" -> "Other Windows" -> "Property Manager" 选择对应的配置并修改即可.

  7. strtr对用户输入的敏感词汇进行过滤

    /** * 过滤用户输入的基本数据,防止script攻击 * * @access public * @return string */ function compile_str($str) { $ar ...

  8. 【poj 3461】Oulipo(字符串--KMP)

    题意:求子串在文本串中出现了多少次. 解法:使用KMP的next[ ]和tend[ ]数组计数. #include<cstdio> #include<cstdlib> #inc ...

  9. IntelliJ和tomcat中的目录结构

    IntelliJ和tomcat中的目录结构   IntelliJ的官网帮助中心:http://www.jetbrains.com/idea/webhelp/getting-help.html   pr ...

  10. 每个软件都自己把操作系统的host配置项加到内存中供频繁调用

    nginx的转发,http_pass 转发到一个域名passport.ab.cn 那具体是到哪台机器上. 其实可以通过/etc/hosts文件来配置的. 可以理解,这个hosts文件是操作系统级别的, ...