多態性
1,多態性簡介
多態是面向對象中的三大主要特征,多態性是在繼承性的基礎上擴展出來的,可以實現父子類之間轉換處理。
·多態性的概念
在Java之中對於多態性有兩種實現的模式:
·方法的多態性:
|-①方法的重載:同一個方法名稱可以根據傳入的參數的類型或個數的不同實現不同功能的執行;
1 public void print(){ 2 System.out.println("無參重載方法"); 3 } 4 public void print(String str){ 5 System.out.println(str); 6 }
|-②方法的覆寫:同一個方法可以根據使用的子類的不同有不同的實現;
1 class DatabaseMessage{ 2 public void print(){ 3 System.out.println("Oracle數據庫連接信息...."); 4 } 5 } 6 class NetworkMessage{ 7 public void print(){ 8 System.out.println("網絡連接信息...."); 9 } 10 }
|-③對象的多態性:父子實例之間的轉換處理,它有兩種模式:
·對象向上轉型:父類 父類實例 = 子類實例、自動完成轉換;
·對象向下轉型:子類 子類實例 = (子類)父類實例、強制完成轉換;
從實際的轉型處理來講,大部分情況下考慮最多的一定是對象的向上轉型(90%)、對於對象的向下轉型往往都在使用子類的特殊功能(子類可以對父類進行功能擴充)的時候(3%)。
2,對象向上轉型(接收或返回參數的統一性)
對象轉型的處理屬於多態性,而這一特性必須在繼承性的基礎上實現。
·范例:簡單代碼
1 class Message{ 2 public void print(){ 3 System.out.println("無參重載方法"); 4 } 5 public void print(String str){ 6 System.out.println(str); 7 } 8 } 9 class DatabaseMessage extends Message{ 10 public void print(){ 11 System.out.println("Oracle數據庫連接信息...."); 12 } 13 } 14 public class Main { 15 public static void main(String[] args) { 16 DatabaseMessage msg=new DatabaseMessage();//①方法的覆寫 17 msg.print(); 18 System.out.println("Hello World!"); 19 } 20 }
·范例:觀察向上轉型本程序是一個最簡單的方法覆寫操作實現,整體的程序之中可以發現,由於現在實例化的是子類對象,並且子類對象覆寫了父類中的print()方法,所以調用的是被覆寫過的方法。
1 Message msg=new DatabaseMessage();//向上轉型
·范例:向上轉型的優勢那么這個時候就需要進行思考了,向上轉型這種操作有什么主要的用處呢?
1 class Message{ 2 public void print(){ 3 System.out.println("無參重載方法"); 4 } 5 public void print(String str){ 6 System.out.println(str); 7 } 8 } 9 class DatabaseMessage extends Message{ 10 public void print(){ 11 System.out.println("Oracle數據庫連接信息...."); 12 } 13 } 14 class WebServerMessage extends Message{ 15 public void print(){ 16 System.out.println("WEB服務器連接信息...."); 17 } 18 } 19 public class Main { 20 public static void main(String[] args) { 21 fun(new DatabaseMessage());//Message msg=new DatabaseMessage() 22 fun(new WebServerMessage());//Message msg=new WebServerMessage() 23 } 24 public static void fun(Message msg){//不管現在傳遞的是哪一個子類都可以接收 25 msg.print(); 26 } 27 }
·范例:方法重載向上轉型的主要特點在於,可以對參數進行統一的設計。但是為什么此時不使用重載來解決當前問題呢?
1 public static void fun(DatabaseMessage msg){//不管現在傳遞的是哪一個子類都可以接收 2 msg.print(); 3 } 4 public static void fun(WebServerMessage msg){//不管現在傳遞的是哪一個子類都可以接收 5 msg.print(); 6 }
現在的操作利用了重載解決了當前的設計,的確可以實現與之前完全一樣的效果。但是在進行程序類設計時候,除了滿足當前的要求之外,還需要做出可維護設計,如果說現在隨着項目的發展,Message產生3萬個子類,那么這個時候每當擴充一個Message子類之后就需要追加一個fun()的方法重載,這樣就對我們程序的維護性造成了很大的困難。
3,對象向下轉型
向下轉型的主要特點在於需要使用到一些子類自己特殊的定義處理。
·范例:向下轉型(需要強制轉換)
1 class Person{ 2 public void print(){ 3 System.out.println("一個普通人"); 4 } 5 } 6 class SuperMan extends Person{ 7 public void fly(){ 8 System.out.println("I can fly"); 9 } 10 public void fire(){ 11 System.out.println("I can make fire out"); 12 } 13 } 14 public class Main { 15 public static void main(String[] args) { 16 Person person=new SuperMan();//向上轉型 17 person.print(); 18 SuperMan superMan=(SuperMan) person;//向下轉型,強制轉換 19 superMan.fly(); 20 } 21 }
·范例:觀察錯誤的程序向上描述的是一些公共的特征,而向下描述的是子類自己特殊的定義環境。但是我們需要明確的是,向下轉型並不是一件安全的事情。因為在進行向下轉型之前一定要發生向上轉型。
1 public class Main { 2 public static void main(String[] args) { 3 Person person=new Person();//沒有轉型 4 person.print(); 5 SuperMan man=(SuperMan) person;//SuperMan類與Person類 6 } 7 }
1 Exception in thread "main" java.lang.ClassCastException: class Person cannot be cast to class SuperMan (Person and SuperMan are in unnamed module of loader 'app')
以后只有是發生對象的向下轉型之前一定要先發生向上轉型,兩個沒有任何關系的實例如果要發生強制轉換,那么就會出現【ClassCastException】異常,所以向下轉型並不是一件安全的事情。
·通俗的話兒來講講:
野豬與家豬都是豬(父類),它們都可以向上轉型成豬類。但是如果有一頭豬,那么它的品種你不能確定是(野豬or家豬)——不能向下轉型。但是在已知一頭野豬向上轉型成為豬,那么我們可以確定它也一定是野豬(向下轉型)。
4,instanceo關鍵字
通過分析可以發現向下轉型本身是一件存在有安全隱患的操作,所以為了保證向下轉型的正確性,往往需要在進行轉型之前進行判斷,判斷某個實例是否是某個類的對象,這個就需要通過instanceof實現。
該判斷將返回一個boolean類型,如果true表示實例是指定類對象。
·范例:觀察instanceof的使用
1 public class Main { 2 public static void main(String[] args) { 3 Person person=new Person();//不轉型 4 System.out.println(person instanceof Person);//true 5 System.out.println(person instanceof SuperMan);//false 6 } 7 }
·范例:觀察instanceof關鍵字
1 public class Main { 2 public static void main(String[] args) { 3 Person person=new SuperMan();//向上轉型 4 System.out.println(person instanceof Person);//true 5 System.out.println(person instanceof SuperMan);//true 6 } 7 }
1 public class Main { 2 public static void main(String[] args) { 3 Person person=new SuperMan();//向上轉型 4 if(person instanceof SuperMan){ 5 SuperMan man=(SuperMan) person; 6 man.print(); 7 } 8 } 9 }
在以后進行一些完善性的程序開發的過程之中,對於轉型之前一定要使用instanceof先進行判斷。所以在日后進行項目的開發過程之中,如果要執行對象的向下轉型,最好先判斷一次。
【ClassCastException】異常就是向下轉型出錯的異常。