JAVA8介面中的default、static方法使用注意事項
JAVA8中介面interface引入方法實現的猜想
在JAVA8之前java中的介面型別旨在定義型別的介面規約,並不能擁有自己的方法實現,具體實現完全交由實現類自己完成。
以普通人和中上階層為例,為各自的子女讀大學的目標:
普通人大部分甚至可能全部都是告誡子女讀書畢業找份好工作;
後者更多要求考TOEFL、GRE、出國留學回來做高管、出資給孩子創業;
介面規約的方法行為是寬泛的,無法具體實現;
而現實中的實現則是 符合該規約的實體自己的實現。
但是在JAVA8中可以在介面中定義預設的行為、以及靜態方法的實現。
你可以想象,人類文明發展到後面,大家都不需要工作了,完全交由機器人處理。這時候,人們的行為是一樣的: 出生 – 接受各種知識注入腦子裡–不工作–等待生命結束(或者永生)。 規約可以有一個稍微具體的實現。大家都可以使用該具體的行為。這就是JAVA8中的default、static方法。
default方法
在java.lang.Iterable介面中有一個預設的方法實現:
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
default方法使用default關鍵字修飾,它是物件方法,需要使用物件來進行訪問。
以下的示例中,使用了JAVA8中的新註解 @FunctionalInterface
package com.byron4j.hightLevel.java8.lambda;
/**
*
* <pre>
* 介面型別 擁有自己的default、static方法實現
* @FunctionalInterface 表明該介面是一個函式式介面,只能擁有 一個抽象方法
* </pre>
* @author Byron.Y.Y
*/
@FunctionalInterface
public interface DefaultStaticMethodDemo {
/*非default、static方法不能有實現
* --否則編譯錯誤--Abstract methods do not specify a body
void sayHello4CompilerError(){};
*/
void sayHello();
/*default、static方法必須有具體的實現
* --否則編譯錯誤--This method requires a body instead of a semicolon
default void studyTarget();
*/
default void studyTarget(){
System.out.println("出生");
System.out.println("\t--> 注入知識");
System.out.println("\t\t--> 生命消亡");
}
//可以擁有多個default方法
default void studyTarget2(){
System.out.println("DefaultStaticMethodDemo#【default】studyTarget2 invok.");
}
//可以擁有多個static方法
static void info(){
System.out.println("DefaultStaticMethodDemo#【static】 info invok.");
}
public static void main(String[] args) {
info();
new DefaultStaticMethodDemo() {
//僅僅需要實現抽象方法
//default、static方法不需要強制自己新實現
@Override
public void sayHello() {
// TODO Auto-generated method stub
}
};
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
介面中方法使用的注意事項
非default、static方法不能有實現,否則編譯錯誤:Abstract methods do not specify a body
default、static方法必須有具體的實現,否則編譯錯誤:This method requires a body instead of a semicolon
可以擁有多個default方法
可以擁有多個static方法
使用介面中型別時,僅僅需要實現抽象方法,default、static方法不需要強制自己新實現
實現多個介面引發的問題
多個介面存在簽名一樣的default方法導致編譯錯誤
JAVA8中實現多個介面可能引發的問題:多個介面存在簽名一樣的default方法導致編譯錯誤。
又有一個介面DefaultStaticMethodDemo2 和DefaultStaticMethodDemo都擁有一樣的簽名的default studyTarget方法:
package com.byron4j.hightLevel.java8.lambda;
/**
*
* <pre>
* 介面型別 擁有自己的default、static方法實現
* @FunctionalInterface 表明該介面是一個函式式介面,只能擁有 一個抽象方法
* </pre>
* @author Byron.Y.Y
*/
public interface DefaultStaticMethodDemo2 {
default void studyTarget(){
System.out.println("出生");
System.out.println("\t--> 注入知識");
System.out.println("\t\t--> 生命消亡");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
因為可以實現多個介面,所以類SubClassDemo實現了DefaultStaticMethodDemo、DefaultStaticMethodDemo2,但是編譯不通過:
package com.byron4j.hightLevel.java8.lambda;
//編譯錯誤:Duplicate default methods named studyTarget
// with the parameters () and () are inherited from the
//types DefaultStaticMethodDemo2 and DefaultStaticMethodDemo
public class SubClassDemo implements
DefaultStaticMethodDemo, DefaultStaticMethodDemo2{
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
這就相當於你在類中定義了兩個同樣的簽名方法,從而引致編譯錯誤。
繼承抽象類同時實現介面引發的問題
如果一個類實現了某個擁有default方法的介面的話,在該類中則不需要自己再次實現該default方法了。
但是如果該類實現介面時,還繼承了某個抽象類,該抽象類擁有一個和default簽名一樣的抽象方法,則在該類中必須重寫抽象方法(也是介面中的該default方法):
抽象類AbstractClassDemo 擁有和介面DefaultStaticMethodDemo同安用的簽名方法studyTarget:
package com.byron4j.hightLevel.java8.lambda;
public abstract class AbstractClassDemo {
abstract void studyTarget();
}
- 1
- 2
- 3
- 4
- 5
- 6
類SubClassDemo2 必須重寫studyTarget方法:
package com.byron4j.hightLevel.java8.lambda;
/**
*
* <pre>
* 繼承抽象類
* 實現介面
* 抽象類、介面存在同樣的簽名方法
* 抽象類未有實現體;介面中default實現了方法。
* </pre>
* @author Byron.Y.Y
*/
public class SubClassDemo2 extends AbstractClassDemo implements
DefaultStaticMethodDemo {
@Override
public void sayHello() {
// TODO Auto-generated method stub
}
@Override
public void studyTarget() {
// TODO Auto-generated method stub
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
其他注意事項
抽象類、介面存在同樣的簽名方法,抽象類有實現體但是不是public修飾的;—-> 編譯錯誤:抽象介面中的實現不能隱藏介面中的方法;—->解決辦法:將抽象類中的方法訪問控制符使用public修飾。
package com.byron4j.hightLevel.java8.lambda;
public abstract class AbstractClassDemo2 {
void sayHello(){
System.out.println("抽象類的sayHello!");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
package com.byron4j.hightLevel.java8.lambda;
/**
*
* <pre>
* 繼承抽象類
* 實現介面
* 抽象類、介面存在同樣的簽名方法
* 抽象類有實現體但是不是public修飾的;
*-------------編譯錯誤:抽象介面中的實現不能隱藏介面中的方法
*-------------解決辦法:將抽象類中的方法訪問控制符使用public修飾
* </pre>
* @author Byron.Y.Y
*/
public class SubClassDemo3 extends AbstractClassDemo2 implements
DefaultStaticMethodDemo {
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
抽象類AbstractClassDemo2 擁有和介面DefaultStaticMethodDemo相同簽名的方法sayHello,但是AbstractClassDemo2 的實現不是public的引發編譯錯誤。
相關推薦
JAVA8介面中的default、static方法使用注意事項
JAVA8中介面interface引入方法實現的猜想在JAVA8之前java中的介面型別旨在定義型別的介面規約,並不能擁有自己的方法實現,具體實現完全交由實現類自己完成。以普通人和中上階層為例,為各自的子女讀大學的目標:普通人大部分甚至可能全部都是告誡子女讀書畢業找份好工作;
Java8 介面中default方法帶來的問題
介面中預設方法中的問題:預設方法的出現,是為了方便 當所有實現類都需要新增某個方法時,在介面中能直接寫實現過程。但是,如果某個類,實現了兩個介面,並且這兩個介面有同名預設方法,那麼這個類就無法判斷是繼承的是誰的類。必須要在繼承方法體中,宣告繼承的是哪個實現類的方法。 例如:
jdk1.8的介面中default修飾的方法
我用的的是jdk1.8,某次在編寫某個類實現listener介面的時候,發現ide沒有提示實現介面的方法,有點迷就去介面原始碼去看了一下,看到接口裡的方法竟然可以定義為default型別,加了一個def
js物件中原型(prototype)的使用方法、替換以及注意事項
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <t
Java8新特性-003-Java8介面中的default修飾符
Java 8新增了default方法,它可以在介面新增新功能特性,而且還不影響介面的實現類。 另外,新增的default方法不會影響函式式介面。 Default方法是非常有用的,通過在介面定義的方法的
Java中this、static、super、final
this class Person { public String _name; public int _age; public Person() //無參構造 { System.out.println("Person()");
Calendar的get()、set()和roll()方法注意事項
轉載:http://blog.sina.com.cn/s/blog_677873910102vcp7.html 示例程式碼: Calendar c = Calendar.getInstance(); c.set(2014, Ca
Java中this、static關鍵字的記憶體圖解
Java中的關鍵字有很多,abstract default goto* null switch boolean do if package nchronzed break&nb
Java中this、static關鍵字的內存圖解
數據區 prot 屬性 volatile stat strong 發展 char ons Java中的關鍵字有很多,abstract default goto* null switch boolean do if package nchronzed
NIO buffer中clear、compact方法的區別
呼叫clear()方法:position將被設回0,limit設定成capacity,換句話說,Buffer被清空了,其實Buffer中的資料並未被清除,只是這些標記告訴我們可以從哪裡開始往Buffer裡寫資料。如果Buffer中有一些未讀的資料,呼叫clear()方法,資料將“被遺忘”,意
接口裡的default,static方法
我們都知道接口裡的變數預設隱含型別是public static final,也是就是說是常量。而方法預設型別是public abstract,所以介面的方法都是抽象方法,但是事實真的是這樣嗎? 我的PC上安裝的是jdk1.8,一次編寫介面程式碼的時候,看到接口裡的方法竟然可以定義為def
Java中 float、double使用注意問題
在java中執行一下程式碼 System.out.println(2.00-1.10); 輸出的結果是:0.8999999999999999 很奇怪,並不是我們想要的值0.9 再執行如下程式碼: System.out.println(2.00f-1.10f);
java--類繼承和實現的介面中含有相同的方法
首先,說一下,當某一個類實現了兩個介面的時候,兩個介面中存在兩個相同的方法,在實現的類中只需實現一個方法的方法體。當一個類繼承一個類,並且實現一個或者多個介面的時候,其中,父類和父介面中存在相同的方法。 如果子類中存在該方法的實現體或者說是覆蓋,則使用該類的物件去掉用該方法
Jmeter HTTP介面案例開發、除錯方法
HTTP介面案例案例開發的步驟為: 1.瞭解要開發案例的業務流程,比如新增案例,是否有其它前置條件,如果有,就需要先開發好前置條件的案例 2.手工開發案例或者通過jmeter錄製功能開發案例 3.對案例進行除錯,響應結果和預期結果一致,則案例開發完成 對於簡單
Hibernate的Session介面中save/delete/update方法2個引數(entityName)的深入解析
Hibernate的Session介面中delete/update方法2個引數(entityName)的深入解析 2010-09-14 18:07 session.update(Object arg0); session.update(String arg0, Obje
Scanner中next、nextLine、nextInt使用注意事項
next()和nextLine()區別 next()會自動過濾空格、tab、enter等結束符,直至遇到有效字元之後,空格、tab、enter等會視為結束符 nextLine()掃描整行即enter之前的所有字元(包括空格、tab等) 在nextInt()後使用nextLine()後ne
有關Java實體類中get、set方法和有參無參構造方法的個人見解。
結論:(總的來說,get和set方法就是為了能以得到和設定實體類中的私有屬性值,而一個類中至少要有一個構造方法,當沒有人為新增的時候,編譯器會自動加入一個隱式的無參構造方法,當有人為新增時,編譯器就不會自動添加了。無參構造方法的作用是為了比較方便的new出一個物
C/C++中auto、static、register、extern關鍵字區別小結
1. 說明 以上四種都是變數儲存說明符,因為C/C++語言在變數定義時候的完整語法是: [儲存說明符] [資料型別] [變數名稱] [=初始化]; 因為大多我們宣告的變數都
Callable介面中何時執行call方法
import java.util.ArrayList; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.
Tensorflow兩種資料讀取方法應用、對比及注意事項
本文對比介紹了兩種Tensorflow針對大資料集的資料讀取方法,具體來說是:方法1:tf.train.slice_input_producer+流水線(這裡用這個API指代這一類,其實還有其他的API)。方法2:Dataset方法,據說是Tensorflow 1.3版本之後