EffectiveJava(16)复合优先于继承
为什么复合优先于继承?
1.继承违反了封装原则,打破了封装性
2.继承会不必要的暴露API细节,称为隐患.比如通过直接访问底层使p.getProperty(K,V)的键值对可以不是String类型
3.继承限定了类的性能,它会把它的缺陷传递给子类
1.复合:不必扩展现有的Set类,而是在此类中加一个私有域,它引用现有类的一个实例
2.它的封装特性使得它更加健壮灵活
3.复合允许设计新的API隐藏父类的缺点
在继承中的例子
public class InstrumentedHashSet<E> extends HashSet<E> {
//The number of attempted element insertions
//试图插入元素的数量
private int addCount = 0;
public InstrumentedHashSet(){
}
public InstrumentedHashSet(int initCap,float loadFactor){
super(initCap,loadFactor);
}
@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(){
return addCount;
}
}
mian方法
InstrumentedHashSet<String> s = new InstrumentedHashSet<>();
s.addAll(Arrays.asList("Snap","Crackle","Pop"));
//返回的值为6
//在hashSet内部 addAll方法是基于add实现的,
System.out.println(s.getAddCount());
使用复合改良这个例子
/**
* 新类
* 转发:新类中的每个实例方法都可以调用被包含的现有类实例中对应的方法并返回结果
* @author JacXuan
*
* @param <E>
*/
public class ForwardingSet<E> implements Set<E> {
private final Set<E> s;
public ForwardingSet(Set<E> s) {
this.s = s;
}
....
/**
* 复合:不必扩展现有的Set类,而是在此类中加一个私有域,它引用现有类的一个实例
* @author JacXuan
*
* @param <E>
*/
public class InstrumentedSet<E> extends ForwardingSet<E> {
private int addCount =0;
//引用ForwardingSet实例
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(){
return addCount;
}
//将此类用于临时替换一个原本没有技术特性的Set实例
//不给出具体Dog类代码
// static void walk(Set<Dog> dogs){
// InstrumentedSet<Dog> iDogs = new InstrumentedSet<Dog>(capacity);
// }
}
//此包中的包装类可以被用来包装任何set实现,并且可以结合任何先前存在的构造器一起工作
//Set<Date> s = new InstrumentedSet<Date>(new TreeSet<Date>(cmp));
//Set<E> s2 = new InstrumentedSet<E>(new HashSet<E>(capacity));
同样,继承也有使得功能复杂的类传播性更好,那么我们该何时使用继承呢
当子类真正是超类的子类型的时候,可以使用继承
EffectiveJava(16)复合优先于继承的更多相关文章
- EffectiveJava——复合优先于继承
继承时实现代码重用的重要手段,但它并非永远是完成这项工作的最佳工具,不恰当的使用会导致程序变得很脆弱,当然,在同一个程序员的控制下,使用继承会变的非常安全.想到了很有名的一句话,你永远不知道你的用户是 ...
- Java复合优先于继承
复合优于继承 继承打破了封装性(子类依赖父类中特定功能的实现细节) 合理的使用继承的情况: 在包内使用 父类专门为继承为设计,并且有很好的文档说明,存在is-a关系 只有当子类真正是父类的子类型时,才 ...
- 【Effective Java】6、使用复合优先于使用继承
这个,不管是什么书都会这样说,因为常常我们并不需要继承,而只是想把类进行一定的扩展,而我们想扩展的属性或方法对应的类都有,这个时候如果两者是is a的关系,这种关系是确实存在的,那么就可以使用继承,不 ...
- Java - 复合模式优于继承
继承是实现代码重用的方法之一,但使用不当则会导致诸多问题. 继承会破坏封装性,对一个具体类进行跨包访问级别的继承很危险. 即,子类依赖父类的实现细节. 如果父类的实现细节发生变化,子类则可能遭到破坏. ...
- effective-java学习笔记---优先使用泛型方法30
泛型类型比需要在客户端代码中强制转换的类型更安全,更易于使用. 当你设计新的类型时,确保它们可以在没有这种强制转换的情况下使用. 这通常意味着使类型泛型化. 如果你有任何现有的类型,应该是泛型的但实际 ...
- Effecvtive Java Note
代码应该被重用,而不是被拷贝 同大多数学科一样,学习编程的艺术首先要学会基本的规则,然后才能知道什么时候可以打破这些规则 创建和销毁对象 1.考虑用静态工厂方法代替构造器. 优势:有名称.不必再每 ...
- Effective Java-第4章
第4章 类和接口 类和接口是Java程序设计语言的核心,它们也是Java语言的基本抽象单元.Java语言提供了许多强大的基本元素,供程序员用来设计类和接口. 13. 使类和成员的可访问性最小化 要区别 ...
- 读effection java
1.考虑用静态工厂方法代替构造器 public static Boolean valueOf(boolean b){ return b?Boolean.TRUE:Boolean.FALSE; } 静态 ...
- Chapter 02:复合 VS 继承
复合优先于继承,继承是实现代码重用的有力手段,并不是所有情况都适用,使用不当会导致软件变得很脆弱.与方法调用不同的是,继承打破了封装性. 总而言之,组合和继承,都能实现对类的扩展.但是要分具体情况用哪 ...
随机推荐
- js对象和jq对象互相转换
1.DOM 对象转成 jQuery 对象 var v = document.getElementById("v"); //DOM对象 var $v = $(v); //jQuery ...
- 无法安装MVC3,一直卡在vs10-kb2483190
原文发布时间为:2011-05-15 -- 来源于本人的百度文章 [由搬家工具导入] 无法安装MVC3,一直卡在vs10-kb2483190 解决方案: 1、用winrar 解压 MVC3安装文件 2 ...
- glance总结
Openstack将glance独立出来的一个原因是尽可能将镜像存储至多种存储上,由glance提供一个完整的适配框架.现在支持亚马逊对象存储S3.openstack自有的swift对象存储,以及常用 ...
- 第3章 MFC框架程序剖析
参考: https://blog.csdn.net/u014162133/article/details/46573873 1. 2.MFC简介:MFC(Microsoft Foundation Cl ...
- asp.net 网站模板怎么用,就是16aspx上面下下来的模板,里面有个sln文件,其他全是文件夹的东西
.net写的程序模板一般都被写死了.那样只有通过程序改了.
- (转)Ubuntu安装g++-4.8
sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install g++-4.8 ...
- Codeforces Round 480 Div 2 光荣掉分记
痛 痛苦 痛苦啊. 越接近黄名想的越多了啊…… 都说了不要在意rating这破玩意了…… 没出E就算了,策略问题. 居然还FST了: FST个D就算了: FST个A算个**啊. 紧张的时候总会写出一些 ...
- N皇后问题(C++实现和函数式编程实现)
题意 在 N * N 的方格棋盘放置了 N 个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上.求出有多少种合法的放置方法. C++实现(位运算 ...
- spoj 913 Query on a tree II (倍增lca)
Query on a tree II You are given a tree (an undirected acyclic connected graph) with N nodes, and ed ...
- 【strork】HAOI2017旅游记
乘着大巴踏上归程,看着赛后落寞的一些人,赛后轻松的一些人,感触颇多. [爪机被lsj坑了,照片等周末再放...] 4月22: 早上起床不用跑操,到了教室我就看见LSJ跑过来,不用想,果然:“早上nin ...