泛型(Generic)

在沒使用到泛型之前,有兩個類別擁有相同的功能:
public class IntegerObj {
    private Integer integerObj;
    /**
    * @param {Integer} integerObj
    */
    public void set(Integer integerObj) {
        this.integerObj = integerObj;
    }
    /**
    * @type Integer
    */
    public Integer get() {
        return integerObj;
    }
}
public class StringObj {
    private Integer stringObj;
    /**
    * @param {String} stringObj
    */
    public void set(String stringObj) {
        this.stringObj = stringObj;
    }
    /**
    * @type String
    */
    public String get() {
        return stringObj;
    }
}

以上這兩個class只有member型態上有差異,邏輯上是一模一樣,等於必須對兩種不同型態去各自撰寫一個類別,但同樣的,這些物件的最上層都是繼承Object,可將member成員替換成Object,最後再經由轉型就可以了。但是由於轉型也有轉錯的可能,那麼是不是能在宣告變數時,就先將型態定義好,並且使用同一個class,那麼這時就要使用到泛型了。

以下是個簡單的例子(java):
class CollectionExample<T>{
     private T[] _objects;
     private int _index;
     /**
     *
     */
     CollectionExample(int total){
        _objects =(T[]) new Object[total];
        _index = 0;
     }
     /**
     * @param {T} obj
     */
     public boolean add(T obj){
        boolean result = false;
        if(_index < _objects.length){
            _objects[_index] = obj;
            _index++;
            result = true;
        }
            return result;
     }
     /**
     * @param {int} index
     * @type T
     */
     public T get(int index){
          return _objects[index];
     }
     /**
     * @type int
     */
     public int getLength(){
          return _objects.length;
     }
     /**
     *
     */
     public static void main(String[] args){
      CollectionExample<Integer> collection = new CollectionExample<Integer>(10);
        //
            for(int i=1;i<=collection.getLength();i++)
                collection.add(i);
            for(int i=0;i<collection.getLength();i++)
                System.out.println(collection.get(i));
     }
}

<T>主要是來定義泛型用,T為變數名稱,換句話說他可以是其它文字,最主要用處是拿來替換型態用,例如當你宣告:
//
CollectionExample<Integer> collection = new CollectionExample<Integer>(5);
上面class的變數T,將會取代成Integer。CollectionExample類別提供了add、get和getLength三個method,主要功能是將object儲存起來以及取出。
 
###### 以下是C++的範例: CollectionExample.h
template <class CType>
class CollectionExample{
//
public:
    CollectionExample(int);
    ~CollectionExample();
    void add(CType);
    int getLength();
    CType get(int);
private:
    CType *_objs;
    int _index;
    int _length;
};
/**
* @param {int} total
*/
template <class CType>
CollectionExample<CType>::CollectionExample(int total){
    _objs = new CType[total];
    _length = total;
    _index = 0;
}
/**
*
*/
template <class CType>
CollectionExample<CType>::~CollectionExample() {
    delete [] _objs;
}
/**
* @param {CType} obj 
*/
template <class CType>
void CollectionExample<CType>::add(CType obj){
    if(_index<_length){
        _objs[_index] = obj;
        _index++;
    }
}
/***
* @param {int} index
* @type CType
*/
template <class CType>
CType CollectionExample<CType>::get(int index){
    if(index<_length)
        return _objs[index];
}
/**
* @type int
*/
template <class CType>
int CollectionExample<CType>::getLength(){
    return _length;
}

main.cpp

#include <iostream> 
#include "CollectionExample.h"
using namespace std; 

int main(){
    CollectionExample<int> collection(10);

       for(int i=0;i<collection.getLength();i++)
           collection.add(i);
       for(int i=0;i<collection.getLength();i++)
           cout<<collection.get(i)<<endl;
    return 0;
} 

結果與java相同。