[英]How does Java inheritance work when inner classes are involved
当存在内部类时,我很难理解继承在Java中的工作方式。 我目前正在研究子类需要稍微更改其父类内部类功能的东西。 我在下面提出了一个更简单,类似的示例。
我希望此代码可以打印“我是ChildClass.InnerClass”,但可以打印“我是ParentClass.InnerClass”。 为什么是这样? 另外,如果我将main中的obj对象更改为ChildClass类型,则输出更改为“我是ChildClass.InnerClass”。 为什么是这样?
通常,建议的改变对象父类内部对象行为的方法是什么?
class InnerClassTest {
//-----------------------------------------------------------------------
// PARENT CLASS
class ParentClass {
public ParentClass() {
x = new InnerClass();
}
InnerClass x;
class InnerClass {
public void speak() {
System.out.println("I am a ParentClass.InnerClass");
}
}
}
//-----------------------------------------------------------------------
// CHILD CLASS
class ChildClass extends ParentClass {
public ChildClass() {
x = new InnerClass();
}
InnerClass x;
class InnerClass extends ParentClass.InnerClass {
public void speak() {
System.out.println("I am a ChildClass.InnerClass");
}
}
}
//-----------------------------------------------------------------------
// MAIN
public static void main(String[] args) {
ParentClass obj = (new InnerClassTest()).new ChildClass();
obj.x.speak();
}
}
变量不像方法那样“被覆盖”。
在您的通话中,您希望x
是Child
但这不是因为x
是变量,而不是方法。
但请注意:您的引用类型是ParentClass
因此obj.x
指向ParentClass
的InnerClass
属性,即使parentClass
背后的实际实例是ChildClass
!
为了显示您期望的句子,您必须将类型引用更改为ChildClass
:
public static void main(String[] args) {
ChildClass obj = (new InnerClassTest()).new ChildClass();
obj.x.speak();
}
为了更好地理解该概念,请尝试在ParentClass
和ChildClass
类中都定义一个方法:
public InnerClass getInnerClass(){
return x;
}
并将x
私有。
因此,“替代概念”适用。
在这种情况下,您的最终通话是:
ParentClass obj = (new InnerClassTest()).new ChildClass();
obj.getInnerClass().speak();
要更改内部类的行为,请考虑使用模板方法模式或更好的方法 : 策略模式 (因为更加尊重DIP)
删除重新声明
InnerClass x;
来自儿童班。 因此,您只有一个x
并且将在子类的构造函数中重新分配。 表示一个x
(指的是在子ctor中创建的对象)。
它在父类中隐藏了一个。 这就是为什么您最终拥有两个字段,分别引用两个不同的对象的原因。 由于存在变量的静态(编译时或早期)绑定,
ParentClass obj;
//obj.x means the x in parent
和
ChildClass obj;
//obj.x means the x in child
通常,建议的改变对象父类内部对象行为的方法是什么?
我建议一开始就使用较简单的设计。 子类应该通过覆盖其方法来修改其父类的行为,因此我只需添加一些工厂方法newInnerClass()
即可覆盖此依赖项的创建,并在类层次结构的顶部管理该对象。
这将比您建议的方法更加灵活,因为newInnerClass()
可以实例化定义在任何地方的类,只要它具有正确的接口即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.