## 連載:面向對象葵花寶典:思想、技巧與實踐(8) - “接口” 詳解
**接口”是我見過的面向對象領域中濫用、亂用、誤用最多的術語**:
有的人說:兄弟,給我提供一個“查詢XXX”的接口。。。。。。
有的人說:系統對外提供了“查詢”、“插入”、“更新”、“刪除”4個接口。。。。。。
有的人說:我們要基于“接口”編程。。。。。。
有的人說:你這樣做破壞了我們的接口設計。。。。。。
。。。。。。。。。。。
倒不是在這里指責他們的水平有多差,而是接口這個屬于的中文翻譯確實難以理解。
臺灣譯為介面,仲介之面的意思;大陸譯作界面,也譯作接口,但無論是“界面”、“介面”、“仲介之面”還是“接口”,都遠遠沒有“類”、“對象”那么直白和容易理解。
?
既然中文很難理解,那么我們從英文入手,看看是否會有什么新的發現。
“接口”英文為“interface”,按照英文的方法將其拆開,其實就是“inter?–?face”,也就是說其包含兩層意思:
**【Inter】:?互相,與互相對應的是單個、多個,為什么這里要強調2個呢?**
首先,“單個”不存在交互,你自己玩自己的,別人管不了,也就沒法交互了;
其次,“多個”交互就混亂了,比如說,假設一個USB接口能夠同時接鼠標和鍵盤,那么怎么知道收到的信號時誰發出的,發出的信號又是要發給誰呢?
?
【Face】:面,與面對應的是點、線,這里為什么要強調“面”呢?
?首先,“面”很形象,圍著你的電腦看一下,USB接口、網絡接口、VGA接口,形狀是不是都是“面”?
其次,“面”體現了功能的多樣性。即:接口包含多個“功能點”,例如:USB接口有輸入功能、輸出功能、充電功能,這三個功能都是USB接口具備的,而不是三個接口。
?
基于上述分析,我們可以給接口下一個清晰和容易理解的定義:接口是一組相關的交互功能點定義的集合。
這個定義的三個關鍵點詳細解析一下:
**【相關】**
接口中包含的功能點是相關的,而不是一堆無關功能的堆砌。
例如USB接口,你見過既支持USB協議、又支持VGA協議、還支持PS/2的接口么?
?
**【交互】**
接口是用于不同物體交互,如果只是自己玩,那么就不能成為接口;
?
**【定義】**
接口中的功能點只是定義,并不涉及具體實現。
也就是說,接口是一個交互協議,是交互雙方的一個約定,但具體如何實現,由具體的交互實體各自實現即可。
就像USB接口,張三可以接鼠標、李四可以接鍵盤、王五可以接散熱風扇,但無論是鼠標、鍵盤還是風扇,都必須遵循USB接口的協議標準。
?
**【集合】**
接口是多個功能點的集合,而不是一個具體的功能點。
?
但如果你說要我重新將interface翻譯成簡單易理解的中文,恕我才能不夠,我也沒法翻譯。
?
回過頭來看本章前面提到的關于接口的不同說法:
有的人說:兄弟,給我提供一個“查詢XXX”的接口——這里說的是一個功能
有的人說:系統對外提供了“查詢”、“插入”、“更新”、“刪除”4個接口——這里說的是多個功能,這些功能合起來才是一個完整的接口
有的人說:我們要基于“接口”編程——這個符合接口的定義
有的人說:你這樣做破壞了我們的接口設計——這個可能符合接口的定義,也可能不符合,關鍵看這里的接口是指某個功能還是一組功能。
?
Java語言中的接口很好的展現了接口的含義:
IAnimal.java
~~~
package com.oo.demo;
public interface IAnimal {
/*
* Java的Interface很好的體現了我們前面分析的接口的特征:
* 1)是一組功能的集合,而不是一個功能
* 2)接口的功能用于交互,所有的功能都是public,即別的對象可操作
* 3)接口只定義函數,但不涉及函數實現
* 4)這些功能是相關的,都是動物相關的功能,但光合作用就不適宜放到IAnimal里面了
*/
public void eat();
public void run();
public void sleep();
public void speak();
}
~~~
Pig.java
~~~
package com.oo.demo;
/**
* “豬”的類設計,實現了IAnnimal接口
*
*/
public class Pig implements IAnimal{
//如下每個函數都需要詳細實現
public void eat(){
System.out.println("Pig like to eat grass");
}
public void run(){
System.out.println("Pig run: front legs, back legs");
}
public void sleep(){
System.out.println("Pig sleep 16 hours every day");
}
public void speak(){
System.out.println("Pig can not speak");
}
}
~~~
Person2.java
~~~
package com.oo.demo;
/**
* 實現了IAnimal的“人”,有幾點說明一下:
* 1)同樣都實現了IAnimal的接口,但“人”和“豬”的實現不一樣,
* 為了避免太多代碼導致影響閱讀,這里的代碼簡化成一行,但輸出的內容不一樣,
* 實際項目中同一接口的同一功能點,不同的類實現完全不一樣
* 2)這里同樣是“人”這個類,但和前面介紹類時給的類“Person”完全不一樣,
* 這是因為同樣的邏輯概念,在不同的應用場景下,具備的屬性和功能是完全不一樣的
*
*/
public class Person2 implements IAnimal {
public void eat(){
System.out.println("Person like to eat meat");
}
public void run(){
System.out.println("Person run: left leg, right leg");
}
public void sleep(){
System.out.println("Person sleep 8 hours every dat");
}
@Override
public void speak(){
System.out.println("Hellow world, I am a person");
}
}
~~~
Tester03.java
~~~
package com.oo.demo;
/**
* @author liyunhua
*
*/
public class Tester03 {
public static void main(String[] args) {
System.out.println("===This is a person===");
IAnimal person = new Person2();
person.eat();
person.run();
person.sleep();
person.speak();
System.out.println("\n===This is a pig===");
IAnimal pig = new Pig();
pig.eat();
pig.run();
pig.sleep();
pig.speak();
}
}
~~~
有了類之后為什么還要有接口呢?我直接用類不行么?
例如,我想操作人的時候就用Person,我想操作豬的時候就用Pig
?
大部分情況下這樣做是可以的,但有的時候,你可能并不知道你面對的是一個人還是一頭豬,因為這個動物可能是別人創建的,或者是上帝創建的。你只知道這是個動物,但你又希望這個動物按照你的要求進行活動。這就是接口的用處所在,即:你不知道一個對象所屬的具體“類”,只知道這些對象都具備某種功能
- 前言
- (1) - 程序設計思想的發展
- (2) - 面向對象語言發展歷史
- (3) - 面向過程 vs 面向對象
- (4) - 面向對象是瑞士軍刀還是一把錘子?
- (5) - 面向對象迷思:面向對象導致性能下降?
- (6) - 不要說你懂“類”
- (7) - “對象”新解
- (8) - “接口” 詳解
- (9) - “抽象類” 詳解
- (10) - “抽象” 詳解
- (11) - “封裝” 詳解
- (12) - “繼承” 詳解
- (13) - “多態” 詳解
- (14) - 面向對象開發技術流程
- (15) - 需求詳解
- (16) - 需求分析終極目的
- (17) - 需求分析518方法
- (18) - 用例分析
- (19) - 功能點提取
- (20) - 用例圖的陷阱
- (21) - SSD
- (22) - 領域模型
- (23) - 領域建模三字經
- (24) - 設計模型
- (25) - 類模型
- (26) - 類模型三板斧
- (27) - 動態模型設計
- (28) - 設計原則:內聚&耦合
- (29) - 高內聚低耦合
- (30) - SRP原則
- (31) - OCP原則
- (32) - LSP原則
- (33) - ISP原則
- (34) - DIP原則
- (35) - NOP原則
- (36) - 設計原則如何用?
- (37) - 設計模式:瑞士軍刀 or 錘子?
- (38) - 設計模式之道
- (39) - 設計原則 vs 設計模式
- (40) - DECORATOR模式
- (完)- 書籍已經出版