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的子類,這裡可以不顯示地宣告。


作為子類,B的實例擁有A所有的成員變量,但對於private的成員變數B卻沒有存取權限,這保障了A的封裝性。



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關鍵字。