复用与继承/静态工厂与构造器
来源:互联网 发布:消防接线网络 编辑:程序博客网 时间:2024/05/16 05:57
# 1.复用与继承
面向对象特性之一就是继承,通过继承可以实现代码复用与功能扩展。但是却破坏了另一种特性封装性,这样就很危险了,你底层实现本应封装好,可却被看得一清二楚,随意更改。而复用就很好的解决这个问题,不但如此,继承有的复用都有。通过在类中引用其他类,这样既保障了类的封装性,也保障了类功能扩展。
如:假设有一个程序使用HashSet,为了查看它自创建以来曾经添加过多少个元素,我们可以通过继承扩展HashSet,重写add和addAll方法。
public class InstrumentedHashSet<E> extends HashSet<E> {
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;
}
}
这段代码看上去没什么问题,假如执行下面的程序,我们期望getAddCount返回3,但它实际上返回的是6。
InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
System.out.println(s.getAddCount());
哪里出错了?
在HashSet内部,addAll方法是基于add方法来实现的,即使HashSet的文档中并没有说明这一细节,这也是合理的。因此InstrumentedHashSet中的addAll方法首先把addCount增加了3,然后利用super.addAll()调用HashSet的addAll实现,在该实现中又调用了被InstrumentedHashSet覆盖了的add方法,每个元素调用一次,这三次又分别给addCount增加了1,所以总共增加了6。
因此,使用继承扩展一个类很危险,父类的具体实现很容易影响子类的正确性。而复合优先于继承告诉我们,不用扩展现有的类,而是在新类中增加一个私有域,让它引用现有类的一个实例。这种设计称为复合(Composition)。
# 2.静态工厂与构造器
静态工厂:不同于设计模式中的工厂,这样只是一个生成对象的方法,就是在类中实现一个私有的方法,返回类对象,像单例模式中,单例模式的实现就是通过静态工厂来实现,保障了对象的唯一性。
构造器:每一个类都有一个默认的构造器,如果你需要自定义一个构造器,那就需要进行在构造器参数个数,类型等进行加以区分,构造器名字都是类名。
静态工厂由于构造方法,不只是因为它能保证对象创造的唯一性,与重复使用,也因为它能自定义名字,很好的加以区分,并可以返回实现原返回类型的任何子类型,并在定义申明参数化类对象时很方便。
- 复用与继承/静态工厂与构造器
- 构造器与静态工厂
- 静态工厂方法与构造器
- 静态工厂方法与构造器
- Effective Java(静态工厂与构造器一)
- Effective Java(静态工厂与构造器二)
- 1. 【创建与销毁对象】考虑用静态工厂方法代替构造器
- Java构造器与继承
- 构造器与继承系统
- 用静态工厂方法代替构造器
- 用静态工厂方法代替构造器
- 用静态工厂方法代替构造器
- 用静态工厂方法代替构造器
- Java类继承中的静态块与构造
- 继承与构造函数
- 继承与构造函数
- 构造器与工厂方法的区别
- 继承与静态成员
- 设计模式-10-组合模式
- android studio jni cmake(2)已有项目上增加jni
- 建造者模式
- 《探索性测试》
- Linux 网络编程——并发服务器的三种实现模型
- 复用与继承/静态工厂与构造器
- JavaScript arguments对象
- redis 内存淘汰机制
- oracle---sqlplus搜索结果输出到文件
- 测试用例设计_如何提高测试覆盖率
- struts2 之注解开发(05)
- python的datetime模块
- 2017.07.26工作日记
- 在struts2中配置自定义拦截器放行多个方法