Java - 介面中的預設方法

你好啊,未來的Java巫師們!今天,我們將踏上一段令人興奮的旅程,進入Java的預設方法的世界。如果你是編程新手,不必擔心;我將成為你友善的嚮導,我們將一起逐步探索這個概念。所以,拿起你的虛擬魔杖(或是鍵盤),讓我們一起深入吧!

Java - Default Methods

預設方法 是什麼?

想象你是一個大家族(我們稱之為介面家族)的一部分,你總是有一些每個人都遵守的規則。但突然間,你意識到你需要一條新規則,而且你不想立即強迫所有的家族成員實施它。這就是預設方法來拯救的地方!

在Java的語境中,預設方法允許你在不破壞實現這些介面的類的情況下,向介面添加新的方法。這就像給你的家族添加一條新規則,但是如果你不想自己想出一條遵守的方式,就給每個人一個預設的遵守方式。

語法

以下是聲明預設方法的方式:

public interface MyInterface {
default void myDefaultMethod() {
System.out.println("This is a default method");
}
}

注意方法聲明前的 default 關鍵字。這就像是在說:"嘿,如果你沒有自己的做法,這裡有一個預設的方式給你!"

Java預設方法範例

讓我們來看一個更具体的例子。想象我們正在創建一個簡單的遊戲,不同的角色可以執行動作。

public interface Character {
void move();

default void speak() {
System.out.println("Hello, I'm a character in this game!");
}
}

public class Hero implements Character {
@Override
public void move() {
System.out.println("Hero moves swiftly");
}
}

public class Villain implements Character {
@Override
public void move() {
System.out.println("Villain sneaks around");
}

@Override
public void speak() {
System.out.println("I am the villain! Fear me!");
}
}

public class GameDemo {
public static void main(String[] args) {
Character hero = new Hero();
Character villain = new Villain();

hero.move();    // 輸出:Hero moves swiftly
hero.speak();   // 輸出:Hello, I'm a character in this game!

villain.move(); // 輸出:Villain sneaks around
villain.speak(); // 輸出:I am the villain! Fear me!
}
}

在這個例子中,我們有一個帶有預設 speak() 方法的 Character 介面。Hero 類使用預設實現,而 Villain 類則覆寫它。這就像給角色一條預設的台詞,但允許反派有自己的戲劇化對白!

多重繼承中的預設方法

現在,讓我們來點激烈的。當一個類實現具有相同名稱的預設方法的多个介面時,會發生什麼情況?這就像有兩個家族成員給你關於如何做某件事的不同建議!

public interface Flyer {
default void takeOff() {
System.out.println("Flyer is taking off");
}
}

public interface Spaceship {
default void takeOff() {
System.out.println("Spaceship is launching");
}
}

public class FlyingSpaceship implements Flyer, Spaceship {
// 我們必須覆寫 takeOff 方法以解決衝突
@Override
public void takeOff() {
Flyer.super.takeOff(); // 呼叫 Flyer 的 takeOff 方法
Spaceship.super.takeOff(); // 呼叫 Spaceship 的 takeOff 方法
}
}

public class SpaceDemo {
public static void main(String[] args) {
FlyingSpaceship ship = new FlyingSpaceship();
ship.takeOff();
}
}

在這種情況下,FlyingSpaceship 必須覆寫 takeOff() 方法以解決衝突。這就像成為家族中的外交官,找到一種遵循兩條建議的方法!

Java中的靜態預設方法

抓好你的帽子,因為這裡有一個情節逆轉:Java不允許在介面中使用靜態預設方法!但是別擔心,這背後有一個很好的理由。靜態方法屬於介面本身,而不屬於實現該介面的對象。

不過,Java 8引入了介面中的靜態方法。讓我們看看它們是如何工作的:

public interface MathOperations {
static int add(int a, int b) {
return a + b;
}

default int subtract(int a, int b) {
return a - b;
}
}

public class Calculator implements MathOperations {
// 沒有必要實現靜態方法
}

public class MathDemo {
public static void main(String[] args) {
Calculator calc = new Calculator();

System.out.println("5 + 3 = " + MathOperations.add(5, 3)); // 在介面上調用靜態方法
System.out.println("5 - 3 = " + calc.subtract(5, 3)); // 在對象上調用預設方法
}
}

在這裡,add() 是一個屬於 MathOperations 介面的靜態方法,而 subtract() 是一個可以由任何實現該介面的類使用的預設方法。

結論

現在,我親愛的Java學徒們,我們已經走過了預設方法之地,探索了多重繼承情節,甚至還觸及了介面中的靜態方法。預設方法就像你Java工具箱中的瑞士軍刀 - 幫助你向介面添加新功能,而不會破壞現有的實現。

記住,能力越大,責任越大。明智地使用預設方法來演變你的介面,同時保持向後兼容性。編程愉快,願你的Java冒險無bug且充滿預設方法的魔法!

Credits: Image by storyset