EFFECTIVE JAVA 类和接口
第十六条:复合优先于继承
//这是一个不好的类---执行的结果 addCount = 4(addAll的实现依赖于HashSet的add方法,InstrumentHashSet方法重写了add方法有执行了addCount++)
public class InstrumentHashSet<E> extends HashSet<E> {
private int addCount = 0 ;
@Override
public boolean add(E e) {
System.out.println("子类添加 ");
addCount++;
return super.add(e);
}
@Override
public boolean addAll(Collection<? extends E> c) {
addCount+= c.size();
System.out.println("添加所有 ");
return super.addAll(c);
}
public static void main(String[] args) {
InstrumentHashSet s = new InstrumentHashSet<String>();
s.addAll(Arrays.asList("1","2"));
System.out.println(s.addCount);
}
}
//wrapper class --- use composition in place of inheritance 因为每一个InstrumentedSet 实例都把另一个Set实例包装起来了,所以InstrumentedSet类被称为包装类(这正是Decorator模式)---注意这不是委托(delegation)除非包装对象把自身传递给被包装对象
public class InstrumentedSet<E> extends ForwardingSet<E> {
private int addCount = 0 ;
/**
* 描述: 构造方法
* @param s
*/
public InstrumentedSet(Set<E> s) {
super(s);
}
@Override
public boolean add(E e) {
System.out.println("我执行了InstrumentedSet 的add");
addCount++;
return super.add(e);
}
@Override
public boolean addAll(Collection<? extends E> c) {
System.out.println("执行 addAll c.size= " + c.size() +" count = "+ addCount);
addCount += c.size();
return super.addAll(c);
}
public int getAddcount(){
return addCount;
}
public static void main(String[] args) {
HashSet<Integer> s = new HashSet<Integer>();
s.add(1);
s.add(2);
HashSet<Integer> s1 = new HashSet<Integer>();
s1.add(3);
s1.add(4);
InstrumentedSet is = new InstrumentedSet<Integer>(s);
// is.add(3);
is.addAll(s1);
System.out.println(is.getAddcount());
}
}
//forwarding class 里面的转发方法称为转发方法(forwarding method) 这样得到的类非常的稳固,它不依赖于现有类的实现细节,即使现有的类添加了新的方法,也不会影响新的类
public class ForwardingSet<E> implements Set<E> {
private Set<E> s ;
/**
* 描述: 构造方法
*/
public ForwardingSet(Set<E> s) {
System.out.println("初始化s,类型:"+s.getClass());
this.s = s;
}
@Override
public int size() {
return s.size();
}
@Override
public boolean isEmpty() {
return s.isEmpty();
}
@Override
public boolean contains(Object o) {
return s.contains(o);
}
@Override
public Iterator<E> iterator() {
return s.iterator();
}
@Override
public Object[] toArray() {
return s.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return s.toArray(a);
}
@Override
public boolean add(E e) {
System.out.println("我执行了ForwardingSet 的add");
return s.add(e);
}
@Override
public boolean remove(Object o) {
return s.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return s.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends E> c) {
System.out.println("我执行了addAll");
return s.addAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return s.retainAll(c);
}
@Override
public boolean removeAll(Collection<?> c) {
return s.removeAll(c);
}
@Override
public void clear() {
s.clear();
}
}
测试中的addAll方法实际上走的是HashSet的add方法
EFFECTIVE JAVA 类和接口的更多相关文章
- 要创建一个EJB,必须要至少编写哪些Java类和接口?
要创建一个EJB,必须要至少编写哪些Java类和接口? A. 定义远程(或业务)接口 B. 定义本地接口 C. 定义Bean接口 D. 编写Bean的实现 解答:ABC
- java类,接口浅谈
一般类,抽象类,接口的使用场景: 类;共同的特征和行为的抽取和封装 接口:标准,规范(功能的扩展) 需要对某个类进行功能的扩展,就让某个类实现这个接口,抽取出来称为接口 内部类: ...
- [Java] 类和接口的初始化步骤 - 继承方面
类和接口在初始化化时,处理继承层级的方法不一样. 类继承的初始化:通过引用 static 字段,触发某个类的初始化,则声明该字段的类,以及该类的父类被初始化. 接口继承的初始化:通过引用 static ...
- 和我一起学Effective Java之类和接口
类和接口 使类和成员的可访问性最小 信息隐藏(information hiding)/封装(encapsulation):隐藏模块内部数据和其他实现细节,通过API和其他模块通信,不知道其他模块的内部 ...
- Java 类、接口的API
本章节收集的类/接口API有: Object类,枚举,包装类,接口Comparable,类Arrays,Thread类,System类,Math,BigInteger,Random,日期时间,异常 O ...
- <<Effective Java>>之Comparable接口的实现约定
对于BigDecimal类在HashSet和TreeSet中 new BigDecimal("1.00") new BigDecimal("1.0") 在Has ...
- 10-01 Java 类,抽象类,接口的综合小练习--运动员和教练
运动员和教练的案例分析 运动运和教练的案例 代码实现 /* 教练和运动员案例 乒乓球运动员和篮球运动员. 乒乓球教练和篮球教练. 为了出国交流,跟乒乓球相关的人员都需要学习英语. 请用所学知识: 分析 ...
- Java常用类、接口关系图谱
呕心沥血画出此图,希望在使用Java类.接口时捋顺其关系,从而更好的组织程序逻辑---请看图 Object分出来的类都是其子类 Iterable接口分出的也是子接口 从继承关系分析,其父类实现的接口子 ...
- Java类的加载、链接和初始化
一.Java的类加载机制回顾与总结: 我们知道一个Java类要想运行,必须由jvm将其装载到内存中才能运行,装载的目的就是把Java字节代码转换成JVM中的java.lang.Class类的对象.这样 ...
随机推荐
- 用户空间缺页异常pte_handle_fault()分析--(下)--写时复制【转】
转自:http://blog.csdn.net/vanbreaker/article/details/7955713 版权声明:本文为博主原创文章,未经博主允许不得转载. 在pte_handle_fa ...
- Java工厂模式浅析理解
由于本人缺乏工作经验,本篇文章作为随笔,只是对工厂模式有一个简单的认识 工厂模式分为以下三种: 1:简单工厂(Simple Factory).2:工厂方法(Factory Method).3:抽象工厂 ...
- Centos 环境变量
1. 控制台中,不赞成使用这种方法,因为换个shell,你的设置就无效了,因此这种方法仅仅是临时使用,以后要使用的时候又要重新设置,比较麻烦. 这个只针对特定的shell; $ PATH=" ...
- hdu 5105(数学题)
Math Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 天猫首页迷思之-jquery实现整个div的懒加载(1)
懒加载是众所周知的减少网页负载,提高性能的方法,不少大型用图片用的多的网站都用到了. 于是我网上一搜,得到一插件:jquery.lazyload 网址:http://www.appelsiini ...
- yii2实现WebService 使用 SoapDiscovery
结合SoapDiscovery实现简单的WebService服务 1 修改php.ini文件 php_soap.dll extension=php_soap.dll 2 WebService 实现主要 ...
- ios控件渐变色的处理
+(CAGradientLayer *)gradientColorWithBounds:(CGRect)bounds startColorHexString:(NSString *)startColo ...
- Jquery学习之路(一) 实现checkbox全选方法
昨天早上有写到怎么利用Jquery实现全选 根据大家的意见对程序中一些写法不好的地方进行了修改,也是本人水平有限,存在各种考虑不到的地方. 文章最后我提出了一个问题,要写一个通用的方法来调用,于是就有 ...
- (32)C#文件读写
一.File 类 这是一个静态类,提供用于创建.复制.删除.移动和打开单一文件的静态方法,并协助创建 FileStream 对象 using System.IO; 没有构造函数和属性 写入数据 1. ...
- python全栈开发- day14列表推导式、生成器表达式、模块基础
一.列表推导式 #1.示例 数据量小 egg_list=[] for i in range(10): egg_list.append('鸡蛋%s' %i) egg_list=['鸡蛋%s' %i fo ...