Java泛型 - 返回父類的子類


一、栗子

復制代碼
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是一樣)

    image

    官方文檔給的結果就是: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{}

復制代碼

image

   

附錄:

  A是B的子類,為什么List<A>就不是List<B>的子類?

  oracle docs jdk1.8

  Java 理論和實踐: 了解泛型

原文地址:https://www.cnblogs.com/VergiLyn/p/6349601.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM