Java8接口之默認(rèn)方法與靜態(tài)方法詳解
前言
在Java8之前,java中的接口只能有抽象方法。默認(rèn)情況下,接口的所有方法都是公共和抽象的。Java8允許接口具有默認(rèn)和靜態(tài)方法。我們?cè)诮涌谥惺褂媚J(rèn)方法的原因是,允許開發(fā)人員向接口添加新方法,而不會(huì)影響實(shí)現(xiàn)這些接口的類。
為什么選擇默認(rèn)方法?
例如,如果A、B、C和D等幾個(gè)類實(shí)現(xiàn)了一個(gè)接口XYZInterface,那么如果我們向XYZInterface添加一個(gè)新方法,我們必須更改實(shí)現(xiàn)該接口的所有類(A、B、C和D)中的代碼。在本例中,我們只有四個(gè)類實(shí)現(xiàn)了我們想要更改的接口,但是想象一下,如果有數(shù)百個(gè)類實(shí)現(xiàn)了一個(gè)接口,那么幾乎不可能更改所有這些類中的代碼。這就是為什么在Java8中,我們有了一個(gè)新概念“默認(rèn)方法”。這些方法可以添加到任何現(xiàn)有接口中,我們不需要強(qiáng)制在實(shí)現(xiàn)類中實(shí)現(xiàn)這些方法,因此我們可以在不破壞代碼的情況下將這些默認(rèn)方法添加到現(xiàn)有接口中。
我們可以說(shuō),java 8中引入了默認(rèn)方法的概念,以便在現(xiàn)有接口中添加新方法,從而使它們向后兼容。向后兼容性是在不破壞舊代碼的情況下添加新功能。
接口中的靜態(tài)方法與默認(rèn)方法類似,只是我們不能在實(shí)現(xiàn)這些接口的類中重寫這些方法。
Java 8示例:接口中的默認(rèn)方法
MyInterface中的方法newMethod()是默認(rèn)方法,這意味著我們不需要在實(shí)現(xiàn)類示例中實(shí)現(xiàn)該方法。通過(guò)這種方式,我們可以將默認(rèn)方法添加到現(xiàn)有接口中,而不必?fù)?dān)心實(shí)現(xiàn)這些接口的類。
interface MyInterface{
/* This is a default method so we need not
* to implement this method in the implementation
* classes
*/
default void newMethod(){
System.out.println("Newly added default method");
}
/* Already existing public and abstract method
* We must need to implement this method in
* implementation classes.
*/
void existingMethod(String str);
}
public class Example implements MyInterface{
// implementing abstract method
public void existingMethod(String str){
System.out.println("String is: "+str);
}
public static void main(String[] args) {
Example obj = new Example();
//calling the default method of interface
obj.newMethod();
//calling the abstract method of interface
obj.existingMethod("Java 8 is easy to learn");
}
}
輸出:
Newly added default method
String is: Java 8 is easy to learn
Java 8示例:接口中的靜態(tài)方法
如上所述,接口中的靜態(tài)方法與默認(rèn)方法類似,因此我們不需要在實(shí)現(xiàn)類中實(shí)現(xiàn)它們。我們可以安全地將它們添加到現(xiàn)有接口中,而無(wú)需更改實(shí)現(xiàn)類中的代碼。由于這些方法是靜態(tài)的,我們不能在實(shí)現(xiàn)類中重寫它們。
interface MyInterface{
/* This is a default method so we need not
* to implement this method in the implementation
* classes
*/
default void newMethod(){
System.out.println("Newly added default method");
}
/* This is a static method. Static method in interface is
* similar to default method except that we cannot override
* them in the implementation classes.
* Similar to default methods, we need to implement these methods
* in implementation classes so we can safely add them to the
* existing interfaces.
*/
static void anotherNewMethod(){
System.out.println("Newly added static method");
}
/* Already existing public and abstract method
* We must need to implement this method in
* implementation classes.
*/
void existingMethod(String str);
}
public class Example implements MyInterface{
// implementing abstract method
public void existingMethod(String str){
System.out.println("String is: "+str);
}
public static void main(String[] args) {
Example obj = new Example();
//calling the default method of interface
obj.newMethod();
//calling the static method of interface
MyInterface.anotherNewMethod();
//calling the abstract method of interface
obj.existingMethod("Java 8 is easy to learn");
}
}
輸出:
Newly added default method
Newly added static method
String is: Java 8 is easy to learn
Java 8 - 抽象類與接口
隨著接口中默認(rèn)方法的引入,抽象類似乎與Java8中的接口相同。然而,這并不是完全正確的,盡管我們現(xiàn)在可以像抽象類一樣在接口中有具體的方法(帶主體的方法),但這并不意味著它們是相同的。它們之間仍然沒(méi)有什么區(qū)別,其中之一是抽象類可以有構(gòu)造函數(shù),而在接口中我們不能有構(gòu)造函數(shù)。
接口的目的是提供完全抽象,而抽象類的目的是提供部分抽象。這仍然適用。界面就像是類的藍(lán)圖,通過(guò)引入默認(rèn)方法,您可以簡(jiǎn)單地說(shuō),我們可以在界面中添加附加功能,而不會(huì)影響最終用戶類。
默認(rèn)方法和多重繼承
當(dāng)我們有兩個(gè)具有相同簽名的默認(rèn)方法的接口時(shí),可能會(huì)出現(xiàn)多重繼承問(wèn)題。讓我們舉個(gè)例子。
interface MyInterface{
default void newMethod(){
System.out.println("Newly added default method");
}
void existingMethod(String str);
}
interface MyInterface2{
default void newMethod(){
System.out.println("Newly added default method");
}
void disp(String str);
}
public class Example implements MyInterface, MyInterface2{
// implementing abstract methods
public void existingMethod(String str){
System.out.println("String is: "+str);
}
public void disp(String str){
System.out.println("String is: "+str);
}
public static void main(String[] args) {
Example obj = new Example();
//calling the default method of interface
obj.newMethod();
}
}
輸出:
Error: Duplicate default methods named newMethod with the parameters () and () are inherited from the types MyInterface2 and MyInterface
這是因?yàn)槲覀冊(cè)诮涌谥卸加邢嗤姆椒?,而編譯器不確定要調(diào)用哪個(gè)方法。
如何解決這個(gè)問(wèn)題?
為了解決這個(gè)問(wèn)題,我們可以在實(shí)現(xiàn)類中實(shí)現(xiàn)這個(gè)方法,如下所示:
interface MyInterface{
default void newMethod(){
System.out.println("Newly added default method");
}
void existingMethod(String str);
}
interface MyInterface2{
default void newMethod(){
System.out.println("Newly added default method");
}
void disp(String str);
}
public class Example implements MyInterface, MyInterface2{
// implementing abstract methods
public void existingMethod(String str){
System.out.println("String is: "+str);
}
public void disp(String str){
System.out.println("String is: "+str);
}
//Implementation of duplicate default method
public void newMethod(){
System.out.println("Implementation of default method");
}
public static void main(String[] args) {
Example obj = new Example();
//calling the default method of interface
obj.newMethod();
}
}
輸出:
Implementation of default method
首先我們要總體說(shuō)一下,為什么要有這兩個(gè)方法存在:
(1)原先的jdk7之類的,它們接口中的方法都是抽象方法,沒(méi)有具體的實(shí)現(xiàn),就相當(dāng)于定義好了這個(gè)接口有哪些功能,卻沒(méi)有具體定義功能是怎么實(shí)現(xiàn)的,通常由接口的實(shí)現(xiàn)類來(lái)做具體功能實(shí)現(xiàn)。那么,如果面向接口編程,大家已經(jīng)根據(jù)自己需要通過(guò)繼承接口的方式來(lái)實(shí)現(xiàn)了自己的功能,突然有一天,產(chǎn)品提需求了,你需要給所有接口的實(shí)現(xiàn)類都添加一個(gè)新的功能即一個(gè)新的方法實(shí)現(xiàn),而且這個(gè)方法可能大家都是一樣的,那咋辦?
jdk8以前的做法肯定是現(xiàn)在接口中定義這個(gè)抽象方法,然后所有實(shí)現(xiàn)類必須實(shí)現(xiàn)這個(gè)方法(不然接口中多出一個(gè)抽象方法,其他類都沒(méi)有實(shí)現(xiàn),編譯是會(huì)報(bào)錯(cuò)的),如果實(shí)現(xiàn)類比較多,那改起來(lái)會(huì)很麻煩,這種情況下是不利于維護(hù)的。
那么我們?cè)趈dk8中就有了好的解決方式,就是在接口中加一個(gè)默認(rèn)方法,這個(gè)默認(rèn)方法有具體實(shí)現(xiàn),這樣就不用去修改實(shí)現(xiàn)類啦,很省事。
總結(jié)
到此這篇關(guān)于Java8接口之默認(rèn)方法與靜態(tài)方法的文章就介紹到這了,更多相關(guān)Java8默認(rèn)方法與靜態(tài)方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java反射機(jī)制給實(shí)體類相同字段自動(dòng)賦值實(shí)例
這篇文章主要介紹了java反射機(jī)制給實(shí)體類相同字段自動(dòng)賦值實(shí)例,具有2020-08-08
Java實(shí)用工具之使用oshi獲取主機(jī)信息的方法
這篇文章主要介紹了Java實(shí)用工具之使用oshi獲取主機(jī)信息的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
Java8 Stream Collectors收集器使用方法解析
這篇文章主要介紹了Java8 Stream Collectors收集器使用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
SpringMVC后端返回?cái)?shù)據(jù)到前端代碼示例
這篇文章主要介紹了SpringMVC后端返回?cái)?shù)據(jù)到前端代碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Java實(shí)戰(zhàn)之晚會(huì)抽獎(jiǎng)系統(tǒng)的實(shí)現(xiàn)
這篇文章主要介紹了如何利用Java語(yǔ)言編寫一個(gè)晚會(huì)抽獎(jiǎng)系統(tǒng),文中采用到的技術(shù)有Jdbc、Servlert、JavaScript、JQuery、Ajax等,感興趣的可以學(xué)習(xí)一下2022-03-03

