inheritance时无法访问受保护的内部类
通过“Thinking in Java”阅读我坚持使用ex:6 of Inner Classes章节。
练习6:(2)在自己的包中创建一个至少包含一个方法的接口。 在单独的包中创建一个类。 添加一个实现该接口的受保护内部类。 在第三个包中,inheritance自您的类,并在方法内部返回受保护内部类的对象,在返回期间向上转换为接口。
这是我的代码:
IOne.java
接口
package intfpack; public interface IOne{ void f(); }
COne.java
具有实现接口的受保护内部类的类
package classpack; import intfpack.*; public class COne{ protected class Inner implements IOne{ public void f(){System.out.println("Inner class of COne");} } }
CTwo.java
从具有受保护内部类的类inheritance
package thirdpack; import classpack.*; import intfpack.*; public class CTwo extends COne{ public IOne getInner(){ IOne io = new Inner(); return io; } public static void main(String[] args){ CTwo ct = new CTwo(); ct.getInner(); } }
Copmiler说下:
javac CTwo.java CTwo.java:9: Inner() has protected access in classpack.COne.Inner IOne io = new Inner(); ^ 1 error
但是这本书说我可以在派生类中访问受保护的内部类。 哪里出错?
错误消息抱怨受保护的构造函数,而不是类。 但是您没有在发布的代码中明确定义构造函数。 在这种情况下, 根据JLS ,默认构造函数将受到保护(与类相同)。
您需要为Inner
class
定义一个public
构造函数:
public class COne { protected class Inner implements IOne{ public Inner() { } public void f(){System.out.println("Inner class of COne");} } }
这很清楚。 但这是一个非常奇怪的事情。
根据JLS,如果CTwo扩展了COne.Inner,它应该访问Inner的受保护构造函数,但实际上它没有……见下文。
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... } }
问题不在于内部类而是inheritance。
我们来做一些实验。
First Inner
和Outer
类都可以完全访问彼此。 所以下面的代码运行良好。
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! } }
现在在另一个包中, DerivedOuter
派生自Outer
。 DerivedOuter
调用从Outer
类inheritance的inner()
方法。 它仍然有效!
package com.ciaoshen.packB; class DerivedOuter extends Outer { public static void main(String[] args) { new DerivedOuter().inner().foo(); // Output: Hello Ronald! } }
但是当我覆盖DerivedOuter
类中的inner()
方法时,会发生相同的错误!
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 } }
结论,受保护的Inner构造函数只能在原始的Outer
类范围内访问。 任何其他方法(例如:您的getInner()
方法)都无法访问受保护的Inner
构造函数。
关键点在于,当DerivedOuter
inheritance自Outer
,您可以想象DerivedClass
IS-A Outer
,并且它包含一个Inner
类作为其成员。 但事实上, DerivedOuter
没有直接访问Inner
类,但只能使用他的超类Outer
。