Java 繼承
繼承是java物件導向程式設計技術的一塊基石,因為它允許建立分等級層次的類別。繼承可以理解為一個物件從另一個物件取得屬性的過程。
如果類A是類B的父類,而類B是類C的父類,我們也稱C是A的子類,類C是從類A繼承而來的。在Java中,類別的繼承是單一繼承,也就是說,一個子類別只能擁有一個父類別
繼承中最常使用的兩個關鍵字是extends和implements。
這兩個關鍵字的使用決定了一個物件和另一個物件是否是IS-A(是一個)關係。
透過使用這兩個關鍵字,我們能實作一個物件取得另一個物件的屬性。
所有Java的類別都是由java.lang.Object類別繼承而來的,所以Object是所有類別的祖先類,而除了Object外,所有類別必須有一個父類別。
透過過extends關鍵字可以申明一個類別是繼承另外一個類別而來的,一般形式如下:
// A.java public class A { private int i; protected int j; public void func() { } } // B.java public class B extends A { }
以上的程式碼片段說明,B由A繼承而來的,B是A的子類別。而A是Object的子類,這裡可以不顯示地宣告。
IS-A關係
IS-A就是說:一個物件是另一個物件的一個分類。
下面是使用關鍵字extends實作繼承。
public class Animal{ } public class Mammal extends Animal{ } public class Reptile extends Animal{ } 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,子類別可以繼承父類別所有的方法和屬性,但是無法使用private(私有) 的方法和屬性。
我們透過使用instanceof 運算子,能夠確定Mammal IS-A 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關鍵字使用在類別繼承介面的情況下, 這種情況不能使用關鍵字extends。
實例
public interface Animal {} public class Mammal implements Animal{ } public class Dog extends Mammal{ }
instanceof 關鍵字
可以使用instanceof 運算子來檢驗Mammal和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 關係
HAS-A代表類別和它的成員之間的從屬關係。這有助於程式碼的重複使用和減少程式碼的錯誤。
範例
public class Vehicle{} public class Speed{} public class Van extends Vehicle{ private Speed sp; }
Van類別和Speed類別是HAS-A關係(Van有一個Speed),這樣就不用將Speed類別的全部程式碼貼到Van類別中了,並且Speed類也可以重複利用於多個應用程式。
在物件導向特性中,使用者不必擔心類別的內部如何實作。
Van類別將實現的細節對使用者隱藏起來,因此,使用者只需要知道怎樣呼叫Van類別來完成某一功能,而不必知道Van類別是自己來做還是呼叫其他類別來做這些工作。
Java只支援單繼承,也就是說,一個類別不能繼承多個類別。
下面的做法是不合法的:
public class extends Animal, Mammal{}
Java只支援單繼承(繼承基本類別和抽象類別),但是我們可以用介面來實作(多繼承介面來實作),腳本結構如:
public class Apple extends Fruit implements Fruit1, Fruit2{}
一般我們繼承基本類別和抽象類別用extends關鍵字,實作介面類別的繼承用implements關鍵字。