Java:无法访问外部类子类中嵌套类子类的受保护方法



我正在分解一个类以重复使用,不同的信息隐藏实现等。

是:

public class Outer
{
    public static class Inner
    {
        // ...
        protected static void innerDoSomething()
        {
            // ...
        }
    }
    public outerDoSomething()
    {
        //...   
        Inner.innerDoSomething();
        //...
    }
}

,一切都很好,因为允许外部类访问嵌套内类的受保护成员。

但试图这样分解:

public class SuperOuter
{
    public static class SuperInner
    {
        // ...
        protected static void innerDoSomething()
        {
            // ...
        }
    }
    // ...
}
public class SubOuter extends SuperOuter
{
    public static class SubInner extends SuperInner
    {
        // ...
        protected static void innerDoSomethingElse()
        {
            // ...
        }
    }
    public outerDoSomething()
    {
        //...   
        SubInner.innerDoSomethingElse(); // OK
        SubInner.innerDoSomething();     // Error: cannnot access!
        //...
    }
}

InnerDosomething()也无法访问,即使SubInner的受保护成员可以通过Subouter访问,并且所有受保护的超级网络成员均应是SubInner受保护界面的一部分。

使它起作用的唯一方法似乎是为每种方法添加明确的委托,例如:

    public static class SubInner extends SuperInner
    {
        // ...
        protected static void innerDoSomethingElse()
        {
            // ...
        }
        protected static void innerDoSomething()
        {
            SuperInner.innerDoSomething();
        }
    }

这很烦人,容易出错且浪费时间。我很想将Innerdosomething()称为公开,但这并不是正确的,因为它只能由Subouter及其子类别使用。

怎么来?不应该对InnerDosothing()受保护的访问权限,并不应该由subouter访问?

无法通过变量参考从不同的软件包访问受保护的方法。如果两个类别和subouter都在同一包中,则将工作。

好吧,我想我四处走动,小心地重新阅读了gosling的 java编程语言,第4 ed ed

  1. superouter和subouter在逻辑上应该使用的是不同的软件包,因此有没有毯子全包受保护的成员可访问性。

  2. 访问嵌套类的受保护成员的访问实际上是作为外在和嵌套类之间的特殊访问手段(请参阅第5章。>)

  3. 然而,受保护的成员可访问性不仅是transitive :与nested/ofter Grant不同,您需要在子类中,并且至少有一个参考该子类的类型(即至少subxxx,superxxx还不够),因为,我引用了段落 3.5。受保护的是真正的含义

每个子类继承超级类的合同,并扩展 以某种方式收缩。假设一个子类,作为其中的一部分 扩大合同,对受保护价值的限制放在限制 超级阶级的成员。如果其他子类可以访问 第一个子类的受保护成员可以 操纵它们的方式会破坏第一个子类 合同,不应允许。

因此,即使在我的情况下,xxxinner在逻辑上是XXXOUTER的一部分,并且Subouter扩展了超级图,因此前者在逻辑上应该能够访问后者的任何受保护的成员,但仍然无法访问Supouter在Superouter中的超级领导者的受保护成员只要它收到了一个超级网络作为参数的参数,就不会以相同的方式,因为该参数可能属于完全不同的层次结构ramification 。在这种情况下,该语言没有具体规定。

这也解释了为什么显式委派有效的原因:Subouter可以访问SubInner的受保护成员,因为外部/嵌套授予和SubInner由于扩展而可以访问超级领导者的受保护成员,但是SubOuter无法访问超级领导者的受保护成员,因为后者是后者实际上,可以属于不同的层次结构,使连接是SubInner的工作。

明确的委托尊重上述所有内容,逻辑上和语言定义,因此考虑到适当的访问,它应该是"正确"的方法,但是由于冗余而容易出错(如果我调用超级器,则该实现都是错误的。InnerDosomethingElse()subinner.innerdosomething()?)

最终:例如,我可以使用一些Python脚本来自动化明确的委托(例如(我确实是为了自动创建构建器模式,具有相似的冗余弱点),或者简单地放弃访问控制的附加安全性并使受保护的成员使受保护的成员公共。

最新更新