# Generic
## introduction
假設我們有:
```java=
class IntegerCoordinate {
public Integer x;
public Integer y;
public IntegerCoordinate(Integer x,Integer y) {
this.x = x;
this.y = y;
}
}
class FloatCoordinate {
public Float x;
public Float y;
public FloatCoordinate(Float x,Float y) {
this.x = x;
this.y = y;
}
}
```
假設我們兩個class的成員幾乎相似,但只有物件Type不同
我們可以寫成
```java=
class Coordinate {
public Object x;
public Object y;
public Coordinate(Object x,Object y) {
this.x = x;
this.y = y;
}
}
```
並且使用:
```java=
public class Main {
public static void main(String[] args) {
Coordinate c = new Coordinate(10,20);
Integer i = (Integer) c.x;
}
}
```
但假設你記錯了呢? 你放入的是浮點數
```java=
public class Main {
public static void main(String[] args) {
Coordinate c = new Coordinate(10.5,20.5);
Integer i = (Integer) c.x; //出錯
}
}
```
## implementation
所以我們可以把
```java=
class Coordinate {
public Object x;
public Object y;
public Coordinate(Object x,Object y) {
this.x = x;
this.y = y;
}
}
```
內的"Object" 全部改成一個自訂的名稱,通常叫做T (Type)
並且在className後面寫```<T>```來表示T是我們的泛型代號
如果有多個,可以用<T,T2,T3...>表示
Key,Value通常使用<K,V>
Element通常使用<E>
```java=
class Coordinate<T> {
private T x;
private T y;
public Coordinate(T x,T y) {
this.x = x;
this.y = y;
}
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
}
```
使用時,把後面的```T```取代成你要的Type(不能是primitive)
```java=
public static void main(String[] args) {
Coordinate<Integer> c = new Coordinate<>(10,20);
c.setX(30);
Integer i = c.getX(); //30
}
```
如果想要限定某泛型只能是某類別的子類別
可以寫說```T extends AnotherClass```
像是
```java=
class Test<T extends Anotherclass> {
//...
}
```
還有另一種是界定父類別的:
```java=
class Test<T super Anotherclass> {
//...
}
```
Static Method:
```java=
public static <T> void aStaticMethod(T t) {
System.out.println(t.getClass().getName() +" "+t);
}
```
## Wildcard
```<?>```可以用來表示任意泛型
但是這代表不確定這個泛型的類別
如果對她進行某特定類別操作 會無法編譯
像這裡, 我不知道Coordinate<E>的E是什麼類別,所以我打個``?``
但是底下又用了Integer
```java=
Coordinate<?> c = new Coordinate<>(10,20);
c.setX(30); //error
Integer i = c.getX(); //error
```
以下範例就沒問題:
```java=
public static void main(String[] args) {
Coordinate<?> c = new Coordinate<>(10,20);
printCoordinate(c);
Coordinate<Double> c2 = new Coordinate<>(30.5,40.5);
printCoordinate(c2);
}
public static <T> void printCoordinate(Coordinate<?> t) {
System.out.println(t.getX()+" "+t.getY());
}
```