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



我想从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 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列为public类。但是为什么呢?这就是为什么WorkersClass的后继者可以在他们的方法中实例化Worker类的原因。我是否误解了什么?

问题不全在于访问说明符

当你没有在类中提供任何构造函数时,编译器会自动为你插入一个默认的无参数构造函数

在这里不成立。因为编译后的内部类没有默认构造函数,因为它被编译为outer$inner,而对于inner,编译器没有提供默认构造函数。

手动提供默认的no org constructor并查看魔术:)

package second;
import workers.Employable;
public class WorkersClass {
    protected class Worker implements Employable {

        public Worker() {
            // TODO Auto-generated constructor stub
        }
        @Override
        public void work() {
            System.out.println("Hello, I'm a worker!");
        }
    }
}

modify WorkersClass

public class WorkersClass {
  protected class Worker implements Employable {
    public Worker(){}
    @Override
    public void work() {
        System.out.println("Hello, I'm a worker!");
    }
  }
}

您的Third类继承了WorkersClass而不是 Worker

Java并没有真正考虑内部类,它是Java 1.1中引入的一个简单的hack。编译器在WorkersClass类的"外部"生成Worker类,但在同一个包中。
这就是为什么,为了从Third方法实现一个新的Worker实例,您需要向Worker添加一个公共构造函数:

protected class Worker implements Employable {
  public Worker(){
  }
  @Override
  public void work() {
    System.out.println("Hello, I'm a worker!");
  }
}

最新更新