多態的分類
什么是多態:同一個行為具有多個不同表現形式或形態的能力就是多態。
多態一般分為兩種:
重寫式多態和重載式多態。
重載式多態,也叫編譯時多態。也就是說這種多態再編譯時已經確定好了。重載大家都知道,方法名相同而參數列表不同的一組方法就是重載。在調用這種重載的方法時,通過傳入不同的參數最后得到不同的結果。
重寫式多態,也叫運行時多態。這種多態通過動態綁定(dynamic binding)技術來實現,是指在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。也就是說,只有程序運行起來,你才知道調用的是哪個子類的方法。
這種多態通過函數的重寫以及向上轉型來實現,我們上面代碼中的例子就是一個完整的重寫式多態。
多態的條件
(1)繼承:在多態中必須存在有繼承關系的子類和父類。
(2)重寫:子類對父類中某些方法進行重新定義,在調用這些方法時就會調用子類的方法。
(3)向上轉型:在多態中需要將子類的引用賦給父類對象,只有這樣該引用才能夠具備技能調用父類的方法和子類的方法。
繼承也可以替換為實現接口。
對象的向上轉型
對象的向上轉型:父類 父類對象 = 子類實例
package test1; class Person{ String name="tom"; public void print() { System.out.println("我是人"); } public void car() { System.out.println("勞斯萊斯"); } } class Student extends Person{ String name="tomcat"; public void print() { System.out.println("我是學生"); } public void house() { System.out.println("別墅"); } } public class TestCollection{ public static void main(String[] args) { //向上轉型 父類 父類對象 = 子類實例 /*1.父類有的方法,都可以調用,如果被子類重寫了,則會調用子類的方法。 *2. 父類沒有的方法,而子類存在,則不能調用。 *3.向上轉型只對方法有影響,對屬性沒影響。屬性不存在重寫。*/ Person per = new Student(); Student st=new Student(); per.print(); per.car(); } }
輸出:
為什么要發生向上轉型?
- 減少重復代碼,使代碼變得簡潔。
- 提高系統擴展性。
- 用於參數統一化,假設父類有n個子類,方法要接受子類的實例,如果沒有向上轉型,就需要定義n個方法接收不同的對象。
對象的向下轉型
對象的向下轉型:子類 子類對象 = (子類)父類實例 為什么要發生向下轉型?當父類需要調用子類的擴充方法時,才需要向下轉型。
class Person{ public void print() { System.out.println("我是人"); } } class Student extends Person{ public void print() { System.out.println("我是學生"); } public void fun() { System.out.println("開心的一天!"); } } public class Test{ public static void main(String[] args) { //向上轉型 父類 父類對象 = 子類實例 Person per = new Student(); /** 運用向上轉型后,此時若想訪問子類中的fun方法是不可以的, 所以就有了向下轉型。 */ Student stu = (Student)per; stu.fun(); } } 向下轉型之前一定要進行向上轉型!! 否則在轉型時會出現ClassCastException(類型轉換異常–運行時異常) 問題: 如果向下轉型存在安全隱患,那么如何轉型才靠譜? 先判斷在轉型(依靠instanceof關鍵字實現)引用名 instanceof 類 表示該引用是否能表示該類實例,返回boolean類型。class Person{public void print() { System.out.println("我是人"); } public void p() { System.out.println("傷心的一天"); } } class Student extends Person{ public void print() { System.out.println("我是學生"); } public void fun() { System.out.println("開心的一天!"); } } public class Test{ public static void main(String[] args) { Person per = new Student(); //per是否能表示Person實例 System.out.println(per instanceof Person); //per是否能表示Student實例 System.out.println(per instanceof Student); if(per instanceof Student) { Student stu = (Student)per; stu.fun(); } } } } }
總結
本篇文章的內容大體上就是這些了。我們來總結一下。
- 對象多態性的核心在於方法的覆寫
- 通過對象的向上轉型可以實現接受參數的統一,向下轉型可以實現子類擴充的調用(一般不操作向下轉型,有安全隱患)
- 兩個沒有關系的類對象是不能夠轉型的,一定會產生ClassCastException
- 多態,簡而言之就是同一個行為具有多個不同表現形式或形態的能力。
- 多態的分類:運行時多態和編譯時多態。
- 運行時多態的前提:繼承(實現),重寫,向上轉型與向下轉型。
- 繼承鏈中對象方法的調用的優先級:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。