java接口默認方法


原文鏈接:https://liushiming.cn/2020/02/23/java-default-methods/

概述

Java8帶來了一些全新的特性,包括lambda表達式、函數接口、方法引用、流、可選方法、接口中的靜態方法和默認方法。

在本文中,我們將深入討論為什么java8接口新增了默認方法,如何使用默認方法,並討論一些有用的用例。

默認方法

在接口中用default關鍵字定義接口的默認方法。普通接口方法是不能有實現的,默認方法必須有實現:

public interface MyInterface {
     
    // 普通接口方法
     
    default void defaultMethod() {
        // 默認方法
    }
}

為什么需要默認方法

在Java8之前,接口只能有抽象方法。如果不強制所有實現類創建新方法的實現,就不能向現有接口添加新功能。

Java8新增默認方法的原因非常明顯。

在一個典型的基於抽象的設計中,一個接口有一個或多個實現類。接口要新增方法,所有的實現都要新增這個方法的實現。否則就不滿足接口的約束。

默認接口方法是處理此問題的解決方案。在接口添加默認方法不需要修改實現類,接口新增的默認方法在實現類中直接可用。

默認方法的使用

定義MobilePhone接口,其中setTime,getLengthInCm為默認方法

interface MobilePhone {
    /**
     * 獲取手機品牌
     */
    String getBrand();

    /**
     * 獲取手機顏色
     */
    String getColor();

    /**
     * 獲取手機長度(毫米)
     */
    Double getLength();

    /**
     * 設置手機時間
     */
    default String setTime(String newTime) {
        return "time set to " + newTime;
    }

    /**
     * 對getLength方法進行拓展,返回厘米為單位的長度
     */
    default String getLengthInCm() {
        return getLength() / 10 + "cm";
    }
}

默認方法在實現類中可以直接使用

public class DefaultTests implements MobilePhone {
    @Override
    public String getBrand() {
        return "iphone";
    }

    @Override
    public String getColor() {
        return "red";
    }

    @Override
    public Double getLength() {
        return 150.00;
    }

    @Test
    public void defaultTest() {
        System.out.println(setTime("8:00 am"));
        System.out.println(getLengthInCm());
    }
}

結果:

time set to 8:00 am
15.0 cm

如果在某個時候我們往接口添加更多的默認方法,實現類可以不用修改繼續使用

默認方法的最典型用法是逐步為接口提供附加功能,而不破壞實現類。

此外,它們還可以用來為現有的抽象方法提供額外的功能:

interface MobilePhone {
    /**
     * 獲取手機長度(毫米)
     */
    Double getLength();

    /**
     * 對getLength方法進行拓展,返回厘米為單位的長度
     */
    default String getLengthInCm() {
        return getLength() / 10 + "cm";
    }
}

默認方法的多繼承

Apple接口和Samsung接口繼承MobilePhone接口:

interface Apple extends MobilePhone {
    @Override
    default String setTime(String newTime) {
        return "time set to " + newTime + " in apple";
    }
}

interface Samsung extends MobilePhone {
    @Override
    default String setTime(String newTime) {
        return "time set to " + newTime + " in samsung";
    }
}

DefaultTests實現Apple和Samsung接口,必須對setTime方法進行重寫,否則對象將不知道該使用Apple的setTime方法還是Samsung的setTime方法,因為它們同名了

public class DefaultTests implements Apple, Samsung {
    @Override
    public String getBrand() {
        return "iphone";
    }

    @Override
    public String getColor() {
        return "red";
    }

    @Override
    public Double getLength() {
        return 150.00;
    }


    @Override
    public String setTime(String newTime) {
        return Apple.super.setTime(newTime);
    }

    @Test
    public void defaultTest() {
        System.out.println(setTime("8:00 am"));
        System.out.println(getLengthInCm());
    }
}

結果

time set to 8:00 am in apple
15.0 cm

總結

在本文中,我們深入探討了Java8中接口默認方法的使用。乍一看,這個特性可能有點馬虎,特別是純粹從面向對象的角度來看。理想情況下,接口不應該封裝行為,而應該只用於定義特定類型的公共API。

但是在維護現有代碼的向后兼容性時,靜態方法和默認方法是一種很好的折衷。

參考資料

Baeldung - Static and Default Methods in Interfaces in Java


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM