最近,在看java编程思想,觉得这的确是一本难得的好书。目前已经看到了第12章异常,个人觉得本书的最精华部分是讲述了,类的复用,多态以及几种常见的设计模式(这些其实就是面向的对象的编程思想),所以我就把这些看完了的,加上自己的理解,总结出来给大家分享一下。
Java的复用
大概有三种,继承,组合,以及他们的折衷代理。
先说组合,组合我们最常用了:
下面给出一个简单的代码示例:
class WaterSource {
private String s;
WaterSource() {
System.out.println("WaterSource()");
s = "Constructed";
}
public String toString() { return s; }
}
public class SprinklerSystem {
private String valve1, valve2;
private WaterSource source = new WaterSource();
private int i;
private float f;
public String toString() {
return
"valve1 = " + valve1 + " " +
"valve2 = " + valve2 + "\n" +
"i = " + i + " " + "f = " + f + " " +
"source = " + source;
}
public static void main(String[] args) {
SprinklerSystem sprinklers = new SprinklerSystem();
System.out.println(sprinklers);
}
} /* Output:
WaterSource()
valve1 = null valve2 = null
i = 0 f = 0.0 source = Constructed
组合,我就不多讲了,下面来说继承
照样给出继承的示例:
import static net.mindview.util.Print.*;
class Cleanser {
private String s = "Cleanser";
public void append(String a) { s += a; }
public void dilute() { append(" dilute()"); }
public void apply() { append(" apply()"); }
public void scrub() { append(" scrub()"); }
public String toString() { return s; }
public static void main(String[] args) {
Cleanser x = new Cleanser();
x.dilute(); x.apply(); x.scrub();
print(x);
}
}
public class Detergent extends Cleanser {
// Change a method:
public void scrub() {
append(" Detergent.scrub()");
super.scrub(); // Call base-class version
}
// Add methods to the interface:
public void foam() { append(" foam()"); }
// Test the new class:
public static void main(String[] args) {
Detergent x = new Detergent();
x.dilute();
x.apply();
x.scrub();
x.foam();
print(x);
print("Testing base class:");
Cleanser.main(args);
}
} /* Output:
Cleanser dilute() apply() Detergent.scrub() scrub() foam()
Testing base class:
Cleanser dilute() apply() scrub()
继承我也不多讲了
下面来说说代理
代理可说是继承和组合的中庸之道,因为有时想要把把另一个类放在这个类中而且对外提供接口,而运用继承的话,要知道有时候这个类跟另一类不是is-a的关系,而是has-a的关系,所以代理就正好是我们需要的了,只暴露想要暴露的接口。
下面给出代码示例:PS:SpaceShipControls 是被代理的类。
public class SpaceShipDelegation {
private String name;
private SpaceShipControls controls =
new SpaceShipControls();
public SpaceShipDelegation(String name) {
this.name = name;
}
// Delegated methods:
public void back(int velocity) {
controls.back(velocity);
}
public void down(int velocity) {
controls.down(velocity);
}
public void forward(int velocity) {
controls.forward(velocity);
}
public void left(int velocity) {
controls.left(velocity);
}
public void right(int velocity) {
controls.right(velocity);
}
public void turboBoost() {
controls.turboBoost();
}
public void up(int velocity) {
controls.up(velocity);
}
public static void main(String[] args) {
SpaceShipDelegation protector =
new SpaceShipDelegation("NSEA Protector");
protector.forward(100);
}
}
注意,有时我们也把组合和继承一起使用,总之这三种方式要灵活使用。
向上转型:
复用父类的接口并不是继承技术最重要的方面,最重要的是向上转型,这个下一篇将讲述。
最后总结一下:什么时候用继承,什么时候用组合。
组合是将现有的类型作为新类型的底层实现的一部分使用,而继承复用的是接口,还有多态。
在设计系统时,优先选择组合,只有确实需要复用父类接口或向上转型时,才需要使用。