在java代碼中,人們慣性的認為一個方法中只能返回一種返回值或者無返回。博主在做開發過程中碰到了這樣一種情況,安卓客戶端請求數據,后台可能返回兩種結果(1)訪問令牌失效,無數據返回。(2)正常獲取數據。
這樣的情況下需要根據訪問令牌標識來判斷是否有數據返回。當無效時返回用戶重新登錄提示,正常時則返回數據。顯然,返回的結果有兩種,那么一個方法里面只能返回一種類型的禁錮使得開發起來略顯笨拙。使得開發起來相當難受。
思考良久,又結合C++協變返回類型的啟發。摘抄原文中的一句話:在C++中,只要原來的返回類型是指向類的指針或引用,新的返回類型是指向派生類的指針或引用,覆蓋的方法就可以改變返回類型。這樣的類型稱為協變返回類型(Covariant returns type).
因為java里面有沒有指針,所以無法做到以上的功能。但是派生類是包含父類的共有方法和保護方法的。再根據里氏代換原則(任何基類可以出現的地方,子類一定可以出現),那么凡是派生類包含的基類屬性,基類一定包含,這樣的話情況會好很多。那么只要由派生類設置屬性返回到基類中,基類方法一定能操作這些屬性。那么一條完整的可變返回類型就可以建立起來。下面結合代碼來驗證:
首先先定義兩個實體類,代碼如下,
1 class Person { 2 /** 假設每個人都有一個名字 **/ 3 String name; 4 5 public String getName() { 6 return name; 7 } 8 9 public void setName(String name) { 10 this.name = name; 11 } 12 13 }// person 14 15 class SuperMan extends Person { 16 /** 假設每個超人都有身高 **/ 17 int height; 18 19 public int getHeight() { 20 return height; 21 } 22 23 public void setHeight(int height) { 24 this.height = height; 25 } 26 }// SuperMan
SuperMan類繼承Person類(博主當時想不出來什么好東西了- -!),則SuperMan類包含name和height兩個屬性,基類Person只包含name屬性。
先說明一下普通的操作方式,以此作為對比。代碼如下:
1 public static Person getPerson1() { 2 Person person = new Person(); 3 person.setName("無語"); 4 return person; 5 }
1 public static SuperMan getSuperMan1() { 2 SuperMan man = new SuperMan(); 3 man.setName("不知道"); 4 man.setHeight(120); 5 return man; 6 }
很簡單,返回值就是預期的返回類型,但是如果把返回類型替換一下結果如何。如下所示:
1 public static SuperMan getSuperMan() { 2 Person person = new SuperMan(); 3 person.setName("小虎"); 4 return (SuperMan) person; 5 }
以上只能得到Superman的name屬性無法得到height屬性,如果在返回之前強轉以此加上height屬性后返回即可得到一個完整的SuperMan對象。這里不再嘗試,讀者自行處理。
1 public static Person getPerson() { 2 SuperMan man = new SuperMan(); 3 man.setHeight(100); 4 man.setName("大明"); 5 return man; 6 }
以上代碼就是此文章的核心,也是解決文章開頭問題的核心。怎么操作呢?
我們寫兩個類,ErroMessage和DataMessage類,其中ErroMessage是基類,DataMessage繼承基類。ErroMessage包含erroMessage屬性類型為private,DataMessage包含data屬性。那么ErroMessage就只包含erroMessage屬性,操作時只會引起erroMessage的變化,而不會引起data的變化。而操作DataMessage類時只能操作data屬性。而在一個方法中,只要保持方法類型為ErroMessage,返回時就可以根據需要來返回相應的類型。這樣使用方法時,用派生類得到所有屬性,如果子類屬性為空,那么基類屬性一定不為空。如果派生類屬性不為空,那么基類屬性一定為空。這樣就可以按需取得相應的數據。操作起來相當簡單。代碼操作如下:
1 printDivider("person"); 2 Person person = getPerson(); 3 System.out.println("person的名字是" + person.getName()); 4 SuperMan superMan = (SuperMan) person; 5 System.out.println("通過強轉獲取到的超人高度是這樣的" + superMan.getHeight());
以上就是博主對可變返回類型的理解。
其中核心思想是這樣的:派生類可以包含基類的共有屬性,那么基類一定能從派生類獲取到自身暴露給派生類屬性的值。這是一種逆向思維方式,可能有悖於傳統代碼編寫方式,但是做軟件就是應該嘗試打破傳統思維,縱使道路崎嶇不堪。如果有錯誤的話,還望各位讀者提出指正批評意見,共同成長。
最后博主寫了一個小demo,下載地址是:http://download.csdn.net/detail/tianqianya/8321397
下一次則將說明接口的可變返回類型。敬請期待~ ^_^
QQ群號433409373 ->老夫在此等候小伙伴一起學習探討交流~~~共建學習平台