Java 实例化使用受保护的访问说明符继承的内部类
我想根据Bruce Eckel的关于内部类的TIJ做以下练习:Java 实例化使用受保护的访问说明符继承的内部类,java,inheritance,inner-classes,Java,Inheritance,Inner Classes,我想根据Bruce Eckel的关于内部类的TIJ做以下练习: Create an interface with at least one method, in its own package. Create a class in a separate package. Add a protected inner class that implements the interface. In a third package, inherit from your class and, inside
Create an interface with at least one method, in its own package.
Create a class in a separate package. Add a protected inner class
that implements the interface. In a third package, inherit from
your class and, inside a method, return an object of the protected
inner class, upcasting to the interface during the return.
以下是我的实现:
首先,界面:
package workers;
public interface Employable {
void work();
}
package second;
import workers.Employable;
public class WorkersClass {
protected class Worker implements Employable {
@Override
public void work() {
System.out.println("Hello, I'm a worker!");
}
}
}
然后,一个具有实现接口的内部类的类:
package workers;
public interface Employable {
void work();
}
package second;
import workers.Employable;
public class WorkersClass {
protected class Worker implements Employable {
@Override
public void work() {
System.out.println("Hello, I'm a worker!");
}
}
}
最后是继承的类:
package third;
import second.WorkersClass;
import workers.Employable;
public class Third extends WorkersClass {
Employable getWorker() {
return new Worker();//the line is reported to be incorrect
}
}
IDEA在getWorker
中用Worker()
划线,并建议将Worker
类公开。但是为什么呢?它是受保护的,这就是为什么workerClass
的继承者可以在其方法中实例化Worker
类的原因。我误解了什么吗?修改WorkersClass
public class WorkersClass {
protected class Worker implements Employable {
public Worker(){}
@Override
public void work() {
System.out.println("Hello, I'm a worker!");
}
}
}
问题不完全在于访问说明符。
当您在类中不提供任何构造函数时,编译器会自动为您插入默认的无参数构造函数
在这种情况下,情况并非如此。因为编译后的内部类没有获得默认构造函数,因为它被编译为outer$internal
,并且对于该internal
,编译器没有提供默认构造函数
手动提供默认的无组织构造函数
,并查看神奇之处:)
您的第三个
类继承了WorkersClass
和非工作者
java并不真正考虑内部类,它是java 1.1中引入的简单黑客。编译器在类
workerClass
的“外部”生成类workerClass
,但在同一个包中。
这就是为什么,为了从第三个
方法实现一个新的工作者
实例,您需要向工作者
添加一个公共构造函数:
protected class Worker implements Employable {
public Worker(){
}
@Override
public void work() {
System.out.println("Hello, I'm a worker!");
}
}
回答正确。但是为什么呢?隐式默认构造函数可见性与类可见性相同,因此在这个类的情况下,它将被“保护”。第三是扩展WorkerClass,而不是WorkerI没有足够的声誉来评论你的答案,然而,这是一个显而易见的问题。