1. 程式人生 > >java基礎==========泛型(Android)

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很好的部落格,讓我開始寫部落格的動力也是因為看了博主的文章
這裡寫圖片描述