当内部类存在时,我无法理解继承在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();
}
}
答案 0 :(得分:8)
变量不会像方法那样“覆盖”。
在通话中,您希望x
成为Child
的一个,但不是因为x
是变量,而不是方法。
但请注意:您的引用类型为ParentClass
,因此obj.x
指向ParentClass
的{{1}}属性,即使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
要改变内部类的行为,请考虑模板方法模式或更好:策略模式(因为更尊重DIP)
答案 1 :(得分:3)
删除重新声明
InnerClass x;
来自儿童班的。因此,您将只有一个x
,并将在子类的构造函数中重新分配。这意味着一个x
(参考在儿童中创建的对象)。
它隐藏了父类中的那个。这就是为什么你最终有两个字段,引用两个不同的对象。并且由于变量情况下的静态(编译时或早期)绑定,
ParentClass obj;
//obj.x means the x in parent
和
ChildClass obj;
//obj.x means the x in child
答案 2 :(得分:1)
一般来说,改变行为的推荐方法是什么? object的父类的内部对象?
我建议首先使用较少复杂的设计。子类应该通过重写其方法来修改其父级的行为,因此我只需添加一些工厂方法newInnerClass()
来覆盖此依赖项的创建,并在类层次结构的顶部管理此对象。
这比你建议的更灵活,因为newInnerClass()
可以实例化一个只要它有正确的接口就定义的类。