1. 程式人生 > 其它 >Java入門姿勢【面向物件9】三大特性之一多型性

Java入門姿勢【面向物件9】三大特性之一多型性

多型之向下轉型 將父類的引用變數轉換為子類型別,稱為向下轉型(downcasting)。向下轉型後就可以呼叫子類特有的方法了。 需要進行強制轉換Chinese ch = (Chinese)pro; 強制轉換不是做手術,必須轉換成真實子型別,否則ClassCastException; 向下轉型之前肯定發生了向上轉型 為了避免ClassCastException,向下轉型之前使用instanceof先判斷一下

上次我為大家寫出啦“繼承性”中比較重要的知識點,同時也結束繼承性這一章節的話題,今天吶我們來講解一下另一個知識點“多型性”,多型性是面向物件三大特性之一是Java學習必備的知識。

Java入門姿勢【面向物件8】繼承性-重要的知識點

學習教程推薦:

多型(polymorphism)是面向物件三大特徵之一。同一行為,通過不同的子類,可以體現出來的不同的形態。

多型指的是同一個方法呼叫,由於物件不同可能會有不同的行為。現實生活中,同一個方法,具體實現會完全不同。 比如:同樣是呼叫人的“休息”方法,張三是睡覺,李四是旅遊,王五是聽音樂; 同樣是呼叫人“吃飯”的方法,中國人用筷子吃飯,英國人用刀叉吃飯,印度人用手吃飯。

編譯器型別指的是‘=’左邊的型別,執行期型別指的是‘=’右邊的型別。當有繼承關係時,可能發生編譯期型別和執行期型別不同的情況,即編譯期型別是父類型別,執行期型別是子類型別。即:父類引用指向子類物件

多型的要點:

1. 多型是方法的多型,不是屬性的多型(多型與屬性無關)。

2. 多型的存在要有3個必要條件:繼承,方法重寫,父類引用指向子類物件。

3. 父類引用指向子類物件後,用該父類引用呼叫子類重寫的方法,此時多型就出現了。

編寫程式碼,為多型做準備:

public class Programmer {
    public String name ="proName";//姓名
    //1.子類繼承的
    public void writeCode(){
        System.out.println("writing code............");
    }
    //2.子類重寫的
    public void eat(){
        System.out.println("eating with mouse.............");
    }
}
public class Chinese extends  Programmer{
    public String name = "ChinName";
    //1.從父類繼承一個方法 writeCode()
    //2.重寫父類的一個方法 eat
    public void eat() {
        System.out.println(" Chinese eat rice with chopsticks.....");
    }
    //3.子類特有的方法
    public void playShadowBoxing(){
        System.out.println("Chinese play showdowBoxing every day......");
    }
}
public class English extends Programmer {
    //1.從父類繼承一個方法 writeCode()
    //2.重寫父類的一個方法 eat
    public void eat() {
        System.out.println("English eating meat with knife.....");
    }
    //3.子類特有的方法
    public void raceHorse(){
        System.out.println("English like racing horse......");
    }
}
public class Italian extends  Programmer {
    //1.從父類繼承一個方法 writeCode()
    //2.重寫父類的一個方法 eat
    public void eat() {
        System.out.println("Italian eating pizza with hand......");
    }
    //3.子類特有的方法
    public void playFootBall(){
        System.out.println("Italian like play football.....");
    }
}

實現eat()多型

public class Test {
//    public static  void showEat(Chinese ch){
//        ch.eat();
//    }
//    public static void showEat(Italian it){
//        it.eat();
//    }
//    public static void showEat(English en){
//      en.eat();
//    }
    public static void showEat(Programmer pro){
        pro.eat();
    }
public static void main(String[] args) {
        //Chinese ch = new Chinese();
        Programmer ch = new Chinese();
        showEat(ch);
        English en = new English();
        showEat(en);
        Italian it = new Italian();
        showEat(it);
        Programmer pro = new Programmer();
        showEat(pro);
    }
}
public class Test2 {
    public static void main(String[] args) {
        Chinese ch = new Chinese();
        ch.writeCode();//從父類繼承的
        ch.eat();//重寫父類的
        ch.playShadowBoxing();//子類特有的方法
        Programmer ch2 = new Chinese();
        ch2.writeCode(); //非多型
        ch2.eat(); //  多型  呼叫的是子類重寫的方法
        //ch2.playShadowBoxing(); // 無法呼叫子類特有的方法
    }
}

使用父類做方法的形參,是多型使用最多的場合。即使增加了新的子類,方法也無需改變,符合開閉原則。

父類引用做方法的形參,實參可以是任意的子類物件,可以通過不同的子類物件實現不同的行為方式。另外即使增加了新的子類,方法也無需改變,提高了擴充套件性,符合開閉原則。

多型之向上轉型

將子類物件賦給父類引用,稱為向上轉型(upcasting),自動進行型別轉換。

向上轉型可以呼叫的子類繼承的方法,但不能呼叫子類特有的方法。需要特別理解的是如果子類重寫了父類的方法,向上轉型後通過父類引用呼叫的卻是真實子類重寫的方法,

向上轉型-程式碼示例:

public class TestPoly {
    public static void main(String[] args) {
        //基本資料型別的自動轉換
        int n = 10;
        System.out.println( n );
        double d = n;  // 左>右  自動轉換
        System.out.println(d);
        //引用資料型別的自動轉換
        Programmer programmer = new Chinese(); // 自動轉換  向上轉型  左>右
        programmer.writeCode();
        programmer.eat();
        //programmer.playShadowBoxing();
    }
}

如何理解向上轉型?

1) 招聘程式設計師,來個英國籍程式設計師,滿足要求,不需要特別宣告

2) 不管是哪個國籍的,寫到程式碼都是Java程式碼

3) 中午休息了,大家都去食堂開始吃飯,原形畢露

4) 老闆隨便找一個程式設計師,說一起賽馬吧,不可以;因為對方可能是中國或義大利程式設計師

多型之向下轉型

將父類的引用變數轉換為子類型別,稱為向下轉型(downcasting)。向下轉型後就可以呼叫子類特有的方法了。

  • 需要進行強制轉換Chinese ch = (Chinese)pro;
  • 強制轉換不是做手術,必須轉換成真實子型別,否則ClassCastException;
  • 向下轉型之前肯定發生了向上轉型
  • 為了避免ClassCastException,向下轉型之前使用instanceof先判斷一下

pro instanceof Italian
物件 instanceof 類或者介面

使用instancof的前提:左邊的物件和右邊的型別在繼承樹上有上下級關係

向下轉型-程式碼示例:

public class TestPoly2 {
    public static void main(String[] args) {
        //基本資料型別的強制轉換
        double d = 3.14;
        System.out.println(d);
        int n = (int)d; // 左 < 右  做手術
        System.out.println(n);
        //引用資料型別的強制轉換
        Programmer programmer = new Chinese();
        programmer.eat();//多型
        //programmer.playShadowBoxing();
//        Chinese ch = (Chinese) programmer; // 左<右  不做手術,必須轉換成原來//的真實子型別
//        ch.playShadowBoxing();//
//        English en = (English)programmer;
//        en.raceHorse();
        if(programmer instanceof Chinese){
            Chinese ch = (Chinese) programmer;
            ch.playShadowBoxing();
        }else if(programmer instanceof English){
            English en = (English) programmer;
            en.raceHorse();
        }else{
            Italian it = (Italian) programmer;
            it.playFootBall();
        }
        //java.lang.ClassCastException:
        // com.bjsxt.poly0.Chinese cannot be cast to com.bjsxt.poly0.English
        System.out.println(programmer instanceof Chinese); //false
        System.out.println(programmer instanceof English); //true
        System.out.println(programmer instanceof Programmer);//true
        System.out.println(programmer instanceof Object);//true
        //System.out.println(programmer  instanceof  String);
    }
}

需要注意的點:多型之和方法有關,和屬性無關。入下面示例所示。

多型和屬性無關-程式碼示例

public class TestPoly3 {
    public static void main(String[] args) {
        Chinese chinese  = new Chinese();
        System.out.println(chinese.name);

        Programmer programmer = new Programmer();
        System.out.println(programmer.name);

        Programmer programmer2 = new Chinese();
        System.out.println(programmer2.name); //ChinName  proName
        programmer2.eat();
    }
}

多型實現簡單工廠模式-返回值是父類型別

不僅可以使用父類做方法的形參,還可以使用父類做方法的返回值型別,真實返回的物件可以是該類的任意一個子類物件。

程式碼示例:

public class TestPoly4 {
    public static void main(String[] args) {
        //自己培養了一個程式設計師
        //Programmer pro = new Chinese();
        Programmer pro = SxtSchool.getProgrammer("en");
        //讓程式設計師幹活
        pro.writeCode();
    }
}
class SxtSchool{
        public static Programmer getProgrammer(String type){
            Programmer pro = null;
            if("ch".equals(type)){
                pro = new Chinese();
            }else if("en".equals(type)){
                pro = new English();
            }else{
                pro = new Italian();
            }
            return  pro;
        }
}

以上程式碼其實是簡單工廠模式的實現,它是解決大量物件建立問題的一個解決方案。將建立和使用分開,工廠負責建立,使用者直接呼叫即可。簡單工廠模式的基本要求是

  1. 定義一個static方法,通過類名直接呼叫
  2. 返回值型別是父類型別,返回的可以是其任意子類型別
  3. 傳入一個字串型別的引數,工廠根據引數建立對應的子類產品

感興趣的同學快去試一下去~~

以上就是本章節所講述的全部內容啦,稍後我在更新後續哦,喜歡的夥伴支援一下哦~

感謝觀看~