Java OOP 中的多型性

多型性是一種 OOP 概念,其中一個名稱可以有多種形式。

例如,你用智慧手機進行通訊。你選擇的通訊模式可以是任何內容,它可以是通話、簡訊、圖片資訊、郵件等。因此,目標通常是溝通,但他們的方法是不同的。這稱為多型性。

在本教程中,你將學習 -

  • 什麼是多型?
  • OOP 中的 Java 多型與示例
  • 方法覆蓋
  • 過載和覆蓋之間的區別
  • 什麼是動態多型?
  • super 關鍵字
  • 靜態和動態多型性之間的差異

Java 多型與示例

我們有一個父類,Account,具有存款和取款功能。帳戶有 2 個子類

存款和取款操作與儲存和檢查帳戶相同。因此,Account 類中的繼承方法將起作用。

![Java 繼承與多型](/img/Java Inherit Account Example.jpg)

軟體要求的變更

軟體需求發生了變化,這在軟體行業中是非常普遍。你需要新增有透支功能的特權銀行賬戶。

因此,重新實現特權需求的取款方法。但是,你不需要在 SavingChecking 帳戶中更改測試過的程式碼。這是 OOP 的優勢。

步驟 1: 這樣當呼叫 Saving 帳戶的 withdraw 方法時,執行來自父帳戶類的方法。

步驟 2: 但是當特權帳戶的 withdraw 方法被呼叫時,執行特權類中定義的 withdraw 方法。這是多型性。

方法重寫

方法重寫是在子類中重新定義超類方法。

方法重寫規則

  • 方法簽名,即方法名稱、引數列表和返回型別必須完全匹配。
  • 重寫的方法可以擴充套件可訪問性但不會縮小它,即如果它在基類中是私有的,則子類可以使其公開但反之亦然。

例子

class Doctor{
    public void treatPatient(){
        //treatPatient method
}
    
class Surgeon extends Doctor{
    public void treatPatient(){
        //treatPatient method
    }
}
    
Class run{
    public static void main (String args[]){
        Doctor doctorObj = new Doctor();
        //treatPatient method in class Doctor will be executed
        doctorObj.treatPatient();

        Surgeon surgeonObj = new Surgeon();
        //treatPatient  method in class Surgeon  will be executed
        surgeonObj.treatPatient();
    }
}

過載和重寫之間的區別

  • **方法過載:**方法過載在同一個類中,其中多個方法具有相同的名稱但簽名不同。 舉例,

    void sum (int a , int b);
    void sum (int a , int b, int c);
    void sum (float a, double b);
    
  • **方法重寫:**方法重寫是在子類中重新定義超類中的一個方法時。在這種情況下,方法的簽名保持不變。

    class X{
        public int sum(){
            // some code
        }
    }
    
    class Y extends X{
        public int sum(){
            //overridden method
            //signature is same
        }
    }
    

什麼是動態多型?

動態多型性是一種機制,通過該機制可以在超類和子類中使用相同的名稱和簽名定義多個方法。在執行時解析對重寫方法的呼叫。

動態多型性示例:

超類的引用變數可以引用子類物件

 Doctor obj = new Surgeon();

比如下面這個語句,

obj.treatPatient();

這裡引用變數 obj 是父類,但它指向的物件是子類。

obj.treatPatient() 將執行子類的 treatPatient() 方法 - Surgeon。

如果使用基類引用來呼叫方法,則要呼叫的方法由 JVM 決定,具體取決於引用指向的物件。

例如,即使 obj 是對 Doctor 的引用,它也會呼叫 Surgeon 的方法,因為它指向 Surgeon 物件

這是在執行期間決定的,因此被稱為動態執行時多型性

super 關鍵字

如果 Surgeon 類中的 treatPatient 方法想要執行 Doctor 類中定義的功能然後執行其自己的特定功能,該怎麼辦?

在這種情況下,關鍵字 super 可用於從子類訪問父類的方法。

Surgeon 類中的 treatPatient 方法可以寫成:

treatPatient(){
    super.treatPatient();
    //add code specific to Surgeon
}

關鍵字 super 可用於訪問子類中超類的任何資料成員或方法。 示例: 學習繼承、多型和超級關鍵字

步驟 1: 將以下程式碼複製到編輯器中

public class Test{
     public static void main(String args[]){
        X x= new X();
       Y y = new  Y();
       y.m2();
      //x.m1();
      //y.m1();
     //x = y;//parent pointing to object of child
     //x.m1() ;
     //y.a=10;
   }
}
class X{
   private int a;
   int b;
      public void m1(){
       System.out.println("This is method m1 of class X");
     }
}
class Y extends X{
      int c; //new instance variable of class Y
         public void m1(){
            //overriden method
            System.out.println("This is method m1 of class Y");
        }
       public void m2(){
           super.m1();
           System.out.println("This is method m2 of class Y");
      }
}

步驟 2: 儲存,編譯和執行程式碼。觀察輸出。

步驟 3: 取消註釋行#6-9。儲存,編譯和執行程式碼。觀察輸出。

步驟 4: 取消註釋行#10。儲存並編譯程式碼。

步驟 5: 錯誤出現的原因這是因為子類無法訪問超類的私有成員。

靜態和動態多型性之間的差異

靜態多型性 動態多型性
它涉及方法過載。 它涉及方法覆蓋。
錯誤(如果有)在編譯時解決。由於程式碼在編譯期間未執行,因此名稱為 static。 如果引用變數正在呼叫重寫方法,則要呼叫的方法由物件確定,你的引用變數指向該方法。這只能在執行時確定正在執行的程式碼時,因此名稱為 dynamic。

舉例

  • 靜態多型性:

    void sum (int a , int b);
    void sum (float a, double b);
    int sum (int a, int b); //compiler gives error.
    
  • 動態多型性:

    //reference of parent pointing to child object
    Doctor obj = new Surgeon();
    // method of child called
    obj.treatPatient();