diff --git a/03:类与对象/04.md b/03:类与对象/04.md index 7117729..474a8bc 100644 --- a/03:类与对象/04.md +++ b/03:类与对象/04.md @@ -546,7 +546,7 @@ edible.howToEat(); ## 3. 接口的使用 -### 3.1. Comparable接口(理解) +### 3.1. Comparable接口(了解) 首先来回忆一下在数组那一章学习到的排序函数: @@ -620,7 +620,7 @@ public class SortRectangles { > 挑战:如果圆形和方形面积可以参与比较,是不是数组中可以存在圆形和方形的对象,而且也可以排序?答案是肯定的。可以尝试对圆形和方形的混合数组进行排序。提示:最好不要在 圆形和方形的类上实现 Comparable 接口,而应该在其父类实现 Comparable 接口。想一想为什么? -## 4. 接口和抽象类 +## 4. 接口和抽象类(了解) > In an interface, the data must be constants; an abstract class can have all types of data. Each method in an interface has only a signature without implementation; an abstract class can have concrete methods. > @@ -637,6 +637,165 @@ public class SortRectangles { 1. 实线箭头表示类的扩展;虚线街头表示接口的扩展方向; 2. 所有类都有一个共同的超类 Object,但是接口没有共同的**超接口**。 -## 本章重点 +### 4.1. 补充说明(了解) + +Java 在类的继承的关系上是单继承方式,也就是说,在定义一个类的时候,有且只能有一个父类(C++是多继承,可以有多个父类)。但是在接口实现上可能有多个。一般来说,接口用来统一某些能力,但是这种能力很难以类属的方式来抽象。 + +### 4.2. 接口与类属关系 + +如下图:数码产品的分类。圆形的是耳机接口,半圆是`USB`接口(接口中的数字代表是2.0还是3.0接口标准)。 + +![Alt text](img/%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E.drawio.svg) + +我们看到不论是耳机接口还是`USB`接口都很难抽象到父类,这两个能力(特性)是和类属无关的,但是又广泛存在于不同的数码产品中。同时我们注意到,`USB3`是`USB2`的升级,也就是说`USB3`由`USB2`扩展而来。接下来我们`UML`的方式来描述: + +#### 4.2.1. 类属关系: + +```mermaid +classDiagram + +DigitalDevice <|-- Speaker +DigitalDevice <|-- Mobile +DigitalDevice <|-- Laptop + +Speaker <|-- SpeakerA +Speaker <|-- SpeakerB + +Mobile <|-- MobileX +Mobile <|-- MobileY + +Laptop <|-- LaptopA +Laptop <|-- LaptopB + +class DigitalDevice{ + <> + + boolean status + + on() + + off() +} + +class Speaker{ + <> + +speak()* +} + +class Mobile{ + <> + +phoneCall(String number)* +} + +class Laptop{ + <> + +runProgram(String file)* +} + +``` + +我们把相同的能力尽量向上级抽象,更便于我们使用多态的机制。 + +抽象类:`DigitalDevice` + +1. 所有的数码设备都有状态`status`,要么开机,要么关机; +2. 所有的数码设备都有开,和关的功能,因此用两个函数`on()`和`off()`描述; + +因此可以把上述的变量和函数抽象到`DigitalDevice`这样,所有的子类都具备上述的能力(注意:函数可能被覆盖)。 + +对于特定的子类型:`Speaker`,`Mobile`,`Laptop`都有自己特有的能力: + +1. Speaker:`speak()` 播放声音; +2. Mobile:`phoneCall(String number)`打电话; +3. Laptop:`runProgram(String file)`运行程序。 + +上述三个类,连同`DigitalDevice`都是抽象类。真正可以实例化的类是: + +1. `SpeakerA` +2. `SpeakerB` +3. `MobileX` +4. `MobileY` +5. `LaptopA` +6. `LaptopB` + +#### 4.2.2. 接口描述 + +`Line35` 是`3.5mm` 的耳机接口。 + +```mermaid +classDiagram + +Usb2 <|-- Usb3 + +class Line35{ + <> + +lineOn()* + +lineOff()* +} + +class Usb2{ + <> + byte[] read()* + write(byte[] data)* +} + +class Usb3{ + <> + negotiationSpeed()* +} + +Line35 <|.. SpeakerA +Usb2 <|.. SpeakerA +Usb2 <|.. MobileX +Line35 <|.. MobileX +Line35 <|.. LaptopB + +Usb3 <|.. MobileY +Usb3 <|.. LaptopA +Usb3 <|.. LaptopB + + +Line35 <|.. SpeakerB + + + +``` + +再看看接口的实现关系: + +1. Usb3 的父接口是 Usb2; +2. 最终不同的数码产品实现的不同的接口。 + +### 4.3. Java 代码 + + + +```java +Object speakerA = new SpeakerA(); +Object speakerB = new SpeakerB(); + +Object mobileX = new MobileX(); +Object mobileY = new MobileY(); + +Object laptopA = new LaptopA(); +Object laptopB = new LaptopB(); + +System.out.println(laptopB instanceof DigitDevice); // true +System.out.println(laptopB instanceof Speaker); // false +System.out.println(laptopB instanceof Laptop); // true +System.out.println(laptopB instanceof LaptopB); // true + +Usb2 usb2 = (Usb2)laptopB; // 合法,因为USB3是USB2的子接口,具备USB2的所有能力 +usb2.read(); // 合法 +usb2.negotiationSpeed(); // 编译错误,没有这个函数。Java认为 usb2 的引用变量类型是 USB2 没有该函数; +Usb3 usb3 = (Usb3)laptopB; // 合法,实现了USB3的接口 +usb3.negotiationSpeed(); // 合法 + +Line35 line35 = (Line35)laptopB; // 合法,实现了Line35的接口 +line35.lineOn(); // 合法 + +Laptop laptop = (Laptop)laptopB; // 合法,是Laptop的子类型 +laptop.runProgram("C:/a.exe"); // 合法 +laptop.on(); // 合法,因为是DigitalDevice的子类型,具有`on()`和`off`的函数; +``` +顺着继承的关系和接口的实现关系来阅读上述的代码。 +## 5. 本章重点 除特别标注,其他都是重点,需要掌握。 \ No newline at end of file diff --git a/03:类与对象/img/接口说明.drawio.svg b/03:类与对象/img/接口说明.drawio.svg new file mode 100644 index 0000000..b3f7fdb --- /dev/null +++ b/03:类与对象/img/接口说明.drawio.svg @@ -0,0 +1,380 @@ + + + + + + + + + + + + + +
+
+
+ + Digital + +
+
+
+
+ + Digital + +
+
+ + + + + + + + +
+
+
+ Speaker +
+
+
+
+ + Speaker + +
+
+ + + + + + + + +
+
+
+ Mobile +
+
+
+
+ + Mobile + +
+
+ + + + + + + + +
+
+
+ Laptop +
+
+
+
+ + Laptop + +
+
+ + + + +
+
+
+ SpeakerA +
+
+
+
+ + SpeakerA + +
+
+ + + + +
+
+
+ SpeakerB +
+
+
+
+ + SpeakerB + +
+
+ + + + +
+
+
+ MobileX +
+
+
+
+ + MobileX + +
+
+ + + + +
+
+
+ MobileY +
+
+
+
+ + MobileY + +
+
+ + + + +
+
+
+ LaptopA +
+
+
+
+ + LaptopA + +
+
+ + + + +
+
+
+ LaptopB +
+
+
+
+ + LaptopB + +
+
+ + + + +
+
+
+ 2 +
+
+
+
+ + 2 + +
+
+ + + + +
+
+
+ 2 +
+
+
+
+ + 2 + +
+
+ + + + +
+
+
+ 3 +
+
+
+
+ + 3 + +
+
+ + + + +
+
+
+ 3 +
+
+
+
+ + 3 + +
+
+ + + + +
+
+
+ 3 +
+
+
+
+ + 3 + +
+
+ + + + + + + + + +
+
+
+ 耳机接口 +
+
+
+
+ + 耳机接口 + +
+
+ + + + +
+
+
+ 2 +
+
+
+
+ + 2 + +
+
+ + + + + + +
+
+
+ 3 +
+
+
+
+ + 3 + +
+
+ + + + +
+
+
+ USB2.0 +
+
+
+
+ + USB2.0 + +
+
+ + + + +
+
+
+ USB3.0 +
+
+
+
+ + USB3.0 + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file