閱讀96 返回首頁    go 阿裏雲 go 技術社區[雲棲]


連載:麵向對象葵花寶典:思想、技巧與實踐(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

 

大部分情況下這樣做是可以的,但有的時候,你可能並不知道你麵對的是一個人還是一頭豬,因為這個動物可能是別人創建的,或者是上帝創建的。你隻知道這是個動物,但你又希望這個動物按照你的要求進行活動。這就是接口的用處所在,即:你不知道一個對象所屬的具體“類”,隻知道這些對象都具備某種功能


================================================ 
轉載請注明出處:https://blog.csdn.net/yunhua_lee/article/details/18502531
================================================ 




最後更新:2017-04-03 12:54:38

  上一篇:go 程序猿的新博客開通啦!
  下一篇:go [LeetCode]27.Remove Element