繁体   English   中英

涉及内部类时,Java继承如何工作

[英]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();
   }
}

变量不像方法那样“被覆盖”。

在您的通话中,您希望xChild但这不是因为x是变量,而不是方法。

但请注意:您的引用类型是ParentClass因此obj.x指向ParentClassInnerClass属性,即使parentClass背后的实际实例是ChildClass

为了显示您期望的句子,您必须将类型引用更改为ChildClass

public static void main(String[] args) {
      ChildClass obj = (new InnerClassTest()).new ChildClass();
      obj.x.speak();
}

为了更好地理解该概念,请尝试在ParentClassChildClass类中都定义一个方法:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM