一、栗子
public class GenericityInher { //error: Type mismatch: cannot convert from ArrayList<Child> to ArrayList<Parent> public ArrayList<Parent> list(){ return new ArrayList<Child>(); } //right public Parent inher(){ return new Child(); } //ERROE: Type mismatch: cannot convert from Parent to Human
public Human hum(){
return new Parent();
}
}class Human{}
class Parent{}class Child extends Parent{}
期望:因為Parent是Child的父類,所以List<Parent>是List<Child>的父類。所以list()方法能正確返回;
結果:看IDE給出的錯誤,明確的說明是”ArrayList<Child>無法轉換成ArrayList<Parent>”,並不是“Parent無法轉換成Child”。
解決方式一:
public ArrayList<? extends Parent> listChild(){ return new ArrayList<Child>(); }
此方式關鍵問題:因為用的是?,所以導致此方法返回的list只可讀,不可寫。(具體原因可以去baidu/google)
解決方式二:
public <T extends Parent> ArrayList<T> listChild(){ return (ArrayList<T>) new ArrayList<Child>(); }
除開需要顯示強制類型轉換外,不知道是否存在別的問題。
二、為什么導致以上問題?
現階段我也只能簡單的說:是java對泛型的定義,導致了以上問題。
所以,牽涉到泛型的都會有這種問題。再如Map
//ERROE: Type mismatch: cannot convert from HashMap<String,Child> to Map<String,Parent>
public Map<String,Parent> map(){ return new HashMap<String, Child>(); }
推薦一篇探討java泛型的文章:Java 理論和實踐: 了解泛型
三、探討:java中private修飾的屬性/方法會被子類“繼承”嗎?
別急着下結論!
結論無非就是: 1、不繼承。 2、繼承,但由於private修飾,並不可用。
雖然不管是哪種結論,“結果”都不會改變(繼承private子類也不能用)。
(1)為什么說“不繼承”?
貌似很多書、博文、回答等,給的答案都是直接的:“被private修飾的屬性/方法不會被子類繼承”。
以下是官方oracle docs jdk1.8原文:(jdk1.7是一樣)
官方文檔給的結果就是:not inherited。
(2)為什么說“繼承”?
雖然官網給的結果是:not inherited。但為什么有些人認為“繼承”呢?
這其實算如何理解“繼承”這個詞語。
正如對“重構”這個詞的理解,什么才算“重構”?
舉個栗子:你寫了一個功能,把excel數據轉換成JavaBean。你balabala的寫完了,在一個方法里面。
寫完后你覺得代碼寫的太難看,你把這1個方法拆成了N個方法。把重復的代碼抽成一個新的方法,把一堆亂七八糟的方法抽成獨立的方法。
總之就是把這一個方法,修改成符合SOLID的N個方法。
那么這能算“重構”嗎? 我個人認為是,這是我對“重構”這個詞的理解。雖然可能與“重構”的原意不一樣。
回過來看繼承,為什么有些人認為private能被子類“繼承”?
因為,子類的內存對象中存在private的屬性!
public class DiscussInheritance { public static void main(String[] args) { Son son = new Son(); System.out.println(son); } }class Father{
public int p_public = 0;
private int p_private = 1;
protected int p_protected = 2;private void pPrivate(){}
public void pPublic(){}
}class Son extends Father{}