你好!在前面的講座中,我們已經多次簡單地遇到繼承的概念。今天我們也會觸及這個話題,但也不會太深入。稍後會有詳細的講座,但今天我們只看實際範例並熟悉 Java 中的一個有趣的運算符。
Java繼承
那麼,繼承到底是什麼呢? 繼承是程式設計(包括 Java)中的一種機制,它允許您基於現有類別來描述新類別。然後,後代類別可以存取父類別的欄位和方法。為什麼這是必要的?舉例來說,假設您需要在程式中創建幾種類型的汽車:卡車、賽車、轎車、皮卡等。即使不開始編寫程式碼,您也可以確定這些類別有很多共同點:所有汽車都有型號名稱、製造年份、引擎尺寸、最高速度等。(更不用說它們都有輪子和其他零件)。在這種情況下,您可以:- 在每個類別中建立這些字段,並在創建時將它們添加到新的汽車類別中
- 將所有機器共有的欄位移到父類別中
Car
,特定類型機器的所有類別都使用extendsCar
一詞繼承。
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() {
//...gas
}
public void brake() {
//...brake
}
}
public class F1Car extends Car {
public void pitStop() {
//...only racing cars make pit stops
}
public static void main(String[] args) {
F1Car formula1Car = new F1Car();
formula1Car.gas();
formula1Car.pitStop();
formula1Car.brake();
}
}
我們已經將所有汽車的通用方法移到了類別中Car
。但在後繼類別中F1Car
,描述了一級方程式賽車 - 進站(緊急維修汽車時的停車),僅在比賽中進行,並透過特定行為進行區分。
Java實例化運算符
要檢查一個物件是否是基於類別創建的,Java中有一個特殊的運算符 -instanceof
。true
如果測試為真,則傳回該值,或false
如果結果為假,則傳回該值。讓我們以我們的汽車類為例看看它是如何運作的:
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
,因此,所有卡車都是基於共同的父級(汽車)創建的。注意運算符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;
}
在將字串與傳遞的物件進行比較之前,該方法會檢查:傳遞的物件實際上是字串嗎?只有那時他才開始比較兩個物體的屬性。如果沒有此檢查,您可以將任何具有值和長度欄位的物件傳遞到該方法中並將其與字串進行比較,這當然是錯誤的。
GO TO FULL VERSION