Can't access protected inner class while inheriting

放肆的年华 提交于 2019-11-30 08:54:05

The error message is complaining about the constructor being protected, not the class. But you haven't explicitly defined a constructor in the code you posted. In this case, according to the JLS, the default constructor will be protected (the same as the class).

You need to define a public constructor for the Inner class:

public class COne {

    protected class Inner implements IOne{

        public Inner() { }

        public void f(){System.out.println("Inner class of COne");}
    }
}

That is clear. But here is a really weird thing.

According to the JLS if CTwo extends COne.Inner it is expected to access Inner's protected constructor, but in practice it does not... See below.

package p1;
public class COne {
    public static class Inner {
        protected Inner() {}
    }
}

package p2;
public class CTwo extends COne.Inner {
    public void getIface() {
        new COne.Inner();
        // Compile time error anyway with the same complains:
        // "Inner() has protected access in p1.COne.Inner"
        // ...unlike my expectations...
    }
}  

The problem is not about the Inner class but Inheritance.

Let do some experiments.

First Inner and Outer class both have full access to each other. So the following code works well.

package com.ciaoshen.packA;

public class Outer {
        protected class Inner {
            public void foo() { System.out.println("Hello Ronald!"); }
        }
        protected Inner inner() {
            return new Inner();
        }
        public static void main(String[] args) {
            new Outer().inner().foo(); // Output: Hello Ronald!
        }
}

Now in another package, DerivedOuter is derived from Outer. DerivedOuter calls inner()method inherited from Outerclass. It still works!

package com.ciaoshen.packB;

class DerivedOuter extends Outer {
    public static void main(String[] args) {
        new DerivedOuter().inner().foo(); // Output: Hello Ronald!
    }
}

But when I Override the inner() method in DerivedOuter class, the same Error occurs!

package com.ciaoshen.packB;

class DerivedOuter extends Outer {
    @Override
    public Inner inner() { // this is not the inner() of Outer class. BOOM!
        return new Inner();
    }
    public static void main(String[] args) {
        new DerivedOuter().inner().foo(); // ERROR: Outer.Inner() has protected access in Outer.Inner
    }
}

Conclusion, the protected Inner constructor is only accessible within the original Outer class scope. Any additional method (ex: your getInner() method) has no access to protected Inner constructor.

The key point is that when DerivedOuter inherit from a Outer, you can imagine that DerivedClass IS-A Outer, and it contains an Inner class inside as his member. But in fact, DerivedOuter has no direct access to Inner class but only works by using his super class Outer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!