Thinking in Java(6-2) 繼承與 protected 關鍵字解析

Thinking in Java(6-2) 繼承與 protected 關鍵字解析
Photo by orbtal media / Unsplash

在 Java 程式設計中,繼承(Inheritance)和封裝(Encapsulation)是兩個關鍵概念。本篇文章將深入探討繼承的機制,並詳細解釋 protected 關鍵字的作用。我們還會討論向上轉型(Upcasting)的概念,了解其在物件導向設計中的重要性。

繼承與 protected 關鍵字

在實際的開發中,我們經常希望類別的某些成員對外部世界隱藏,但仍然允許子類別訪問。這正是 protected 關鍵字的用途。

  • protected 的意義:對類別的使用者來說,protected 成員是不可訪問的,類似於 private。但是,對於繼承自該類別的子類別,以及同一個封裝(package)中的其他類別,protected 成員是可訪問的。

雖然可以將欄位聲明為 protected,但最佳實踐是將欄位保持為 private,以維護封裝性。這樣可以保留更改底層實現的權利,而不影響子類別的行為。

以下是一個範例,展示了如何使用 protected 方法:

class Villain {
  private String name;
  protected void set(String nm) { name = nm; }
  public Villain(String name) { this.name = name; }
  public String toString() {
    return "I'm a Villain and my name is " + name;
  }
}	

public class Orc extends Villain {
  private int orcNumber;
  public Orc(String name, int orcNumber) {
    super(name);
    this.orcNumber = orcNumber;
  }
  public void change(String name, int orcNumber) {
    set(name); // Available because it's protected
    this.orcNumber = orcNumber;
  }
  public String toString() {
    return "Orc " + orcNumber + ": " + super.toString();
  }	
  public static void main(String[] args) {
    Orc orc = new Orc("Limburger", 12);
    print(orc);
    orc.change("Bob", 19);
    print(orc);
  }
} /* Output:
Orc 12: I'm a Villain and my name is Limburger
Orc 19: I'm a Villain and my name is Bob
*/

在這個範例中:

  • Villain 類別有一個 protected 方法 set(String nm),子類別 Orc 可以訪問並使用這個方法。
  • Orcchange() 方法使用了 set() 來修改 name,並修改了自己的 orcNumber
  • OrctoString() 方法覆寫了 VillaintoString(),並透過 super.toString() 調用父類別的方法。

這展示了 protected 如何允許子類別訪問父類別的成員,同時仍然對其他類別保持隱藏。

向上轉型(Upcasting)

繼承的核心在於子類別是父類別的一種形式,這使得子類別的物件可以被當作父類別的物件來使用。這種轉換被稱為向上轉型

向上轉型的概念

  • 定義:將子類別的引用賦值給父類別的引用,即把一個更專用的類型轉換為更通用的類型。
  • 安全性:向上轉型是安全的,因為子類別包含了父類別的所有特性和行為。

以下是向上轉型的範例:

class Instrument {
  public void play() {}
  static void tune(Instrument i) {
    // ...
    i.play();
  }
}

// Wind objects are instruments
// because they have the same interface:
public class Wind extends Instrument {
  public static void main(String[] args) {
    Wind flute = new Wind();
    Instrument.tune(flute); // Upcasting
  }
}

在這個範例中:

  • Wind 繼承自 Instrument,因此是一種 Instrument
  • main 方法中,flute 是一個 Wind 物件,但我們將它作為參數傳遞給需要 Instrumenttune() 方法。
  • 編譯器自動將 Wind 型別的引用轉換為 Instrument 型別,這就是向上轉型。

為何稱為向上轉型

在類別繼承的層次結構中,父類別通常被畫在上方,而子類別則在下方。因此,從子類別轉型為父類別,視覺上是向上的,故稱為向上轉型

  • 專用到通用:向上轉型是從更專用的類型轉換為更通用的類型。
  • 方法可用性:向上轉型後,只能使用父類別中定義的方法和屬性,子類別特有的方法將不可用。

向上轉型的意義

  • 多型的基礎:向上轉型是實現多型(Polymorphism)的基礎,允許我們以統一的方式處理不同的子類別。
  • 接口的一致性:透過向上轉型,我們可以使用父類別的接口來操作子類別的物件,提高程式的彈性和可擴充性。

總結

在這篇文章中,我們深入探討了 Java 中繼承與 protected 關鍵字的使用,以及向上轉型的概念。

關鍵要點

  • protected 關鍵字:允許子類別和同一個封裝中的類別訪問,但對其他類別隱藏。
  • 封裝性:盡可能將欄位聲明為 private,使用 protected 方法來提供子類別訪問的能力。
  • 向上轉型:將子類別的引用賦值給父類別的引用,實現多型和接口一致性。
  • 安全性:向上轉型是安全的,但可能會喪失子類別特有的方法。

透過理解這些概念,我們可以編寫出更安全、靈活且可維護的 Java 程式。在設計類別結構時,應該謹慎考慮成員的存取修飾符,並善用繼承與多型的特性來提高程式的品質。