java基礎==========泛型(Android)
這一篇將系統的回憶起泛型的知識
在做Android的時候用到泛型的類有很多,很多時候會遇到將資料儲存到一個List集合,Map等等,他們之間使用<>來填寫資料型別,說一個我現在想到的就是Android中非同步載入這個類AsyncTask《Params, Progress, Result》,第一個引數是在execute()中寫入的引數,然後在doInBackgound中中傳入了這個引數,最後返回了Result這個型別值。說了有點多,下面就說一下泛型的知識。
首先來一段簡單的泛型程式碼
格式 :
- <資料型別>
- 此處的資料型別只能是引用型別。
ArrayList<String > array = new ArrayList();
array.add("fat");
array.add("one");
Iterator<String> it = array.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
把泛型定義在類上
格式:public class 類名<泛型型別1,…>
注意:泛型型別必須是引用型別—引用型別就是一個物件型別
泛型類
就是把泛型定義在類上,類中的引數是泛型
public class Test {
//泛型類 --類中使用的引數是泛型
public static class Fat<T>{
private T obj;
public T getObj(){
return obj;
}
public void setObj(T obj){
this.obj = obj;
}
}
public static void main(String[] args) {
Fat<String> fat = new Fat<String>();
fat.setObj("一個胖兒");
System.out.println( fat.getObj());
Fat<Integer> age = new Fat();
age.setObj(22);
System.out.println(age.getObj());
}
}
泛型方法
就是將泛型定義在方法上,此方法就可以傳任意型別的引數,定義泛型方法的格式是
public <T> 方法名 (T t){}
//注意 泛型方法所在的類是個泛型類,因為前面生命的<T>就是泛型類中的泛型
看程式碼
public class Test {
public static class Fat<T>{
private T obj;
public T getObj(){
return obj;
}
public void setObj(T obj){
this.obj = obj;
}
public <T> void show(T obj){
System.out.println(obj);
}
}
public static void main(String[] args) {
Fat<String> fat = new Fat<String>();
fat.setObj("一個胖兒");
// System.out.println( fat.getObj());
fat.show(fat.getObj());
Fat<Integer> age = new Fat();
age.setObj(22);
// System.out.println(age.getObj());
fat.show(age.getObj());
}
}
泛型介面
格式:public interface 介面名<泛型>
看程式碼
//定一個父介面
public interface Finterface <T>{
public void show(T t);
}
//然後定義一個子類來實現這個父類介面
public class Zinterfaceimpl<T> implements Finterface<T>{
@Override
public void show(T t) {
System.out.println(t);
}
//測試
public class Test {
public static void main(String[] args) {
Finterface<Integer> one = new Zinterfaceimpl();
one.show(123);
}
}
//當然實現介面的時候可以確定型別
public class Zinterfaceimpl implements Finterface<String>{
@Override
public void show(String t) {
System.out.println(t);
}
萬用字元–?
- 類< ?>
表示任意型別,如果沒有明確,就是Object以及任意的java類 - ? extends E
向下限定,E及其子類,就是所有繼承了E的類才可以傳入 - ? super E
向上限定,E及其父類,就是所有E的類或者E的父類。
看程式碼好理解一點:
//首先定義了一個A類
public class A<T> {
private T t;
A(){}
A(T t){
this.t = t;
}
public void show(){
System.out.println(t);
}
}
//定一個Fat類
public class Fat {
public void show(){
System.out.println("一個胖兒");
}
}
//測試
public class D {
public static void main(String[] args) {
A<Object> a = new A<Object>();
// A<Object> b = new A<Fat>();報錯 ,必須前後一致
//為了解決這個問題使用萬用字元 ?
A<?> b = new A<Fat>();
//? extends E
A<? extends Fat> c = new A<>();//這個的意思就是限定了傳入繼承Fat或者Fat類的類型別
c.show(); //這裡會輸出一個null 注意這裡呼叫的是A中的show方法
//如果我非要呼叫Fat中的show方法呢?這就要改一下A中的show程式碼
}
}
//修改後的A類show方法 還是得定義一個類的引用,其實這樣我感覺根本就沒體現向下限定
public void show(){
Fat f = (Fat) t;
f.show();
}
關於向上限定和向下限定有什麼用呢?在Android中目前我還沒用過,不過可以限定你傳入物件的型別,必須是你想要物件的子類,或者必須是實現了這個介面的類。比如說
//將Fat定義成介面
public interface Fat {
public void show();
}
//B類
public class B implements Fat{
@Override
public void show() {
}
}
//測試
public class D {
public static void main(String[] args) {
B ccc =new B();
A<? extends Fat> d = new A<B>(ccc);
d.show();
//結果為 one fat
}
}
//注意A類,沒有任何改動,使用Fat介面引用
ublic class A<T> {
private T t;
A(){}
A(T t){
this.t = t;
}
public void show(){
Fat f = (Fat) t;
f.show();
}
}
介面作為引用型別來使用,任何實現該介面的類的例項都可以儲存在該介面型別的變數中,通過這些變數可以訪問類中所實現的介面中的方法,Java 執行時系統會動態地確定應該使用哪個類中的方法,實際上是呼叫相應的實現類的方法。
================================================================================
之後想到新的心得會繼續更新這篇
下面是參考的部落格
https://blog.csdn.net/m366917/article/details/52264728很好的部落格,讓我開始寫部落格的動力也是因為看了博主的文章