CodeGym /Java Blog /Toto sisi /Java 中的 Instanceof 和繼承
John Squirrels
等級 41
San Francisco

Java 中的 Instanceof 和繼承

在 Toto sisi 群組發布
你好!在前面的課程中,我們已經簡要地熟悉了繼承的概念。今天,我們將再次討論這個話題,但不會太深入。以後我們還會有更詳細的教訓。今天,我們將快速瀏覽幾個實際示例,並熟悉 Java 中一個有趣的運算符。

遺產

那麼,什麼是繼承? instanceof 和繼承 101 - 1 繼承是一種編程機制(包括在 Java 中),它允許您在現有類的基礎上聲明一個新類。然後派生類可以訪問父類的字段和方法。我們為什麼需要這個?好吧,假設您需要在一個程序中創建多個汽車類:Truck、RaceCar、Sedan、Pickup 等。甚至在編寫任何代碼之前,您就可以肯定地知道所有這些類有很多共同點:所有汽車都有一個模型名稱、製造年份、發動機尺寸、最大速度等(更不用說它們都有共同的車輪和其他部件)。在這種情況下,您可以:
  • 在每個類中創建這些字段(在創建時將它們添加到每個新汽車類中)
  • 將所有汽車共有的字段放入一個Car父類中,然後使用關鍵字extends從該類中派生出特定類型汽車的所有類Car
當然,第二種選擇更方便:

public class Car {

   private String model;
   private int maxSpeed;
   private int yearOfManufacture;

   public Car(String model, int maxSpeed, int yearOfManufacture) {
       this.model = model;
       this.maxSpeed = maxSpeed;
       this.yearOfManufacture = yearOfManufacture;
   }
}

public class Truck extends Car {

   public Truck(String model, int maxSpeed, int yearOfManufacture) {
       super(model, maxSpeed, yearOfManufacture);
   }
}

public class Sedan extends Car {
   public Sedan(String model, int maxSpeed, int yearOfManufacture) {
       super(model, maxSpeed, yearOfManufacture);
   }
}
至少,我們避免了不必要的代碼重複(我們在編寫程序時應該始終努力做到這一點)。另外,我們有一個簡單易懂的類結構,所有汽車共有的所有字段都合併到一個類中。如果卡車有任何其他汽車沒有的特殊字段,可以在Truck類中聲明。方法也是如此。所有的汽車都有一些共同的行為,可以用方法來描述,例如啟動汽車,加速/剎車等。這些共同的方法可以合併到父類中,每個特定類型的Car汽車都可以在其派生類中定義其獨特的行為.

public class Car {

   public void gas() {
       // Accelerate
   }

   public void brake() {
       // Brake
   }
}


public class F1Car extends Car {

   public void pitStop() {
      
       // Only race cars make pit stops
   }

   public static void main(String[] args) {
      
       F1Car formula1Car = new F1Car();
       formula1Car.gas();
       formula1Car.pitStop();
       formula1Car.brake();
   }
}
我們將所有汽車通用的方法添加到類中Car。但是,看看F1Car代表“一級方程式”賽車的級別。進站(因緊急汽車維修而停止)僅在比賽中進行,因此我們將此特定功能添加到相關的派生類中。 instanceof 和繼承 101 - 2

instanceof 運算符

在 Java 中,有一個特殊的運算符instanceof用於檢查對像是否是基於特定類創建的。它根據檢查結果返回truefalse 。讓我們使用汽車示例中的類看看它是如何工作的:

public class Truck extends Car {

   public static void main(String[] args) {

       Truck truck = new Truck();
       System.out.println(truck instanceof Car);
   }
}
輸出: true 運算instanceof符返回true,因為我們有一個Truck對象,所有卡車都是汽車。類Truck派生自Car類。所有卡車都是基於共同的父類創建的Car。仔細查看instanceof運算符的使用方式。你寫的時候沒有句點,因為它是一個運算符,而不是一個方法(“object instanceof Class”)。讓我們嘗試另一種方式:

public static void main(String[] args) {

   Car car = new Car();
   System.out.println(car instanceof Truck);
}
輸出: false 該類Car(和汽車對象)不是從該類派生的Truck。所有卡車都是汽車,但並非所有汽車都是卡車。Car對像不基於Truck類。再舉一個例子:

public static void main(String[] args) {

   Car car = new Car();
   Truck truck = new Truck();
   System.out.println(car instanceof Object && truck instanceof Object);
}
輸出: True 這裡的邏輯也很簡單:Java 中的所有類,包括您創建的類,都是該類的後代Object(即使您沒有寫“extends Object”——它已經暗示了)。這將如何以及何時有用?instanceof重寫方法時最常使用運算符equals()。例如,下面是該equals方法在類中的實現方式String

public boolean equals(Object anObject) {
   if (this == anObject) {
       return true;
   }
   if (anObject instanceof String) {
       String anotherString = (String) anObject;
       int n = value.length;
       if (n == anotherString.value.length) {
           char v1[] = value;
           char v2[] = anotherString.value;
           int i = 0;
           while (n-- != 0) {
               if (v1[i] != v2[i])
                       return false;
               i++;
           }
           return true;
       }
   }
   return false;
}
在將 aString與傳遞的對象進行比較之前,該方法會測試對像是否為字符串?只有這樣它才開始比較兩個對象的屬性。如果此測試不存在,則可以將任何具有長度字段的對像傳遞給該方法並與 String 進行比較,這當然是錯誤的。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION