所谓组合,就是在创建新类中复用现有的代码,而新的类是由现有类的对象所组成的,所以称之为组合!
所谓继承,它是按照现有类的类型来创建新类,无须改变现有类的形式,采用现有类的形式并在其中添加新的代码!它也是代码的复用。
网上有句话,“所谓继承,就是让父亲来帮我干活儿,而组合是找了个老头来帮我干活儿!”
网络上有很多组合的例子有用到接口,我觉得《Java编程思想》上面的示例更纯粹一些。
class Soap{
private String s;
Soap(){
System.out.println("Soap()");
s = "Constructed";
}
public String toString(){
return s;
}
}
public class Bath {
private String s1 = "Hello",
s2 = "World",
s3,s4;
private Soap castille;
private int i;
private float toy;
public Bath(){
System.out.println("Inside Bath()");
s3 = "toy";
toy = 3.14f;
castille = new Soap();
}
{i = 47;}
public String toString(){
if(s4 == null)
s4 = "Joy";
return "s1 = " + s1 + "\n" +
"s2 = " + s2 + "\n" +
"s3 = " + s3 + "\n" +
"s4 = " + s4 + "\n" +
"i = " + i + "\n" +
"toy = " + toy + "\n" +
"castille = " + castille ;
}
public static void main(String[] args){
Bath b = new Bath();
System.out.println("*********************");
System.out.print(b);
}
运行结果如下:
Inside Bath()
Soap()
*********************
s1 = Hello
s2 = World
s3 = toy
s4 = Joy
i = 47
toy = 3.14
castille = Constructed
继承的基本语法如下:
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();
System.out.println(x);
}
}
public class Detergent extends Cleanser{
public void scrub(){
append("Detergent.scrub() ");
super.scrub();
}
public void foam(){append(" foam");}
public static void main(String[] args){
Detergent x = new Detergent();
x.dilute();
x.apply();
x.scrub();
x.foam();
System.out.println("Testing base class:");
System.out.println(x);
Cleanser.main(args);
}
}
运行结果:
Testing base class:
Cleanser dilute() apply() Detergent.scrub() scrub() foam
Cleanser dilute() apply() scrub()
这个代码中有两个main方法,我在运行的时候是选择Detergent来运行的,这也就是说在同一个Java文件中,我们是可以有两个main方法的,但是一个类中只能有一个,这种写法可方便调试,每个类可以单独测试!
为了继承,一般规则是将所有的数据成员都指定为private,将所有的方法指定为public。
在继承和组合的使用上,我们的准则是“组合优于继承”。
下面从两者的区别来说明为什么要像上面准则那样做?
1、组合(has-a)与继承(is-a)都允许在新的类中放置子对象,组合是显示的这样做,继承是隐式的那样做。
2、继承的子类与父类之间的联系比较紧密,子类依赖于父类的实现,有时候父类的修改会给子类造成影响,破坏封装,而组合相对彼此独立。
3、继承不支持动态继承,所有的一切都是在编译期就完成了,而组合在运行期,整体对象可以选择不同类型的局部对象。
4、继承也支持拓展,但是相对于组合来说,会复杂很多。
5、继承能自动继承父类的接口,但是组合不能自动获取和局部类同样的接口。
6、继承在创建子类对象的时候,不需要创建父类的对象,而组合在创建整体类的对象时,需要创建所有局部类的对象。