Java 实例化使用受保护的访问说明符继承的内部类

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

我想根据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 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没有足够的声誉来评论你的答案,然而,这是一个显而易见的问题。