Java中继承与组合的区别

组合和继承,是拿到一个问题,设计相应的Java类的时候,不得不面对的来自灵魂的拷问。

“XX到底是YY的一种,还是只是组合了YY?”,”手机到底是手电筒的一种,还是组合了一个可以当手电的闪光灯?”

is-a与has-a关系

is-a( 是 “a” 小明是人类)表示的是属于得关系。比如兔子属于一种动物(继承关系)。

has-a( 有 “a” 汽车有轮胎) 表示组合,包含关系。比如兔子包含有腿,头等组件;就不能说兔子腿是属于一种兔子(不能说是继承关系)

继承与组合的区别

继承,其实表达的是一种”is-a”的关系,也就是说,在你用类构造的世界中,”子类是父类的一种特殊类别”。

组合,在类中创建另一个类的对象,来进行各种操作。

继承不是组合,继承也不只是为了能简单的拿来父类的属性和方法。如果仅仅如此,原封不动的拿来主义,组合也能做到。

继承也不是通过组合的方式来实现的。和组合相比,继承更像是”融合”

所谓融合,即合二为一,可以互相影响。父类影响子类没问题,子类怎么影响父类呢?如何限制手机一次只能最多买五个?

我们为什么需要使用继承?

如果使用组合,对于作为属性的类对象,我们无法修改其方法。有时候是因为没有权限,有时候是因为我们的习惯:我们不该为了一个类去修改作为其属性的另一个类的方法。对于组合这种方式,我们只有使用的权限,而没有修改的权限。也就是说组合很难做到上面提到的限制手机买5个。

而对于继承,因为有覆写的存在,因此,虽然某个方法属于父类,但如果子类想要拥有区别于父类的属于自己的独特的方法,那么可以使用覆写机制所以,对于继承这种方式,我们不仅可以使用,还可以修改。

继承之于组合特殊的一点在于,它能够进行覆写,对继承自父类的方法不满足就可以修改。而在Java中,组合是没有覆盖的,覆盖只在继承中存在。

即组合,我们从其他类简单地拿来了属性和方法;而继承,我们不仅仅从其他类拿来了属性和方法,我们还可以修改拿来的方法。

组合让两个类相对保持自己的独立性,而继承则让两个类相互渗透,因为继承更确切地说是子类和父类的融合。
类存在的目的是封装,而继承在某种程度上破坏了这种封装,让两个类紧紧耦合在了一起。

覆盖(重写)的实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package test;

class Father{
public void fun1(){
System.out.println("Father -- > fun1()");
}

public void fun2(){
this.fun1();
}
}

class Son extends Father {
public void fun1(){
System.out.println("Son -- > fun1()");
}

public void fun3(){
System.out.println("Son -- > fun3()");
}
}

public class override_test_1 {
public static void main(String[] args){
Father fa = new Son();
Son son = (Son) fa;// 左边的引用决定能调用哪些方法,右边new的对象决定具体执行哪个方法
son.fun1();// Son -- > fun1()
son.fun2();// Son -- > fun1()
son.fun3();// Son -- > fun3()
}
}
// 并不是强制类型转换的一个例子
public static void main(String[] args){
Father fa = new Father();
Son son = (Son) fa; // 不能转换,不是多态,会报错
son.fun1();
son.fun2();
son.fun3();
}
坚持原创技术分享,您的支持将鼓励我继续创作!