父类引用调用子类私有方法编译失败问题咨询
问题分析与解决办法
咱们先拆解下你这段代码为啥过不了编译:
- 编译阶段的类型检查:Java编译器只认变量的声明类型(这里
d是Dog类型),不管它实际指向的对象是什么。Dog类里根本没有mew()方法,所以直接写d.mew()肯定会触发编译错误。 - private方法的访问限制:就算你知道
d实际指向Cat对象,Cat里的mew()是private的——这种方法只能在Cat类内部调用,外部哪怕拿到Cat对象也没法直接访问它。
下面给你两种针对性的解决思路:
思路一:强制类型转换+调整方法访问权限
如果mew()是Cat特有的行为,那咱们先把Dog引用转成Cat类型,同时要把mew()的访问权限改成public(或者同包下的protected/默认权限):
public class Dog { } public class Cat extends Dog { // 把private改成public,让外部能访问 public void mew() { System.out.println("喵~"); } } // 调用逻辑 Dog d = new Cat(); // 实际对象是Cat // 先判断类型,避免ClassCastException if (d instanceof Cat) { Cat cat = (Cat) d; cat.mew(); // 现在可以正常调用了 }
思路二:在父类定义方法,子类重写
如果希望所有Dog的子类都能实现“叫”的行为,那应该在Dog类里定义这个方法的模板,让Cat去重写:
// 可以把Dog改成抽象类,定义抽象方法 public abstract class Dog { public abstract void mew(); } // 或者给一个空实现,让子类按需重写 // public class Dog { // public void mew() { // // 默认空实现 // } // } public class Cat extends Dog { @Override public void mew() { System.out.println("喵~"); } } // 调用逻辑 Dog d = new Cat(); d.mew(); // 编译通过,运行时会调用Cat的mew()
这样不管编译还是运行阶段都能正常工作,也符合面向对象的多态思想~
内容的提问来源于stack exchange,提问作者Fabian Zbinden
相关产品推荐
相关产品推荐

