Inheritance disadvantage

Unlike method invocation, inheritance violates encapsulation. Since you don't know the super class implementation which may involve some unpredictable calling between different methods of super class. And it is difficult to maintain the subclass when there is a change of the super class.

Be careful with the interaction between inner methods of the superclass. Here is the demo.

package com.effectivejava.classinterface;

import java.util.Collection;

import java.util.Set;

/**

* @author Kaibo

*

*/

// Wrapper class - uses composition in place of inheritance

public class InstrumentedSet<E> extends ForwardingSet<E> {

private int addCount = 0;

public InstrumentedSet(Set<E> s) {

super(s);

}

@Override

public boolean add(E e) {

addCount++;

return super.add(e);

}

@Override

public boolean addAll(Collection<? extends E> c) {

addCount += c.size();

return super.addAll(c);

}

public int getAddCount() {

/* If you directly extends one implementation such as HashSet<E> of the Set<E> interface you will get the wrong addCount since the addAll method invoke the add method internally which has been override by your sub class.

*/

return addCount;

}

}

/**

* Implementation of prefer to composite to inherence.

*/

package com.effectivejava.classinterface;

import java.util.Collection;

import java.util.Iterator;

import java.util.Set;

/**

* @author Kaibo

*

*/

// Reusable forwarding class

public class ForwardingSet<E> implements Set<E> {

private final Set<E> s;

public ForwardingSet(Set<E> s) {

this.s = s;

}

public void clear() {

s.clear();

}

public boolean contains(Object o) {

return s.contains(o);

}

public boolean isEmpty() {

return s.isEmpty();

}

public int size() {

return s.size();

}

public Iterator<E> iterator() {

return s.iterator();

}

public boolean add(E e) {

return s.add(e);

}

public boolean remove(Object o) {

return s.remove(o);

}

public boolean containsAll(Collection<?> c) {

return s.containsAll(c);

}

public boolean addAll(Collection<? extends E> c) {

return s.addAll(c);

}

public boolean removeAll(Collection<?> c) {

return s.removeAll(c);

}

public boolean retainAll(Collection<?> c) {

return s.retainAll(c);

}

public Object[] toArray() {

return s.toArray();

}

public <T> T[] toArray(T[] a) {

return s.toArray(a);

}

@Override

public boolean equals(Object o) {

return s.equals(o);

}

@Override

public int hashCode() {

return s.hashCode();

}

@Override

public String toString() {

return s.toString();

}

}

Wrapper class (Composite) disadvantage

Wrapper classes are not suited for use in callback frameworks, wherein objects pass self-references to other objects for subsequent invocations ("callbacks").

To avoid the method invoke subclass's overrided version

You can eliminate a class's self-use of overridable methods mechanically, without changing its behavior. Move the body of each overridable method to a private "helper method" and have each overridable method invoke its private helper method. Then replace each self-use of an overridable method with a direct invocation of the overridable method's private helper method.

Effective Java 16 Favor composition over inheritance的更多相关文章

  1. Effective Java 26 Favor generic types

    Use generic types to replace the object declaration Add one or more type parameters to its declarati ...

  2. Effective Java 27 Favor generic methods

    Static utility methods are particularly good candidates for generification. The type parameter list, ...

  3. Effective Java 60 Favor the use of standard exceptions

    Benefits to reuse preexisting exceptions It makes your API easier to learn and use. Programs using y ...

  4. Effective Java Index

    Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...

  5. 《Effective Java》读书笔记 - 4.类和接口

    Chapter 4 Classes and Interfaces Item 13: Minimize the accessibility of classes and members 一个好的模块设计 ...

  6. Effective Java Chapter4 Classes and Interface

    MInimize the accessibility of classes and members 这个叫做所谓的 information hiding ,这么做在于让程序耦合度更低,增加程序的健壮性 ...

  7. Effective Java 目录

    <Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...

  8. 【Effective Java】阅读

    Java写了很多年,很惭愧,直到最近才读了这本经典之作<Effective Java>,按自己的理解总结下,有些可能还不够深刻 一.Creating and Destroying Obje ...

  9. 《Effective Java》读书笔记 - 3.对于所有对象都通用的方法

    Chapter 3 Methods Common to All Objects Item 8: Obey the general contract when overriding equals 以下几 ...

随机推荐

  1. js-计时事件

    JavaScript 一个设定的时间间隔之后来执行代码,称之为计时事件. 主要通过两个方法来实现:     1.setInterval() - 间隔指定的毫秒数不停地执行指定的代码.     2.se ...

  2. R提高篇(二): 图形初阶

    目录: 图形示例 图形参数 符号.线条 颜色 文本属性 尺寸与边界 自定义标题 自定义坐标轴 图例 文本标注 图形组合 图形示例 如下代码描述病人对两种药物五个剂量水平上的响应情况 > myda ...

  3. dock基本使用

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

  4. IOS开发UI基础 UIAlertView的属性

    UIAlertView1.Title获取或设置UIAlertView上的标题. 2.Message获取或设置UIAlertView上的消息 UIAlertView *alertView = [[UIA ...

  5. (8)分布式下的爬虫Scrapy应该如何做-图片下载(源码放送)

      转载主注明出处:http://www.cnblogs.com/codefish/p/4968260.html 在爬虫中,我们遇到比较多需求就是文件下载以及图片下载,在其它的语言或者框架中,我们可能 ...

  6. 暴力 + 贪心 --- Codeforces 558C : Amr and Chemistry

    C. Amr and Chemistry Problem's Link: http://codeforces.com/problemset/problem/558/C Mean: 给出n个数,让你通过 ...

  7. 使用“原生”HTML DOM获取input的输入值并显示

    理论基础 HTML <input> value属性.value规定<input>元素的值.value对于不同input类型,用法也不同. 1.对于"button&qu ...

  8. PHP图像处理类库及演示分享

    简单写了一个PHP的图像处理类库,虽然功能比较少,但是目前也没用到太高级的,以后用到了再填吧,或者哪位给点建议加上什么功能,或者有什么需求可以跟我说,我有时间加上,如果哪位对这个类库进行了扩展的话,还 ...

  9. 利用Spring创建定时任务

    啊Spring Task看似很简单的感觉,但是自己搞起来还是花了蛮大的精力的,因为以前没接触过这个东西,所有当任务交给我的时候,我是一头的雾水的.然后我就各种查资料.其中我印象最深的是版本的问题和架包 ...

  10. java int转byte和long转byte

    在网络编程中,出于节约带宽或者编码的需要,通常需要以原生方式处理long和int,而不是转换为string. public class ByteOrderUtils { public static b ...