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

时间:2012-10-23 23:02:37

标签: java inheritance polymorphism inner-classes

当内部类存在时,我无法理解继承在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();
   }
}

3 个答案:

答案 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()可以实例化一个只要它有正确的接口就定义的类。