目錄
一. 引入預設介面方法的背景
二. 預設介面方法的定義
三.衝突及其解決方法
首頁 Java java教程 Java8 新特性之預設介面方法

Java8 新特性之預設介面方法

Feb 23, 2017 am 10:25 AM
java8 新特性

摘要: 從java8開始,介面不只是一個只能宣告方法的地方,我們還可以在宣告方法時,給方法一個預設的實現,我們稱之為預設介面方法,這樣所有實作該介面的子類別都可以持有該方法的預設實作。

一. 引入預設介面方法的背景

java8可以看做是java版本更新迭代過程中變化最大的一個版本(與時俱進,方能不滅,我們應該感到欣慰),但是經過這麼多年的發展和迭代,java的源碼儼然已是一個龐然大物,要在這樣龐大的體積上大動幹戈,肯定不易。所以當我第一次看到java8的預設介面方法的時候,我第一感覺就是這是java的設計人員在填自己之前挖的坑。

從前幾篇的講解中我們知道java8在現有的介面上加入了許多方法,例如List的

sort(Comparator<? super E> c)
登入後複製

方法。如果按照java8之前介面的設計思路,​​當給一個介面添加方法聲明的時候,實作該介面的類別都必須為該新添加的方法添加對應的實作。考慮相容性,這樣是不可取的,所以說這是一個坑,而新的特性又要求不得不為介面添加一些新的方法,為了兼得魚和熊掌,java8的設計人員提出了預設介面方法的概念。

這樣說來,預設介面方法似乎是為api的設計人員而開發的,離我們普通開發人員還有些距離,這樣想有點圖森破啦,雖然我們不用去設計jdk,但是我們在日常的開發過程中還是會有提供api給別的業務方呼叫的需求,當我們在更新我們api的時候,就可以採用預設方法來提供更高階的功能,同時保持相容性。

二. 預設介面方法的定義

預設介面方法的定義很簡單,只要在介面的方法定義前面加上一個

default
登入後複製

關鍵字即可,如下:

public interface A {
    /**
     * 默认方法定义
     */
    default void method() {
        System.out.println("This is a default method!");
    }
}
登入後複製

當我們這樣定義一個預設方法之後,所有實作該介面的子類別都間接持有了該方法。或者你會跟我一樣覺得介面和抽象類別越來越像了,確實,不過它們之間還是有如下差別:

1. 一個類別只能繼承一個類,但是可以實作多個介面

2. 抽象類別可以定義變量,而接口卻不能
抽象除了解決了我們上面提及到的問題,還具有如下好處:

1. 對於一些不是每個子類別都需要的方法,我們給它一個預設實現,從而避免我們在子類別中對其無意義的實現(一般我們都會throw new UnsupportedException())

2. 預設方法為java的多重繼承提供了新的途徑(雖然我們只能繼承一個類,但是我們可以實作多個介面啊,現在介面也可以定義預設方法了)

三.衝突及其解決方法

因為一個類別可以實現多個接口,所以當一個類別實作了多個接口,而這些接口中存在兩個或兩個以上方法簽名相同的預設方法時就會產生衝突,java8定義如下三個原則來解決衝突:

1. 類別或父類別中明確宣告的方法,其優先權高於所有的預設方法

2. 如果1規則失效,則選擇與當前類別距離最近的具有具體實現的預設方法

3. 如果2規則也失效,則需要明確指定介面
下面透過幾個例子加以說明:

#例1

public interface A {
    /**
     * 默认方法定义
     */
    default void method() {
        System.out.println("A&#39;s default method!");
    }
}
public interface B extends A {
    /**
     * 默认方法定义
     */
    default void method() {
        System.out.println("B&#39;s default method!");
    }
}
public class C implements A, B {
    public static void main(String[] args) {
        new C().method();
    }
}
// 输出:B&#39;s default method!
登入後複製

此處因為介面B相對於A距離C更近,同時B的method是一個具體的預設實現,依據規則2,所以此處實際上呼叫的是介面B的預設方法

例2

public class D implements A {
}
public class C extends D implements A, B {
    public static void main(String[] args) {
        new C().method();
    }
}
// 输出:B&#39;s default method!
登入後複製

例2在原有介面A、B的基礎上,新增了一個實作介面A的類別D,然後類別C繼承於D,並實現A和B,此處雖然C離D更近,但因為D的具體實現在A中,所以B中的默認方法還是距離最近的默認實現,依據規則2,此處實際上調用的是B的預設方法。

範例3

// A接口不变
public interface B {
    /**
     * 默认方法定义
     */
    default void method() {
        System.out.println("B&#39;s default method!");
    }
}
public class C implements A, B {
    @Override
    public void method() {
        // 必须显式指定
        B.super.method();
    }
    public static void main(String[] args) {
        new C().method();
    }
}
登入後複製

例3中介面B不再繼承自介面A,所以此時C中呼叫預設方法

method()
登入後複製

距離接口A和B的具體實作距離相同,編譯器無法確定,所以報錯,此時需要明確指定:

B.super.method()
登入後複製

 以上就是Java8 新功能預設介面方法 的內容,更多相關內容請關注PHP中文網(www.php.cn)!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1675
14
CakePHP 教程
1429
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
Java 8中如何計算一年前或一年後的日期? Java 8中如何計算一年前或一年後的日期? Apr 26, 2023 am 09:22 AM

Java8計算一年前或一年後的日期利用minus()方法計算一年前的日期packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[]args ){LocalDatetoday=LocalDate.now();LocalDatepreviousYear=today.minus(1,ChronoUni

PHP 8.3發布:新功能一覽 PHP 8.3發布:新功能一覽 Nov 27, 2023 pm 12:52 PM

PHP8.3發布:新功能一覽隨著技術的不斷發展和需求的不斷變化,程式語言也不斷更新和改進。作為一種廣泛應用於網頁開發的腳本語言,PHP一直在不斷進步,為開發者提供更強大和高效的工具。最近發布的PHP8.3版本帶來了許多期待已久的新功能和改進,以下讓我們來看看這些新特性的一覽。非空屬性的初始化在過去的PHP版本中,如果一個類別的屬性沒有明確賦值,它的值

學習PHP8的新特性,深入理解最新技術的指南 學習PHP8的新特性,深入理解最新技術的指南 Dec 23, 2023 pm 01:16 PM

深入解析PHP8的新特性,幫助您掌握最新技術隨著時間的推移,PHP程式語言一直在不斷演進和改進。最近發布的PHP8版本為開發者提供了許多令人興奮的新功能和改進,為我們的開發工作帶來了更多便利和效率。在本文中,我們將深入解析PHP8的新特性,並提供具體的程式碼範例,旨在幫助您更好地掌握這些最新的技術。 JIT編譯器PHP8引進了JIT(Just-In-Time)編

如何使用Java 8計算一週後的日期? 如何使用Java 8計算一週後的日期? Apr 21, 2023 pm 11:01 PM

Java8如何計算一週後的日期這個例子會計算一週後的日期。 LocalDate日期不包含時間訊息,它的plus()方法用來增加天、週、月,ChronoUnit類別宣告了這些時間單位。由於LocalDate也是不變型,回傳後一定要用變數賦值。 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[

php8有什麼新特性 php8有什麼新特性 Sep 25, 2023 pm 01:34 PM

php8新特性有JIT 編譯器、型別推導、命名參數、聯合型別、屬性、錯誤處理改進、非同步程式支援、新的標準函式庫函數和匿名類的擴充等。詳細介紹:1、JIT編譯器,PHP8引入了JIT編譯器,這是一個重要的效能改進,JIT編譯器可以對一些高頻執行的程式碼進行即時編譯和最佳化,從而提高運行速度;2、類型推導,PHP8引入了類型推導功能,允許開發者在宣告變數時自動推導出變數的類型等等。

Go語言新功能解讀:讓程式設計更有效率 Go語言新功能解讀:讓程式設計更有效率 Mar 10, 2024 pm 12:27 PM

【Go語言新特性解讀:讓程式設計更有效率,需要具體程式碼範例】近年來,Go語言在軟體開發領域備受關注,其簡潔、高效的設計理念吸引了越來越多的開發者。作為一種靜態類型的程式語言,Go語言不斷推出新的功能以提高開發效率,簡化程式碼編寫過程。本文將深入解讀Go語言最新的特性,探討如何透過具體的程式碼範例來體驗這些新特性帶來的便利性。模組化開發(GoModules)Go語言從1

CSS3的新功能一覽:如何使用CSS3實現過渡效果 CSS3的新功能一覽:如何使用CSS3實現過渡效果 Sep 09, 2023 am 11:27 AM

CSS3的新功能一覽:如何使用CSS3實現過渡效果CSS3作為CSS的最新版本,在眾多新功能中,最有趣和實用的應該是過渡效果(transition)。過渡效果可以讓我們的頁面在互動時更加平滑、更漂亮,為使用者帶來良好的視覺體驗。本文將介紹CSS3過渡效果的基本用法,並附有對應的程式碼範例。 transition-property屬性:指定需要過渡的CSS屬性過渡效果

CSS3的新功能一覽:如何使用CSS3實現水平居中佈局 CSS3的新功能一覽:如何使用CSS3實現水平居中佈局 Sep 09, 2023 pm 04:09 PM

CSS3的新功能一覽:如何使用CSS3實現水平居中佈局在網頁設計和佈局中,水平居中佈局是一項常見的需求。過去,我們經常使用複雜的JavaScript或CSS技巧來實現此目的。然而,CSS3引入了一些新的特性,使得水平居中佈局更加簡單和靈活。本文將介紹一些CSS3的新特性,並提供一些程式碼範例,示範如何使用CSS3實現水平居中佈局。一、使用flexbox佈局fle

See all articles