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)”的關係,比如上面的“老師有學校的不同”、“學生有學校的不同”