1. 程式人生 > 其它 >多型性和instanceof關鍵字的使用

多型性和instanceof關鍵字的使用

person類

package com.atguigu.java3; public class Person { String name; int age; int id= 1001; public void eat(){ System.out.println("人吃飯"); } public void walk(){ System.out.println("人走路"); } }

man類

package com.atguigu.java3; public class Man extends Person{ boolean isSmoking; int id = 1002; public void earn(){ System.out.println("男人掙錢養家"); } public void eat(){ System.out.println("男人吃肉"); } public void walk(){ System.out.println("男人霸氣走路"); } }

woman類

package com.atguigu.java3; public class Women extends Man{ boolean isBeauty; public void goShopping(){ System.out.println("女人喜歡購物"); } public void eat(){ System.out.println("女人少吃減肥"); } public void walk(){ System.out.println("女人窈窕的走路"); } }

personTest類

package com.atguigu.java3; public class PersonTest { public static void main(String[] args) { Person p = new Man(); p.eat(); p.walk(); System.out.println(p.id); Man m1 = (Man)p; // Women m2 = (Women)m1; // m2.goShopping(); if(m1 instanceof Women){ Women w1 = (Women)m1; w1.goShopping(); System.out.println("**********Women************"); } if(m1 instanceof Man){ Man m2 = (Man)m1; m2.earn(); System.out.println("**********man************"); } if(m1 instanceof Person){ System.out.println("**********Person************"); } if(m1 instanceof Object){ System.out.println("**********Object************"); } } }

man和woman類都要是person類的子類,然後對person類的方法要進行重寫,這是多型性的條件,然後

Person p = new Man();

new的物件不是person類的而是符合條件的子類的

此時這個物件只能呼叫重寫父類的方法------------->虛擬方法呼叫

而子類特有的方法調不了

輸出的結果是子類重寫方法執行的結果,即編譯看左邊,執行看右邊。

編譯時看左邊父類的哪些方法在子類重寫過,而執行時結果看子類重寫的方法。這個叫做虛擬方法呼叫

多型性的舉例

//多型性的使用舉例一: public class AnimalTest { public static void main(String[] args) { AnimalTest test = new AnimalTest(); test.func(new Dog());//輸出狗的方法 test.func(new Cat());輸出貓的方法 } public void func(Animal animal){//Animal animal = new Dog(); animal.eat(); animal.shout(); if(animal instanceof Dog){ Dog d = (Dog)animal; d.watchDoor(); } } // public void func(Dog dog){ // dog.eat(); // dog.shout(); // } // public void func(Cat cat){ // cat.eat(); // cat.shout(); // } } class Animal{ public void eat(){ System.out.println("動物:進食"); } public void shout(){ System.out.println("動物:叫"); } } class Dog extends Animal{ public void eat(){ System.out.println("狗吃骨頭"); } public void shout(){ System.out.println("汪!汪!汪!"); } public void watchDoor(){ System.out.println("看門"); } } class Cat extends Animal{ public void eat(){ System.out.println("貓吃魚"); } public void shout(){ System.out.println("喵!喵!喵!"); } }

按住Ctrl鍵進入方法體時

p.eat();

p.walk();

進入的是person的eat、walk方法體內,因為是person類體現的多型性,方法就是體現多型性的一個途徑。

明確:子類可以獲取父類的私有屬性和方法,因為像屬性的話,在父類中設定get和set方法,然後就可以呼叫get和set方法修改屬性和呼叫屬性。

將父類的私有方法放在一個公有方法裡面,就可以通過呼叫共有方法來間接呼叫私有方法

這些私有的屬性和方法都是子類物件載入父類來的,即每個子類物件在堆結構中都有父類的屬性和方法,不管是共有的還是私有的,這樣就體現了繼承性

同時,屬性是不能體現多型性的,所以,父類和子類定義了同一個屬性時,呼叫

System.out.println(p.id);

結果是父類的屬性,即1001,

,這時候,就是編譯執行都看左邊了

即子類定義了與父類同名的的屬性,這個屬性不會覆蓋父類的同名屬性,即編譯執行都看左邊

呼叫時不能呼叫子類特有的屬性和方法,但是要明確一點,宣告物件的時候,子類的那些屬性都被載入進來了,只不過因為宣告的person類的型別,導致那些子類特有屬性和方法都被遮蔽了。但是在堆記憶體都有的

如何呼叫P3中特有的方法呢

強制將person型別裝換為man型別,再賦給m1,m1就可以呼叫

man型別的方法和屬性

向下轉型有風險,有可能不成功

instanceof關鍵字的使用

明確:

if(m1 instanceof Person){ System.out.println("**********Person************"); } if(m1 instanceof Object){ System.out.println("**********Object************"); }

返回的是true

m1是person類的子類的例項

向下轉型要想通過,有兩種情況

a instanceof A

a物件是A的例項,即a是A這個類new出來的

a instanceof B

產生a物件的類是B的子類