Java 繼承是什麼?語法、流程完整解析,附範例教學一次就搞懂!
Java 繼承是 Java 的重要機制,不論是要建立類別之間的關聯,還是希望提升程式碼的重用性與維護效率,繼承都會是關鍵的基礎工具,對初學者來說,更是理解 Java 設計思維的重要起點。今天這篇文章就將帶你認識 Java 繼承機制,包含如何使用、有哪些注意事項等等,並都附上範例教學,讓你一次就搞懂!
Java 繼承是什麼?為什麼需要繼承?
Java 繼承(Inheritance)是 Java 物件導向程式設計(
OOP)最核心的特性之一,與封裝(Encapsulation)、多型(Polymorphism)並列,構成 Java 的設計基礎。在繼承的架構下,我們能夠為類別建立「父子關係」,藉此達到程式碼重用、結構分層等目的。
Java 繼承的基本概念
要掌握 Java 繼承機制,首先需要掌握兩個重要概念,即一般化、特殊化。
- 一般化(Generalization):把多個類別的共通特徵與行為提取出來,形成一個通用的父類別。
- 特殊化(Specialization):在父類別的基礎上,各自加入子類別的獨特功能。
舉例來說,我們先來建立一個 Animal 類別,用來描述所有動物的共通行為,例如吃飯 eat() 和睡覺 sleep():
class Animal {
void eat() {
System.out.println("This animal is eating");
}
void sleep() {
System.out.println("This animal is sleeping");
}
}
而如果我們想要定義「狗」和「貓」這兩種動物,可以分別建立 Dog 和 Cat 類別,讓它們繼承 Animal,這樣一來,Dog 和 Cat 就會自動擁有 eat() 和 sleep() 這兩個方法,而你也可以在子類別中新增牠們獨有的行為,像是汪汪叫 bark()、喵喵叫 meow()。
class Dog extends Animal {
void bark() {
System.out.println("Woof!");
}
}
class Cat extends Animal {
void meow() {
System.out.println("Meow!");
}
}
這時你可能會好奇,那 Animal 有沒有父類別呢?答案是有的!在
Java 中,每個類別最終都會繼承自一個內建的頂層類別── Object,即使沒有寫 extends Object,Java 編譯器也會自動幫你加上,意味著所有 Java 類別都擁有來自 Object 類別的基本功能。
class Animal {
// 其實背後默默寫了 extends Object
}
Object 提供了一些基本的方法,可以在所有 Java 物件中使用,像是:
- toString():可以把物件轉成字串,常用於印出物件或除錯時查看物件內容。
- equals():用來比較兩個物件內容是否相同。
- hashCode():搭配集合使用,幫物件生成唯一代碼。
這些方法你可以選擇直接使用,或是在自己的類別中覆寫(Override)來自訂行為(下一段會提供實際範例)。換句話說,不管你建立多少個類別,最終都會有一層來自 Java 預設提供的「祖宗級」類別── Object。
Java 繼承的實際用途
了解 Java 繼承的基本概念後,一起看看它的用途有哪些:
- 重複使用程式碼:父類別寫過的方法,子類別都可以直接使用,不需要重複撰寫。
- 維護更容易:更新父類別程式碼時,所有子類別都會自動套用,省去維護的麻煩。
- 建立層級結構:清楚表達物件之間的關係,讓整體架構更具層次性與可讀性。
總結來說,Java 繼承能讓我們在既有程式基礎上擴充功能,不須從零開始寫起,不論是效率、可維護性,或是結構設計上,都能帶來實質幫助。
補充小教室!Java 單向繼承
在 Java 中,每個類別只能有一個直接的父類別,也就是單向繼承(Single Inheritance)。雖然不像
C++ 支援多重繼承(即一個類別可以繼承多個父類別),但這樣的設計反而能避免常見的混淆與衝突問題。
且為了彌補限制,Java 也引入介面(
interface)概念,能在類別中定義可以被多個類別實作(
implement)的方法,達到類似多重繼承的效果,既避免了衝突,也保持程式結構的清晰,更適合初學者入門。
進階小教室!Java 多型
Java 繼承的另一個重要延伸,就是多型(Polymorphism),Java 多型簡單來說,指的是相同的方法名稱,在不同的物件中可以展現出不同的行為,例如當呼叫 animal.makeSound() 時,Dog 類別會輸出「汪汪」,而 Cat 類別則會輸出「喵喵」。
Animal animal1 = new Dog(); // animal1 實際是 Dog 類別
Animal animal2 = new Cat(); // animal2 實際是 Cat 類別
animal1.makeSound(); // 輸出:Woof!
animal2.makeSound(); // 輸出:Meow!
多型可以讓程式碼更加靈活,擴充性也更強,下一段也會為大家詳細示範。
Java 繼承如何操作?語法、流程一次看
講再多不如動手做!建立 Java 繼承關係其實沒有想像中困難,以下一步步帶你練習。
使用 extends 建立繼承關係
在 Java 中,繼承關係是透過 extends 關鍵字來實現的。我們繼續沿用前面的 Animal 範例來說明:
class Animal {
void eat() {
System.out.println("The animal is eating.");
}
}
class Dog extends Animal {
void bark() {
System.out.println("The dog is barking.");
}
}
這裡 Dog 類別繼承了 Animal,所以 Dog 類別除了能呼叫自己的 bark() 方法外,也能直接使用 Animal 的 eat() 方法。接下來看看如何使用這些方法:
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // 繼承自父類別的方法
dog.bark(); // 子類別自有的行為(方法)
}
}
執行後,就會分別輸出:
The animal is eating.
The dog is barking.
使用方法覆寫重新定義父類別
有些情況,子類別需要重新定義父類別的方法,讓行為更符合自己的需求,這時就可以使用方法覆寫(
Override)來達成目的。至於使用方法覆寫時,會需要注意以下幾點規則:
- 一致性:方法名稱、參數型態、回傳值都必須與父類別一致。
- 存取修飾詞:子類別的方法存取修飾詞不能比父類別更嚴格,例如:父類別是 public,子類別也必須是 public,不能是 private。
- 拋出例外:如果父類別的方法有拋出例外(Exception),子類別的覆寫方法只能拋出相同或更少的例外。
下面是簡單範例示範:
class Animal {
void makeSound() {
System.out.println("Some sound");
}
}
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("Meow");
}
}
在這個範例中,Cat 類別覆寫了父類別 Animal 的 makeSound() 方法,當你呼叫 Cat 物件的 makeSound() 時,就會輸出「Meow」,而不是父類別的預設「Some sound」。
使用 super 呼叫父類別成員
有時子類別需要在自己的方法中使用父類別的功能,這時就可以使用 super 關鍵字來呼叫父類別的方法或建構子。
class Animal {
Animal() {
System.out.println("Animal constructor");
}
void makeSound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
Dog() {
super(); // 呼叫父類別建構子
System.out.println("Dog constructor");
}
void makeSound() {
super.makeSound(); // 呼叫父類別的方法
System.out.println("Dog barks");
}
}
在這裡,Dog 類別透過 super() 呼叫了父類別 Animal 的建構子,並在 makeSound() 方法中使用 super.makeSound() 來保留父類別的行為,然後再加入自己的邏輯。
執行這段程式碼時,輸出結果會是:
Animal constructor
Dog constructor
Animal sound
Dog barks
可以看到,先執行了父類別的建構子,再執行子類別的建構子;而在 makeSound() 方法中,先呼叫父類別的行為,再加上自己的行為。
這樣的設計在實際專案非常常見,尤其是需要擴充某些控制元件或框架時,繼承和方法覆寫可以讓你在保留基礎功能的前提下,根據需求加入特定的行為,十分方便、高效。
Java 可以多重繼承嗎?有哪些修飾詞?常見問題解答
Q:Java 可以多重繼承嗎?
不行。Java 不允許一個類別同時繼承兩個父類別,例如以下程式會出錯:
class A {}
class B {}
class C extends A, B {} // ❌ 錯誤
這樣的目的是為了避免當兩個父類別有同名方法時,子類別該選擇哪一個版本就會變得模糊不清。不過 Java 提供了介面(Interface)來解決這個問題。介面可以多重實作,因此一個類別可以同時實作多個介面:
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
class Duck implements Flyable, Swimmable {
public void fly() { System.out.println("Duck flies"); }
public void swim() { System.out.println("Duck swims"); }
}
透過介面,我們可以享有類似多重繼承的彈性,卻不會有衝突的風險。
Q:使用繼承時有哪些修飾詞?
- public:這個類別或方法可以被任何其他類別繼承或存取,幾乎沒有任何限制。
- protected:只有同一個 package 內的類別或子類別可以存取,這讓它比 private 更靈活,但還是有限制的。
- private:這個類別或方法無法直接被繼承或存取,只有在同一類別內可以使用。如果想要外部存取,只能透過公開的方法來間接使用。
- final:若類別被宣告為 final,代表該類別不能再被繼承;若方法被宣告為 final,則表示這個方法不能被覆寫,保證它的行為不會被更改。
Q:Java 是物件導向語言嗎?
是的。Java 是以物件導向為核心設計的語言,透過封裝、繼承、多型這 3 大原則,幫助開發者撰寫結構化、模組化且可重用的程式碼,也是 Java 能長期在企業開發領域中如此重要的原因之一。
想學好 Java?選擇巨匠電腦 Java 課程吧!
魔鬼藏在細節裡!在學習 Java 繼承時,初學者很可能因為不熟悉規則,不小心踩到以下地雷,導致程式編譯失敗或運作異常:
- 常見地雷 1:忘記呼叫父類別建構子。若父類別無預設建構子,子類別必須在建構子第一行使用 super() 明確呼叫。
- 常見地雷 2:覆寫時方法簽名不一致。原意是想覆寫(Override),卻因參數寫錯變成了多載(Overload),建議善用 @Override 檢查。
- 常見地雷 3:嘗試覆寫 private 方法。父類別的 private 方法對子類別不可見,無法被繼承或覆寫。
- 常見地雷 4:存取修飾詞降低可見性。子類別覆寫方法時,其開放權限不能小於父類別(例如:不能將 public 改為 protected)。
學習 Java 不僅僅是掌握語法而已,真正的挑戰在於如何將這些基礎概念應用到真實的專案開發中。繼承、多型、封裝等物件導向的核心觀念,乍聽之下似乎不難,但想要靈活地運用、避開常見雷區,十分講求系統化的指導。
巨匠電腦的
Java 程式開發課程,正是為了解決這些問題而設計,無論你是程式開發的新手、轉職者,還是已有一定基礎的工程師,巨匠電腦都提供了專業的師資和完整的課程規劃,幫助你從基礎到進階慢慢進步,成為 Java 開發高手!
學習 Java 語法固然重要,但更關鍵的是理解「設計思維」,從掌握語法到靈活運用程式設計的精髓,一起跟隨巨匠電腦的課程,打造屬於你的開發實力吧!