一、栗子
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{}