如何从 Child class 中访问 Parent class 中的内部 class?

How can I access a inner class in a Parent class from within a Child class?

亲爱的,

我有一个 Parent 和 Child class:

public class Parent{

    protected class Inner{
    
    }
}

public class Child extends Parent{

    protected class Inner{
    
    }
}

我想在 parent 中使用 Child classes:

myMethod(Inner inner)

将内部 class 设置为保护足以实现此目的吗?

没有,

您需要像这样扩展 Child class 中的内部 class:

public class Child extends Parent{

    protected class Inner extends Parent.Inner{

这样你的 myMethod(Inner inner) 就会将 Child class 识别为 Parent.Inner class 的 children。否则 Child class 的 Inner 将不是 Parent.Inner 类型(并且不会被识别为 class 的子 class(或者可能用同样的方法))。

在您提供的代码中,名为 Inner 的两个 class 是完全、完全不相关的。你只是..有两个 classes 碰巧同名。就像 java.awt.Listjava.util.List:是的,同名,但是就等价性(它们与枪支和祖母一样不同)和访问规则(访问规则就是它们的含义)而言,这根本没有任何意义; 他们共用一个名字与它无关)。

要命名为'properly',可以写Child.InnerParent.Inner来区分它们。仅仅写 Inner 将被 javac 解释为一个或另一个取决于导入和上下文(在 Child extends Parent {} 附带的大括号内,它被解释为 Child.Inner 因为它们是相同的-file sibling,除非你有明确的导入;大多数其他地方它要么不会编译,要么被解释为 Parent.Inner)。鉴于这些规则有些深奥,最好的办法是在这种情况下不要只写 Inner,并且始终要明确。 “但更短的代码”是一个很好的经验法则,但之所以称为经验法则,是因为它们并不总是正确的。不然就叫“规矩”,不用大拇指了。

但是,在这样做之前,为什么您首先在同一个项目中有 2 个不相关的同名 class?即使每个人都写出全名来避免混淆,这也会让人感到困惑。

你的实际意图是什么?

我希望Child.Inner成为Parent.Inner的子class,镜像ChildParent的关系

然后这样写:

public class Child extends Parent {
  public class Inner extends Parent.Inner {}
}

我仍然会强烈考虑在这里选择不同的名称。也许 public class ChildInner - 显然 Inner 在这里只是一个占位符名称,而不是您项目中的真正名称,因此我无法就选择什么名称提供太多建议。只是 'same name' 是个坏主意。

您的 Child.Inner 有一个 Child 的隐藏命名实例可用,它是一种更具体的 Parent,它本身也是一种更具体的 Parent.Inner,意思是 4 个 class 中的任何一个方法 都可用。如果 ParentChild 有一个名为 x() 的方法并且 Parent.InnerChild.Inner 也有一个名为 x() 的方法,则可以使用此语法进行区分:

Child.this.x();

但是,再说一遍,你为什么会多次使用相同的名称来混淆这样的事情?

我只希望 Child 中的代码能够访问 Parent.Inner 中的方法和字段。

然后 not 做第二个 class,你的意图显然不是首先有 2 个内部 classes。 Child 的每个实例都是一种更具体的 Parent,因此您可以创建 Parent.Inner 的新实例,其 'enclosing instance' 实际上是 Child 的实例,没问题。

Child.java中:

Inner inner = new Inner();

除此之外:

Parent.Inner inner = someInstanceOfChild.new Parent.Inner();

自然地,因为 Parent's Inner 中的代码不知道封闭 class 的实例是专门用 new Parent() 制作的实例还是更具体类型的实例,例如new Child(),不能调用仅存在于Child中的方法,但可以instanceof并转换你的外层this实例:

if (Parent.this instanceof Child) {
    Child c = (Child) Parent.this;
    c.methodOnlyInChild();
}

工作正常。