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. Mysql学习笔记(十四)备份与恢复

    学习内容: 1.数据库的重要数据备份... 2.什么时候需要使用到数据库备份.. 3.如何恢复备份的数据.. 1.备份: 说到备份,相比大家都不应该陌生,比如说我们平时在为我们的电脑重新做系统的时候, ...

  2. ASP.NET跨服务器上传文件的相关解决方案

    第一种:通过FTP来上传文件 首先,在另外一台服务器上设置好FTP服务,并创建好允许上传的用户和密码,然后,在ASP.NET里就可以直接将文件上传到这台 FTP 服务器上了.代码如下: <%@ ...

  3. IOS开发UI基础storyboard相关概念的认识

    本文主要介绍一些基本的概念 为后面的学习做个准备 需要了解的知识点有以下几个方面: storyboard文件的认识 IBAction 和IBOutlet UIViewController控制器的认识 ...

  4. Redis设计与实现-附加功能

    发布与订阅 redis订阅分为精准的频道订阅与模糊匹配的模式订阅: redis将所有频道的订阅关系都保存在服务器状态pubsub_channels字典里,键是频道名,值是一个记录所有订阅此频道的客户端 ...

  5. [团队项目]expat不兼容BUG

    本周五软工团队项目的第一次前后端全部对接时,出了一个蛋疼的错误. 最初起因是小丽叔出于安全的考虑,使用守护进程来跑Web服务器.守护进程(Daemon)是运行在后台的一种特殊进程,如果服务器用root ...

  6. 译:Datetime类型的扩展

    译文出处:http://www.codeproject.com/Articles/870939/Datetime-Extensions 本文主要针对System.DateTime类型的一系列扩展.包括 ...

  7. U3D自定义Inspector项未触发保存事件的解决方案

    1.问题描述与解决方案 1.1.说明 应该只有起步做U3D编辑器插件的部分同行需要了解本文. 该问题源于在做UI插件的时候,发现Inspector面板上手动修改值后,没有触发U3D编辑器本身的修改事件 ...

  8. 使用PreparedStatement执行SQL语句时占位符(?)的用法

    1.Student数据库表 ID  name gender       2.Java代码 public static void main(String[] args) { int _id=1; Str ...

  9. php中的抛出异常和捕捉特定类型的异常

    测试环境:PHP5.5.36  Safari 9.1.2   异常捕获,在现在很多ide工具里都可以用快捷键很方便的添加上,防止用户看到自己看不懂的报错甚至莫名其妙崩溃,导致用户体验不好. 哪怕显示一 ...

  10. Hibernate之lazy延迟加载(转)

    一.延迟加载的概念 当Hibernate从数据库中加载某个对象时,不加载关联的对象,而只是生成了代理对象,获取使用session中的load的方法(在没有改变lazy属性为false的情况下)获取到的 ...