【daily】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 理论和实践: 了解泛型

posted @ 2017-01-25 15:57  淡丶无欲  阅读(6430)  评论(0编辑  收藏  举报