繼承可以定義為一個類獲取另一個類的屬性(方法和欄位)的過程。 通過使用繼承,可以按層次順序管理資訊。
繼承其他類的屬性的類稱為子類(或派生類),被其它繼承其屬性的類稱為超類(或基礎類別,父類別)。
extends
是用於繼承類屬性的關鍵字。 以下是extends
關鍵字的語法。
語法
class Super {
.....
.....
}
class Sub extends Super {
.....
.....
}
範例程式碼
以下是演示Java繼承的範例。 在此範例中,可以觀察兩個類,即Calculation
和MyCalculation
。
使用extends
關鍵字,MyCalculation
繼承Calculation
類的方法:addition()
和Subtraction()
。
將以下程式複製並貼上到名為MyCalculation.java 的檔案中。
// 檔案:MyCalculation.java
class Calculation {
int z;
public void addition(int x, int y) {
z = x + y;
System.out.println("兩個數的和是:" + z);
}
public void Subtraction(int x, int y) {
z = x - y;
System.out.println("兩個數的差是:" + z);
}
}
public class MyCalculation extends Calculation {
public void multiplication(int x, int y) {
z = x * y;
System.out.println("兩個數的乘積是:" + z);
}
public static void main(String args[]) {
int a = 20, b = 10;
MyCalculation demo = new MyCalculation();
demo.addition(a, b);
demo.Subtraction(a, b);
demo.multiplication(a, b);
}
}
執行上面範例程式碼,得到以下結果:
兩個數的和是:30
兩個數的差是:10
兩個數的乘積是:200
在給定的程式中,當建立MyCalculation
類的物件時,會在物件內部建立超類(Calculation
)的內容的副本。就可以使用子類的物件,來存取超類的成員。
超類參照變數可以包含子類物件,但是使用該變數只能存取超類的成員,因此要存取兩個類的成員,建議始終為子類建立參照變數。
如果考慮上面的程式,可以範例化下面給出的類。 但是使用超類參照變數(在本例中為cal
),無法呼叫方法multiplication()
,因為方法multiplication()
屬於子類MyCalculation
的方法。
註 - 子類從超類繼承所有成員(欄位,方法和巢狀類)。建構函式不是成員,因此它們不能被子類繼承的,但是可以從子類呼叫超類別建構函式。
super
關鍵字與this
關鍵字類似,以下是使用super
關鍵字的注意事項。
super
與this
關鍵字用於區分超類的成員和子類的成員。super
關鍵字用於從子類呼叫超類建構函式。區分成員
如果一個類繼承了另一個類的屬性。如果超類的成員具有與子類相同的名稱,要區分這些變數,使用super
關鍵字顯示地存取父類別的屬性,如下所示 -
super.variable; // 存取父類別變數
super.method();// 存取父類別方法
範例程式碼
本節提供了一個演示如何使用super
關鍵字用法的程式。
在給定的程式中有兩個類,即Subclass
和Superclass
,它們都有一個名為display()
的方法,具有不同的實現,以及一個num
變數,具有不同的值。 呼叫兩個類的display()
方法並列印兩個類的變數num
的值。 在這裡,使用super
關鍵字來區分超類和子類的成員。
將程式複製並貼上到名為Subclass.java
的檔案中。
// Subclass.java
class Superclass {
int num = 20;
// 超類方法
public void display() {
System.out.println("這是超類的顯示方法");
}
}
public class Subclass extends Superclass {
int num = 10;
// 子類方法
public void display() {
System.out.println("這是子類的顯示方法");
}
public void my_method() {
// 初始化子類
Subclass sub = new Subclass();
// 呼叫子類的display()方法
sub.display();
// 呼叫父類別的display()方法
super.display();
// 列印子類變數num的值
System.out.println("子類中名為num的變數的值:" + sub.num);
// 列印父類別變數num的值
System.out.println("超類中名為num的變數的值:" + super.num);
}
public static void main(String args[]) {
Subclass obj = new Subclass();
obj.my_method();
}
}
執行上面範例程式碼,得到以下結果:
這是子類的顯示方法
這是超類的顯示方法
子類中名為num的變數的值:10
超類中名為num的變數的值:20
如果一個類繼承另一個類的屬性,則子類自動獲取超類的預設建構函式。 但是如果要呼叫超類的引數化建構函式,則需要使用super
關鍵字,如下所示。
super(parm-values);
範例程式碼
下面給出的程式中演示了如何使用super
關鍵字來呼叫超類的引數化建構函式。 這個程式包含一個超類和一個子類,超類中包含一個接受整數值的引數化建構函式,在子類中使用super
關鍵字來呼叫超類的引數化建構函式。
將以下程式複製並貼上到名為Subclass.java 的檔案中 -
// Subclass.java
class Superclass {
int age;
Superclass(int age) {
this.age = age;
}
public void getAge() {
System.out.println("超類中名為age的變數的值是: " + age);
}
}
public class Subclass extends Superclass {
Subclass(int age) {
super(age);
}
public static void main(String argd[]) {
Subclass s = new Subclass(24);
s.getAge();
}
}
執行上面範例程式碼,得到以下結果:
超類中名為age的變數的值是: 24
IS-A是這樣的一種說法:物件A
是物件B
的一種。下面來看看如何使用extends
關鍵字實現繼承。
public class Animal {
}
// Mammal IS-A Animal
public class Mammal extends Animal {
}
// Reptile物件是(IS-A)物件 Animal 的一種
public class Reptile extends Animal {
}
// Dog物件是(IS-A)物件 Mammal 的一種
public class Dog extends Mammal {
}
基於上面的例子,在物件導向的術語中,以下是真的 -
Animal
)類是哺乳動物(Mammal
)類的超類。Animal
)類是爬行動物(Reptile
)類的超類。Mammal
)類和爬行動物(Reptile
)是Animal
類的子類。Dog
)是哺乳動物(Mammal
)類和動物(Animal
)類的子類。現在,如果使用IS-A關係,可以這樣描述 -
Mammal
IS-A Animal
Reptile
IS-A Animal
Dog
IS-A Mammal
Dog
IS-A Animal
通過使用extends
關鍵字,子類將能夠繼承超類的所有屬性,但超類的私有屬性除外。可以確保Mammal
使用instanceof
運算子來判斷它是Animal
型別。
範例程式碼
class Animal {
}
class Mammal extends Animal {
}
class Reptile extends Animal {
}
public class Dog extends Mammal {
public static void main(String args[]) {
Animal a = new Animal();
Mammal m = new Mammal();
Dog d = new Dog();
System.out.println(m instanceof Animal);
System.out.println(d instanceof Mammal);
System.out.println(d instanceof Animal);
}
}
執行上面範例程式碼,得到以下結果:
true
true
true
通過上面的學習,現在對extends
關鍵字應該有很好的理解了,下面來看看implements
關鍵字如何用於獲取IS-A 關係。
通常,implements
關鍵字與類一起用於繼承介面的屬性。 介面永遠不能被類擴充套件。
範例
public interface Animal {
}
public class Mammal implements Animal {
}
public class Dog extends Mammal {
}
使用instanceof
運算子來檢查確定Mammal
是否是Animal
類的一種,Dog
是否是Animal
類的一種。
範例
interface Animal{}
class Mammal implements Animal{}
public class Dog extends Mammal {
public static void main(String args[]) {
Mammal m = new Mammal();
Dog d = new Dog();
System.out.println(m instanceof Animal);
System.out.println(d instanceof Mammal);
System.out.println(d instanceof Animal);
}
}
執行上面範例程式碼,得到以下結果:
true
true
true
這些關係主要基於用法。 這決定了某某類HAS-A
是否有某種東西。這種關係有助於減少程式碼重複和錯誤。
範例
public class Vehicle{}
public class Speed{}
public class Van extends Vehicle {
private Speed sp;
}
上面範例中Vehicle
類有HAS-A Speed
類。 通過為Speed
提供一個單獨的類,不必將屬於Speed
類的整個程式碼放在Van
類中,這樣就可以在多個應用程式中重用Speed
類。
在物件導向的功能中,使用者無需擔心哪個物件正在進行實際工作。要實現這一點,Van
類隱藏了使用者的實現細節。 因此,基本上發生的事情是使用者會要求Van
類執行某個操作,而Van
類要麼自己完成工作要麼要求另一個類執行操作。
如下所示,有各種各樣型別的繼承。
需要注意:Java不支援多重繼承。 在Java中,一個類不能擴充套件多個類。 因此以下程式碼是非法的 -
// 非法宣告類
public class extends Animal, Mammal{}
但是,一個類可以實現一個或多個介面,這有助於Java實現多重繼承特性。