当涉及内部类时,Java继承是如何工作的
当存在内部类时,我很难理解继承在Java中是如何工作的。我目前正在做一些事情,其中子类需要稍微更改其父类的内部类的功能。我在下面给出了一个更简单的例子 我希望这段代码可以打印“我是一个ChildClass.InnerClass”,但它会打印 “我是一个父类。内类”。为什么会这样?另外,如果我在main中更改obj对象 如果是ChildClass类型,则输出更改为“我是一个ChildClass.InnerClass”。为什么会这样 一般来说,改变对象父类内部对象行为的推荐方法是什么当涉及内部类时,Java继承是如何工作的,java,inheritance,polymorphism,inner-classes,Java,Inheritance,Polymorphism,Inner Classes,当存在内部类时,我很难理解继承在Java中是如何工作的。我目前正在做一些事情,其中子类需要稍微更改其父类的内部类的功能。我在下面给出了一个更简单的例子 我希望这段代码可以打印“我是一个ChildClass.InnerClass”,但它会打印 “我是一个父类。内类”。为什么会这样?另外,如果我在main中更改obj对象 如果是ChildClass类型,则输出更改为“我是一个ChildClass.InnerClass”。为什么会这样 一般来说,改变对象父类内部对象行为的推荐方法是什么 class I
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
是子对象的一个,但这不是因为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
及
一般来说,建议用什么方法来改变用户的行为
对象的父类的内部对象
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();
}
}
我建议首先使用不太复杂的设计。子类应该通过重写其方法来修改其父类的行为,因此我只需添加一些工厂方法newInnerClass()
来重写此依赖项的创建,并在类层次结构的顶部管理此对象
这将比您建议的更灵活,因为只要有正确的接口,newInnerClass()
就可以实例化在任何地方定义的类//obj.x表示子对象中的x
??你是指儿童班obj;如果第二个InnerClass
扩展了ParentClass.InnerClass
,那么它的构造函数将调用ParentClass
构造函数。从而用ParentClass的InnerClass隐藏子类的InnerClass