接口的概念
- 大家可能都聽說過 usb 接口吧,無論你什麼設備,只有符合 USB 接口的規範,設備之間就可以連接。例如筆記本電腦上都會有一個 usb 母口,我們的手機數據線,鼠標等都有一個 usb 公口,我們把公口插到母口中,設備之間就可以互聯。我們可以看到,接口定義了一種公共的規範標準,只要符合規範標準,大家就可以通用。
Java中的接口
- 接口是多個類的公共規範。
- 接口是一種引用數據類型。
- 接口是方法的集合。
- 接口中不可以寫構造函數和靜態代碼塊。
- 在 Java 中,提供了 interface 關鍵字來定義接口。
public interface 接口名{}
接口中可以定義什麼那?
- JDK 任何版本
- 常量
- 抽象方法
- JDK 8 及以上版本
- 默認方法
- 靜態方法
- JDK 9 及以上版本
- 私有方法
常量
-
格式:
public static final 數據類型 常量名稱 = 數據值
-
注意:
- public static final 可以省略。
- 接口中的常量必須賦值。
- 常量使用大寫,單詞之間使用下劃線分隔。
-
如何訪問:接口名.常量名
-
示例:
public interface MyInterface {
int NUM_CONSTANT = 5;
}
public class Demo {
public static void main(String[] args) {
//直接使用 接口名.常量名訪問。
int NUM_CONSTANT = MyInterface.NUM_CONSTANT;
}
}
抽象方法
-
格式:
public abstract 返回值類型 方法名(參數列表);
-
如果使用:寫實現類。
-
注意:
- public abstract 可以省略。
- 抽象方法是接口中最重要的部分。非抽象實現類必須實現接口中的全部抽象方法,抽象實現類不必實現接口中的全部抽象方法。
public interface MyInterface {
void show();
}
//使用implement關鍵字
public class MyInterfaceImpl implements MyInterface {
//非抽象實現類需要實現其中的全部抽象方法
@Override
public void show() {
System.out.println("實現了MyInterface");
}
}
//創建實現類對象,調用方法
public class Demo {
public static void main(String[] args) {
MyInterfaceImpl myInterfaceImpl = new MyInterfaceImpl();
myInterfaceImpl.show();
}
}
默認方法
- 格式:
public default 返回值類型 方法名稱(參數列表){方法體};
- 作用:一方面解決了接口升級的問題。我們可以在接口中添加默認方法而不是抽象方法,這樣實現類就不會因爲要實現抽象方法而去修改代碼,並且實現類對象可以直接調用默認方法。另一方面,解決了Lambda表達式與函數式編程中函數模型拼接的問題,這方面就不介紹了。
- 注意:
- public 可以省略。
- 接口中的默認方法可以被實現類覆蓋重寫。
- 使用示例:
public interface MyInterface {
void show();
default void showDefault() {
System.out.println("這是接口中的默認方法");
}
}
public class MyInterfaceImpl implements MyInterface {
@Override
public void show() {
System.out.println("實現了MyInterface");
}
}
public class Demo {
public static void main(String[] args) {
MyInterfaceImpl myInterfaceImpl = new MyInterfaceImpl();
myInterfaceImpl.show();
myInterfaceImpl.showDefault();
}
}
靜態方法
- 格式:
public static 返回值類型 方法名(參數列表){方法體}
- 如果使用:接口名.靜態方法名(參數)
- 注意:
- public 可以省略。
- 我們都知道類中寫了一個靜態方法,可以使用 類名.靜態方法名 或者 對象名.靜態方法名 調用。但是接口中的靜態方法只能使用 接口名.靜態方法名 調用,而不能使用使用 實現類對象.靜態方法名 調用。
- 使用示例:
public interface MyInterface {
static void showStatic(){
System.out.println("這是接口的靜態方法");
}
}
public class Demo {
public static void main(String[] args) {
MyInterface.showStatic();
}
}
私有方法
- 分類:普通私有方法 和 靜態私有方法。
- 作用:解決多個默認方法或靜態方法之間代碼重複的問題,同時私有方法對外部隱藏。
- 格式:
- 普通私有方法:
private 返回值類型 方法名(參數列表){方法體}
- 靜態私有方法:
private static 返回值類型 方法名(參數列表){方法體}
- 普通私有方法:
- 使用場景1:
public interface MyInterface {
default void showDefault1(){
System.out.println("------");
showDefaultCommon();
}
default void showDefault2(){
System.out.println("------");
showDefaultCommon();
}
//抽取默認方法1和默認方法2的重複代碼。
//但是這個方法應該對實現類隱藏,我們不想要實現類對象調用這個方法,
//實現類調用默認方法1和默認方法2就行了,所以用到了private關鍵字。
private void showDefaultCommon(){
System.out.println("這是showDefault1和showDefault2都需調用的重複代碼");
}
}
- 使用場景2:
public interface MyInterface {
static void showDefault1(){
System.out.println("------");
showDefaultCommon();
}
static void showDefault2(){
System.out.println("------");
showDefaultCommon();
}
//抽取默認方法1和默認方法2的重複代碼。
//但是這個方法在外部調用時應該隱藏,所以用到了private關鍵字。
private static void showDefaultCommon(){
System.out.println("這是showDefault1和showDefault2都需調用的重複代碼");
}
}
實現類多實現,接口多繼承
- 類與類之間是單繼承的,直接父類只有一個。
- 但是類與接口之間是多實現的。一個類可以實現多個接口。
- 接口也可以繼承多個接口。
實現類繼承父類並實現多個接口的注意事項
- 如果實現類所實現的多個接口當中,存在重複的抽象方法,那麼只需要覆蓋重寫一次即可。
public interface MyInterface1 {
void show();
}
public interface MyInterface2 {
void show();
}
public class MyInterfaceImpl implements MyInterface1,MyInterface2 {
@Override
public void show() {
System.out.println("this a demo");
}
}
- 如果實現類所實現的多個接口當中,存在重複的默認方法,那麼實現類一定要對沖突的默認方法進行重寫。
public interface MyInterface1 {
default void show(){
System.out.println("this is MyInterface1");
}
}
public interface MyInterface2 {
default void show(){
System.out.println("this is MyInterface2");
}
}
public class MyInterfaceImpl implements MyInterface1,MyInterface2 {
@Override
public void show() {
System.out.println("this is a demo");
}
}
- 一個類如果直接父類當中的方法,和接口當中的默認方法發生了衝突,優先用父類當中的方法。
public class Fu {
public void show() {
System.out.println("this is Fu");
}
}
public interface MyInterface {
default void show(){
System.out.println("this is MyInterface");
}
}
public class Zi extends Fu implements MyInterface {
}
public class Demo {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show();//輸出:this is Fu
}
}
接口的多繼承注意事項
- 多個父接口當中的抽象方法如果重複,沒關係。
public interface MyInterface1 {
void method1();
void methodCommon();
}
public interface MyInterface2 {
void method2();
void methodCommon();
}
public interface MyInterface extends MyInterface1,MyInterface2{
void method3();
}
問:如果實現MyInterface,需要實現幾個方法?答案:4個。重複的methodCommon方法實現一次就行了。
- 多個父接口當中的默認方法如果重複,那麼子接口必須進行默認方法的覆蓋重寫。注意重寫時不要忘了default關鍵字。
public interface MyInterface1 {
default void method() {
System.out.println("this is MyInterface1");
}
}
public interface MyInterface2 {
default void method() {
System.out.println("this is MyInterface2");
}
}
public interface MyInterface extends MyInterface1,MyInterface2{
@Override
default void method() {
System.out.println("this is MyInterface");
}
}