工厂模式
工厂模式是Java最常用的设计模式之一,它提供了创建对象的最佳方式。
定义
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
作用
将类的实例化延迟到工厂类的子类中完成,即由子类来决定应该实例化哪一个类。
让其子类实现工厂接口,返回的也是一个抽象的产品,因此可以解决接口选择的问题。
应用举例
您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
若不使用工厂方法,调用者为了组装一台汽车还需要实例化其各种零件, 如轮胎、发动机等,但实际上这些零件都与调用者无关。
由此可看出使用工厂模式的好处。
重写与重载
重写(Override)
重写是子类对父类的允许访问的方法的实现过程进行重新编写,方法名、返回值和形参都不能改变。即外壳不变,核心重写!
它发生在子类与父类之间,子类覆盖父类中的原先的方法。
class Fruit{
public void a(){
System.out.println("水果");
}
}
class Apple extends Fruit{
public void a(){
System.out.println("苹果");
}
}
重载(Overload)
重载是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
class Test{
public void a(){
System.out.println("a1");
}
public void a(int b){
System.out.println("a2");
}
}
重载和重写的区别
指标 | 重写 | 重载 |
---|---|---|
参数 | 不能修改 | 必须修改 |
返回类型 | 可改可不改 | 不能修改 |
异常 | 可改可不改 | 可减少或删除,但不能抛出新的异常 |
访问 | 可改可不改 | 只能更弱,不能更强 |
设计不可变的类
- 不要提供mutators方法
- 确保没有方法被重写
- 在所有域前加final
- 在所有域前加private
- 避免表示泄露
- 重新实现equals(),hashCode(), toString()等方法
OOP和ADT中的等价性
不可变类型
站在外部观察者的视角,对两个对象调用任何相同的操作都会得到相同的结果,则认为这两个对象等价——观察等价性
实际上,对于两个immutable类型的变量,只要AF映射到相同的结果,则二者等价。
== 与 .equals()
== 判断的是引用等价性,两个对象只有在完全相同(数值与地址)时才会返回true。
.equals() 判断的是对象等价性,即两对象值相同则返回true。
对于基本数据类型,用 == 判定相等;
对于对象类型,用equals()判定相等。
然而,Object中实现的缺省的equals()是在判断引用等价性,因此一般需要重写。
观察下面两段代码:
Map<String, Integer> a =new HashMap(), b = new HashMap();
a.put("c", 130);
b.put("c", 130);
a.get("c") == b.get("c");
Map<String, Integer> a =new HashMap(), b = new HashMap();
a.put("c", 1);
b.put("c", 1);
a.get("c") == b.get("c");
其中,前一段代码返回的是false,后一段代码返回的是true;
事实上,在-128~127之间的数字,都会返回true,这是因为,Java只用一个空间保存这一数字,而把两者的引用都指向这一空间。