全套Java教程_Java基礎入門教程,零基礎小白自學Java必備教程 🛴# 014 # 第十四單元 介面 #
一、本單元知識點概述
(Ⅰ)知識點概述
二、本單元目標
三、本單元知識詳講
14.1 發紅包的綜合案例
14.1.1 綜合案例:群主發普通紅包★★★
群主發普通紅包。某群有多名成員,群主給成員發普通紅包。普通紅包的規則:
-
群主的一筆金額,從群主餘額中扣除,平均分成n等份,讓成員領取。
-
成員領取紅包後,保存到成員餘額中。
請根據描述,完成案例中所有類的定義以及指定類之間的繼承關係,並完成發紅包的操作。
14.1.2 案例分析 ★★★
根據描述分析,得出如下繼承體系:
14.1.3 案例實現 ★★★
1 public class User { 2 // 成員變數 3 private String username;// 用戶名 4 private double leftMoney;// 餘額 5 // 構造方法 6 public User() { } 7 public User(String username, double leftMoney) { 8 this.username = username; 9 this.leftMoney = leftMoney; 10 } 11 // get/set方法 12 public String getUsername() { 13 return username; 14 } 15 public void setUsername(String username) { 16 this.username = username; 17 } 18 public double getLeftMoney() { 19 return leftMoney; 20 } 21 public void setLeftMoney(double leftMoney) { 22 this.leftMoney = leftMoney; 23 } 24 // 展示資訊的方法 25 public void show() { 26 System.out.println("用戶名:"+ username +" , 餘額為:" + leftMoney + "元"); 27 } 28 }
定義群主類:
1 public class QunZhu extends User { 2 // 添加構造方法 3 public QunZhu() { } 4 public QunZhu(String username, double leftMoney) { // 通過super 調用父類構造方法 5 super(username, leftMoney); 6 } 7 /* 8 群主發紅包,就是把一個整數的金額,分層若干等份。 9 1.獲取群主餘額,是否夠發紅包. 不能則返回null,並提示. 能則繼續. 10 2.修改群主餘額. 11 3.拆分紅包. 12 3.1.如果能整除,那麼就平均分。 13 3.2.如果不能整除,那麼就把餘數分給最後一份。 14 */ 15 public ArrayList<Double> send(int money, int count) { 16 // 獲取群主餘額 17 double leftMoney = getLeftMoney(); 18 if(money > leftMoney) { 19 return null; 20 } 21 // 修改群主餘額的 22 setLeftMoney(leftMoney ‐ money); 23 // 創建一個集合,保存等份金額 24 ArrayList<Double> list = new ArrayList<>(); 25 // 擴大100倍,相當於折算成'分'為單位,避免小數運算損失精度的問題 26 money = money * 100; 27 // 每份的金額 28 int m = money / count; 29 // 不能整除的餘數 30 int l = money % count; 31 // 無論是否整除,n‐1份,都是每份的等額金額 32 for (int i = 0; i < count ‐ 1; i++) { 33 // 縮小100倍,折算成 '元' 34 list.add(m / 100.0); 35 } 36 // 判斷是否整除 37 if (l == 0) { 38 // 能整除, 最後一份金額,與之前每份金額一致 39 list.add(m / 100.0); 40 } else { 41 // 不能整除, 最後一份的金額,是之前每份金額+餘數金額 42 list.add((m + l) / 100.00); 43 } 44 // 返回集合 45 return list; 46 } 47 }
定義成員類:
1 public class Member extends User { 2 public Member() { } 3 public Member(String username, double leftMoney) { 4 super(username, leftMoney); 5 } 6 // 打開紅包,就是從集合中,隨機取出一份,保存到自己的餘額中 7 public void openHongbao(ArrayList<Double> list) { 8 // 創建Random對象 9 Random r = new Random(); 10 // 隨機生成一個角標 11 int index = r.nextInt(list.size()); 12 // 移除一個金額 13 Double money = list.remove(index); 14 // 直接調用父類方法,設置到餘額 15 setLeftMoney( money ); 16 } 17 }
定義測試類:
1 public class Test { 2 public static void main(String[] args) { 3 // 創建一個群主對象 4 QunZhu qz = new QunZhu("群主" , 200); 5 // 創建一個鍵盤錄入 6 Scanner sc = new Scanner(); 7 System.out.println("請輸入金額:"); 8 int money = sc.nextInt(); 9 System.out.println("請輸入個數:"); 10 int count = sc.nextInt(); 11 // 發送紅包 12 ArrayList<Double> sendList = s.send(money,count); 13 // 判斷,如果餘額不足 14 if(sendList == null){ 15 System.out.println(" 餘額不足..."); 16 return; 17 } 18 // 創建三個成員 19 Member m = new Member(); 20 Member m2 = new Member(); 21 Member m3 = new Member(); 22 // 打開紅包 23 m.openHongbao(sendList); 24 m2.openHongbao(sendList); 25 m3.openHongbao(sendList); 26 // 展示資訊 27 qz.show(); 28 m.show(); 29 m2.show(); 30 m3.show(); 31 } 32 }
14.2 介面
14.2.1 概述 ★★★
介面,是Java語言中一種引用類型,是方法的集合,如果說類的內部封裝了成員變數、構造方法和成員方法,那麼
介面的內部主要就是封裝了方法,包含抽象方法(JDK 7及以前),默認方法和靜態方法(JDK 8),私有方法(JDK 9)。
介面的定義,它與定義類方式相似,但是使用 interface 關鍵字。它也會被編譯成.class文件,但一定要明確它並
不是類,而是另外一種引用數據類型。
引用數據類型:數組,類,介面。
介面的使用,它不能創建對象,但是可以被實現( implements ,類似於被繼承)。一個實現介面的類(可以看做是介面的子類),需要實現介面中所有的抽象方法,創建該類對象,就可以調用方法了,否則它必須是一個抽象
14.2.2 定義格式 ★★★★
public interface 介面名稱 { // 抽象方法 // 默認方法 // 靜態方法 // 私有方法 }
含有抽象方法
抽象方法:使用 abstract 關鍵字修飾,可以省略,沒有方法體。該方法供子類實現使用。
public interface InterFaceName { public abstract void method(); }
**含有默認方法和靜態方法**
默認方法:使用 default 修飾,不可省略,供子類調用或者子類重寫。
靜態方法:使用 static 修飾,供介面直接調用。
程式碼如下:
public interface InterFaceName { public default void method() { // 執行語句 } public static void method2() { // 執行語句 } }
含有私有方法和私有靜態方法
私有方法:使用 private 修飾,供介面中的默認方法或者靜態方法調用。
public interface InterFaceName { private void method() { // 執行語句 } }
實現的概述
類與介面的關係為實現關係,即類實現介面,該類可以稱為介面的實現類,也可以稱為介面的子類。實現的動作類
似繼承,格式相仿,只是關鍵字不同,實現使用 implements 關鍵字。
非抽象子類實現介面:
-
必須重寫介面中所有抽象方法。
-
繼承了介面的默認方法,即可以直接調用,也可以重寫。
實現格式:
class 類名 implements 介面名 { // 重寫介面中抽象方法【必須】 // 重寫介面中默認方法【可選】 }
抽象方法的使用
定義介面:
public interface LiveAble { // 定義抽象方法 public abstract void eat(); public abstract void sleep(); }
定義實現類:
1 public class Animal implements LiveAble { 2 @Override 3 public void eat() { 4 System.out.println("吃東西"); 5 } 6 @Override 7 public void sleep() { 8 System.out.println("晚上睡"); 9 } 10 }
定義測試類:
1 public class InterfaceDemo { 2 public static void main(String[] args) { 3 // 創建子類對象 4 Animal a = new Animal(); 5 // 調用實現後的方法 6 a.eat(); 7 a.sleep(); 8 } 9 } 10 輸出結果: 11 吃東西 12 晚上睡
默認方法的使用
可以繼承,可以重寫,二選一,但是只能通過實現類的對象來調用。
1 public interface LiveAble { 2 public default void fly(){ 3 System.out.println("天上飛"); 4 } 5 }
定義實現類:
public class Animal implements LiveAble { // 繼承,什麼都不用寫,直接調用 }
定義測試類:
1 public class InterfaceDemo { 2 public static void main(String[] args) { 3 // 創建子類對象 4 Animal a = new Animal(); 5 // 調用默認方法 6 a.fly(); 7 } 8 } 9 輸出結果: 10 天上飛
定義介面:
1 public interface LiveAble { 2 public default void fly(){ 3 System.out.println("天上飛"); 4 } 5 }
定義實現類:
1 public class Animal implements LiveAble { 2 @Override 3 public void fly() { 4 System.out.println("自由自在的飛"); 5 } 6 }
定義測試類:
1 public class InterfaceDemo { 2 public static void main(String[] args) { 3 // 創建子類對象 4 Animal a = new Animal(); 5 // 調用重寫方法 6 a.fly(); 7 } 8 } 9 輸出結果: 10 自由自在的飛
靜態方法的使用
定義介面:
1 public interface LiveAble { 2 public static void run(){ 3 System.out.println("跑起來~~~"); 4 } 5 }
定義實現類:
public class Animal implements LiveAble { // 無法重寫靜態方法 }
定義測試類:
1 public class InterfaceDemo { 2 public static void main(String[] args) { 3 // Animal.run(); // 【錯誤】無法繼承方法,也無法調用 4 LiveAble.run(); 5 } 6 } 7 輸出結果: 8 跑起來~~~
私有方法的使用
-
私有方法:只有默認方法可以調用。
-
私有靜態方法:默認方法和靜態方法可以調用。
去調用。從設計的角度講,私有的方法是對默認方法和靜態方法的輔助。同學們在已學技術的基礎上,可以自行測
試。
定義介面:
1 public interface LiveAble { 2 default void func(){ 3 func1(); 4 func2(); 5 } 6 private void func1(){ 7 System.out.println("跑起來~~~"); 8 } 9 private void func2(){ 10 System.out.println("跑起來~~~"); 11 } 12 }
之前學過,在繼承體系中,一個類只能繼承一個父類。而對於介面而言,一個類是可以實現多個介面的,這叫做接
口的多實現。並且,一個類能繼承一個父類,同時實現多個介面。
實現格式:
class 類名 [extends 父類名] implements 介面名1,介面名2,介面名3... { // 重寫介面中抽象方法【必須】 // 重寫介面中默認方法【不重名時可選】 }
[ ]: 表示可選操作。
抽象方法
介面中,有多個抽象方法時,實現類必須重寫所有抽象方法。如果抽象方法有重名的,只需要重寫一次。程式碼如
下:
定義多個介面:
1 interface A { 2 public abstract void showA(); 3 public abstract void show(); 4 } 5 interface B { 6 public abstract void showB(); 7 public abstract void show(); 8 }
定義實現類:
1 public class C implements A,B{ 2 @Override 3 public void showA() { 4 System.out.println("showA"); 5 } 6 @Override 7 public void showB() { 8 System.out.println("showB"); 9 } 10 @Override 11 public void show() { 12 System.out.println("show"); 13 } 14 }
默認方法
介面中,有多個默認方法時,實現類都可繼承使用。如果默認方法有重名的,必須重寫一次。程式碼如下:
1 interface A { 2 public default void methodA(){} 3 public default void method(){} 4 } 5 interface B { 6 public default void methodB(){} 7 public default void method(){} 8 }
定義實現類:
1 public class C implements A,B{ 2 @Override 3 public void method() { 4 System.out.println("method"); 5 } 6 }
靜態方法
優先順序的問題
當一個類,既繼承一個父類,又實現若干個介面時,父類中的成員方法與介面中的默認方法重名,子類就近選擇執
行父類的成員方法。程式碼如下:
定義介面:
1 interface A { 2 public default void methodA(){ 3 System.out.println("AAAAAAAAAAAA"); 4 } 5 }
定義父類:
1 class D { 2 public void methodA(){ 3 System.out.println("DDDDDDDDDDDD"); 4 } 5 }
定義子類:
1 class C extends D implements A { 2 // 未重寫methodA方法 3 }
定義測試類:
1 public class Test { 2 public static void main(String[] args) { 3 C c = new C(); 4 c.methodA(); 5 } 6 } 7 輸出結果: 8 DDDDDDDDDDDD
14.2.5 介面的多繼承★★★
定義父介面:
1 interface A { 2 public default void method(){ 3 System.out.println("AAAAAAAAAAAAAAAAAAA"); 4 } 5 } 6 interface B { 7 public default void method(){ 8 System.out.println("BBBBBBBBBBBBBBBBBBB"); 9 } 10 }
定義子介面:
1 interface D extends A,B{ 2 @Override 3 public default void method() { 4 System.out.println("DDDDDDDDDDDDDD"); 5 } 6 }
小貼士:
子介面重寫默認方法時,default關鍵字可以保留。
子類重寫默認方法時,default關鍵字不可以保留。
14.2.6 其他成員特點
-
介面中,無法定義成員變數,但是可以定義常量,其值不可以改變,默認使用public static final修飾。
-
介面中,沒有構造方法,不能創建對象。
-
介面中,沒有靜態程式碼塊。
四、本單元知識總結
1. 介面的定義格式
2. 介面的特點
3. 介面的多實現