※ 引述《oldhead1029 (想不到)》之銘言:
: 最近也在看Generic,實在有點搞不懂Generic的真正功用在那?
: 以Map來說好了,如果程式是我們自己寫的,我們一定會知道
: 裡面放的是什麼型別....
: 如果使用泛型(覺得名字怪怪的,反而違反「泛」字..純自己的想法)
: 放了別的型別的物件也是會錯,跟我們在一般的取Map裡的物件轉型錯
: 一樣意思不是嗎?而且相同物件不是反而限制了Map這類collection的
: 功用嗎?
: 有沒有大大可以舉個在工作上寫程式會用到的例子呢?
: 謝謝!
考慮介面和共同的父類別
public AbstractCollection<Component> getComponents() {...}
這樣寫的話,只要是 Component 的子類別都可以加入這個容器
public Map<String, Runnable> getMap() {...}
這個 Map 的 Key 型態必須是字串; Value 型態則必須實作 Runnable 介面
這樣來看的話, Generic 並沒有真的限制了容器的功用
反而加強了語法的結構,試想以後再也不用刻意為了一個未知的型態做強制轉型
例如:
AbstractCollection collection = new Vector();
String result = (String) collection.iterator().next();
^^^^^^^^
過去在這邊都得加上強制轉型
但是一旦有了 Generic 之後,強制轉型的工作就可以省下了
例如:
AbstractCollection<String> collection = new Vector<String>();
String result = collection.iterator().next();
^
不再需要強制轉型了
再說,針對介面寫程式,本來就是 OO 設計師的守則之一
在 Map<K, V> 的括號(?)裡填入適當的 Interface ,才能讓 Generic 的優點充分發揮
試想一個專案中有許多相似的類別,並且實作同一個 Interface
在容器中取出這些物件時,我們不用理會它是哪一個子類別的實體
只要藉由多型的優點,針對它的介面去操作就可以了
例如:
public static void main(String argv[]) {
AbstractCollection<Runnable> collection = new Vector<Runnable>();
collection.add(new PrintA());
collection.add(new PrintB());
collection.iterator().next().run();
}
class PrintA implements Runnable {
public void run() {
System.out.println("A");
}
}
class PrintB implements Runnable {
public void run() {
System.out.println("B");
}
}
一般的程式並不會像這個例子這麼做作
在實務上,當你發現加入容器的型態都實作某個介面或父類別時 (通常都是如此)
就可以開始考慮是否有必要在容器加上 <E> 這樣的 Generic
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.115.205.85