1. 程式人生 > >第七講 繼承與多態

第七講 繼承與多態

geo main http abs 一個 .com display mon xtend

1.

技術分享

源碼:

class Grandparent {

public Grandparent() {

System.out.println("GrandParent Created.");

}

public Grandparent(String string) {

System.out.println("GrandParent Created.String:" + string);

}

}

class Parent extends Grandparent {

public Parent() {

//super("Hello.Grandparent.");

System.out.println("Parent Created");

// super("Hello.Grandparent.");

}

}

class Child extends Parent {

public Child() {

System.out.println("Child Created");

}

}

public class TestInherits {

public static void main(String args[]) {

Child c = new Child();

}

}

運行結果:

修改之前:

技術分享

修改之後:

技術分享

在java語言的繼承中,在執行子類的構造方法之前,會先調用父類沒有參數的構造方法,其目的是為了要幫助繼承自父類的成員做初始化操作。子類的構造方法通過super()來調用父類特定的構造方法(如果沒有super語句還是會自動調用父類沒有參數的構造方法),調用父類特定的構造方法的super語句必須寫在子類構造方法的第一行,否則編譯時出錯,如果父類只定義了有參數的構造方法,而在子類中又沒有用super關鍵字來調用父類的特定構造方法,則編譯時出錯。

又問:

技術分享

子類是通過父類繼承過來的,所以子類有父類的所有非私有的屬性和方法,如果不調用父類的構造方法,那麽不能初始化父類中定義的屬性,就給父類的屬性分配內存空間 ,如果父類的屬性沒有分配內存空間,那麽子類訪問父類的屬性,就會報錯。

2.

自行編寫代碼測試以下特性(動手動腦):

在子類中,若要調用父類中被覆蓋的方法,可以使用super關鍵字。

(1)覆蓋方法的允許訪問範圍不能小於原方法。

(2)覆蓋方法所拋出的異常不能比原方法更多。

(3)聲明為final方法不允許覆蓋。

例如,Object的getClass()方法不能覆蓋。

(4)不能覆蓋靜態方法。

技術分享

3.

技術分享

技術分享

m=d; //編譯正確,因為子類對象可以直接賦給基類變量。

d=m; //編譯錯誤,基類對象要賦給子類對象變量,必須執行類型轉換(子類對象變量=(子類名)基類對象名;)

d=(Dog)m; //編譯正確,基類對象要賦給子類對象變量,必須執行類型轉換

d=c; //編譯錯誤,不同子類之間不能復制

c=(Cat)m; //m已經轉換成Dog, Dog和Cat子類之間不能轉換

4.

技術分享

(1)運行結果:

技術分享

(2)解釋:

在調用的時候,對象是子類的,就調用子類的方法,對象是父類的,就調用父類的方法。父類對象訪問子類成員,調用相同的函數名的函數屬於子類的;父類的變量進行相關的原算,但是,如果這時父類變量指向子類對象,繼續調用得方法和變量仍然是子類覆蓋後的新的變量和方法的,例如如果將代碼改為:

技術分享

則第三個結果為:101

技術分享

最後一個輸出為父類強轉為子類對象,調用的是子類的變量和方法輸出。

(3)

父類對象可以訪問子類的成員,當然只限於”覆蓋”發生時,調用的時候,對象是子類的,就調用子類的方法,對象是父類的,就調用父類的方法。當然還有如下特性:

1.當子類與父類擁有一樣的方法,並且讓一個父類變量引用一個子類對象時,到底調用哪個方法,由對象自己的“真實”類型所決定,這就是說:對象是子類型的,它就調用子類型的方法,是父類型的,它就調用父類型的方法。這個特性實際上就是面向對象“多態”特性的具體表現。

2.如果子類與父類有相同的字段,則子類中的字段會代替或隱藏父類的字段,子類方法中訪問的是子類中的字段(而不是父類中的字段)。如果子類方法確實想訪問父類中被隱藏的同名字段,可以用super關鍵字來訪問它。

3.如果子類被當作父類使用,則通過子類訪問的字段是父類的.

5.

技術分享

源碼:

class Parent

{

public int value=100;

public void Introduce()
{

System.out.println("I‘m father");

}


}

class Son extends Parent
{

public int value=101;

public void Introduce()
{

System.out.println("I‘m son");

}

}


class Daughter extends Parent
{

public int value=102;
public void Introduce()
{

System.out.println("I‘m daughter");

}

}

public class TestPolymorphism
{


public static void main(String args[])
{

Parent p=new Parent();

p.Introduce();

System.out.println(p.value);

p=new Son();

p.Introduce();

System.out.println(p.value);

p=new Daughter();

p.Introduce();

System.out.println(p.value);


}


}

結果:

技術分享

多態依賴於類型和實現的分離,多用來把接口和實現分離。

6.(多態:多態性(polymorphisn)是允許你將父對象設置成為和一個或更多的他的子對象相等的技術,賦值之後,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作。簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。)

技術分享

運行結果如:

技術分享

雖然猴子和鴿子有數量的變化,定義固定長度的數組使用不方便,長度有限。

技術分享

(接口)固定數組實現

public class Denglu
{
public static void main(String args[])
{
Feeder f = new Feeder("小李");
// 飼養員小李餵養一只獅子
f.eat();
// 飼養員小李餵養十只猴子
for (int i = 0; i < 10; i++)
{
f.eat1();
}
// 飼養員小李餵養5只鴿子
for (int i = 0; i < 5; i++)
{
f.eat3();
}
}
}
interface Lion
{
abstract void eat();
}
interface Monkey
{
abstract void eat1() ;
}
interface Pigeon extends Lion,Monkey
{
abstract void eat3() ;
}

class Feeder implements Pigeon
{
public String name;
public Feeder(String name)
{
this.name = name;
}
public void eat()
{
System.out.println("我不吃肉誰敢吃肉!");
}
public void eat1()
{
System.out.println("我什麽都吃,尤其喜歡香蕉。");
}
public void eat3()
{
System.out.println("我要減肥,所以每天只吃一點大米。");
}
}

運行結果:

技術分享

第七講 繼承與多態