Java繼承與組合的異同

1、定義

繼承:子類可以獲得父類的public方法,程序使用子類時,將可以直接訪問該子類從父類那裏繼承到的方法。
組合:把舊類的對象作爲新類的成員變量組合進行,用以實現新類的功能,用戶看到的是新類的方法,而不能看到 被組合對象的方法

2、相同點與不同點

相同點:都是實現類複用的重要手段
不同點:繼承可使變量具有多態性、組合則不具備這種多態的靈活性
繼承會破壞父類的封裝性、組合則不會

3、舉例

適合使用繼承的例子:
//使用繼承手段:
class Person{
	private void beat() {
		System.out.println("人的心會跳");
	}
	public void breath() {
		beat(); //人在呼吸的時候心會跳,所以調用beat方法
		System.out.println("人會呼吸");
	}
}
//繼承Person類,直接擁有父類的breath方法,因爲beat方法是private修飾的,因此不可以直接調用beat方法
class Student extends Person{
	public void studying() {
		System.out.println("學生需要學習");
	}
}
//繼承Person類,直接擁有父類的breath方法,因爲beat方法是private修飾的,因此不可以直接調用beat方法
class Teacher extends Person{
	public void teaching() {
		System.out.println("老師會傳授知識");
	}
}
public class t{
	public static void main(String[] args) {
		Student s=new Student();
		s.breath();
		s.studying();
		
		Teacher t=new Teacher();
		t.breath();
		t.teaching();
	}
}

//使用組合手段:
class Person{
	private void beat() {
		System.out.println("人的心會跳");
	}
	public void breath() {
		beat(); //人在呼吸的時候心會跳,所以調用beat方法
		System.out.println("人會呼吸");
	}
}
class Student{
	//將原來父類組合到原來的子類,作爲子類的一個組合成分
	private Person p;  //定義一個Person類的實例p,則該實例p可以訪問Person類中的breath方法
	//定義Student類的構造器
	public Student(Person p) {
		this.p=p;
	}
	//Student類中的breath方法
	public void breath() {
		p.breath();  //訪問到Person類的breath方法
	}
	public void studying() {
		System.out.println("學生需要學習");
	}
}
class Teacher{
	//將原來父類組合到原來的子類,作爲子類的一個組合成分
	private Person p;//定義一個Person類的實例p,則該實例p可以訪問Person類中的breath方法
	//定義Teacher類的構造器
	public Teacher(Person p) {
		this.p=p;
	}
	//Teacher類中的breath方法
	public void breath() {
		p.breath();
	}
	public void teaching() {
		System.out.println("老師會傳授知識");
	}
}
public class t{
	public static void main(String[] args) {
		Person p1=new Person(); //需要顯示創建一個被組合的Person對象
		Student s=new Student(p1);
		s.breath();
		s.studying();
		
		Person p2=new Person();//需要顯示創建一個被組合的Person對象
		Teacher t=new Teacher(p2);
		t.breath();
		t.teaching();
	}
}
/*對於Student和Teacher兩個類來說,他們都會breath,並且這個breath與父類的breath方法完全相同。但是這裏無法直接訪問Person類的breath方法,因此需要在新類中創建一個Person對象,利用該對象來訪問父類的breath方法。*/
輸出結果:
人的心會跳
人會呼吸
學生需要學習
人的心會跳
人會呼吸
老師會傳授知識
適合使用組合的例子:
//採用繼承方式
class School{
	private void Location() {
		System.out.println("學校的地點");
	}
	public void Name() {
		Location(); //不同的學校名字會有不同的地點
		System.out.println("學校的名字");
	}
}
//繼承School類,直接擁有父類的Name方法
class Student extends School{
	public void studying() {
		System.out.println("學生需要學習");
	}
}
//繼承School類,直接擁有父類的Name方法
class Teacher extends School{
	public void teaching() {
		System.out.println("老師會傳授知識");
	}
}
public class t{
	public static void main(String[] args) {
		Student s=new Student();
		s.Name();
		s.studying();
		Teacher t=new Teacher();
		t.Name();
		t.teaching();
	}
}

//採用組合方式
class Student{
	private School sch;
	public Student(School sch) {
		this.sch=sch;
	}
	public void Name() {
		sch.Name();
	}
	public void studying() {
		System.out.println("學生需要學習");
	}
} 
class Teacher{
	private School sch;
	public Teacher(School sch) {
		this.sch=sch;
	}
	public void Name() {
		sch.Name();
	}
	public void teaching() {
		System.out.println("老師會傳授知識");
	}
}
public class t{
	public static void main(String[] args) {
		School sch1=new School();
		Student s=new Student(sch1);
		s.Name();
		s.studying();
		
		School sch2=new School();
		Teacher t=new Teacher(sch2);
		t.Name();
		t.teaching();
	}
}
/*輸出結果:
學校的地點
學校的名字
學生需要學習
學校的地點
學校的名字
老師會傳授知識
*/

4、總結

繼承是一種”是(is-a)“的關係,比如上面的”l老師是人類“、”學生是人類“

組合是一種“有(has-a)”的關係,比如上面的“老師有學校的不同”、“學生有學校的不同”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章