java 涉及内部类时Java继承如何工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13040650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does Java inheritance work when inner classes are involved
提问by martega
I am having trouble understanding how inheritance works in Java when inner classes are present. I'm currently working on something where a child class needs to slightly change the functionality of the inner class of it's parent. I've come up with an simpler, analagous example below.
当存在内部类时,我无法理解继承在 Java 中的工作原理。我目前正在研究子类需要稍微改变其父类的内部类的功能的事情。我在下面想出了一个更简单的类似例子。
I expected this code to print "I am a ChildClass.InnerClass" but instead it prints "I am a ParentClass.InnerClass". Why is this? Also, if I change the obj object in main to be of type ChildClass then the output changes to "I am a ChildClass.InnerClass". Why is this?
我希望此代码打印“我是 ChildClass.InnerClass”,但它打印“我是 ParentClass.InnerClass”。为什么是这样?此外,如果我将 main 中的 obj 对象更改为 ChildClass 类型,那么输出将更改为“我是 ChildClass.InnerClass”。为什么是这样?
In general, what is the recommended way of altering the behavior of an object's parent class's inner object?
一般来说,改变对象的父类的内部对象的行为的推荐方法是什么?
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();
}
}
采纳答案by Mik378
Variable are not "overriden" as methods are.
变量不像方法那样被“覆盖”。
In your call, you expected x
to be the Child
's one but it isn't because x
is a variable, not a method.
在您的调用中,您希望x
成为Child
's ,但它不是,因为x
是变量,而不是方法。
But pay attention: Your reference type is ParentClass
so obj.x
points to the ParentClass
's InnerClass
attribute even though the real instance behind parentClass
is a ChildClass
!
但要注意:你的引用类型是ParentClass
这样obj.x
指向ParentClass
的InnerClass
属性,即使真正的实例背后parentClass
是一个ChildClass
!
In order to display your expected sentence, you have to change the type reference to ChildClass
:
为了显示您预期的句子,您必须将类型引用更改为ChildClass
:
public static void main(String[] args) {
ChildClass obj = (new InnerClassTest()).new ChildClass();
obj.x.speak();
}
To better understand the concept, try to define a method in both ParentClass
and ChildClass
classes:
为了更好地理解这个概念,尝试在ParentClass
和ChildClass
类中定义一个方法:
public InnerClass getInnerClass(){
return x;
}
and make x
private.
并设为x
私有。
so that "override concept" applies.
因此“覆盖概念”适用。
Your final call would be in this case:
在这种情况下,您的最终调用将是:
ParentClass obj = (new InnerClassTest()).new ChildClass();
obj.getInnerClass().speak();
To alter the behavior of the inner classes, think of Template methodpattern or better: Strategy pattern(since more respectful of DIP)
要改变内部类的行为,请考虑模板方法模式或更好的:策略模式(因为更尊重 DIP)
回答by Bhesh Gurung
Remove the redeclaration
删除重新声明
InnerClass x;
from the child class. So, that you will have only one x
and will be reassigned in the constructor of the child class. Which means one x
(refering to the object created in child ctor).
从儿童班。因此,您将只有一个x
,并将在子类的构造函数中重新分配。这意味着一个x
(指的是在子 ctor 中创建的对象)。
It's hiding the one in the parent class. Which is why you end up having two fields, refering to two different objects. And due to static (compile-time or early) binding in case of variables,
它隐藏在父类中的那个。这就是为什么你最终有两个字段,引用两个不同的对象。并且由于变量的静态(编译时或早期)绑定,
ParentClass obj;
//obj.x means the x in parent
and
和
ChildClass obj;
//obj.x means the x in child
回答by millimoose
In general, what is the recommended way of altering the behavior of an object's parent class's inner object?
一般来说,改变对象的父类的内部对象的行为的推荐方法是什么?
I'd recommend using a less convoluted design to begin with. A child class should modify the behaviour of its parent by overriding its methods, so I'd just add some factory method newInnerClass()
to override the creation of this dependency, and manage this object at the top of the class hierarchy.
我建议首先使用不太复杂的设计。子类应该通过覆盖其方法来修改其父类的行为,因此我只需添加一些工厂方法newInnerClass()
来覆盖此依赖项的创建,并在类层次结构的顶部管理此对象。
This would be more flexible than what you propose, because newInnerClass()
could instantiate a class that's defined wherever as long as it has the right interface.
这将比您建议的更灵活,因为newInnerClass()
只要它具有正确的接口,就可以实例化在任何地方定义的类。