当类实现该接口时,该类是否继承该接口内声明的抽象内部类?

时间:2018-07-27 22:23:27

标签: java inheritance interface override abstract

我正在运行以下Java版本
openjdk版本“ 10.0.1” 2018-04-17
OpenJDK运行时环境(内部版本10.0.1 + 10-Ubuntu-3ubuntu1)
OpenJDK 64位服务器VM(内部版本10.0.1 + 10-Ubuntu-3ubuntu1,混合模式)

程序1

class Outer{
abstract class Inner{
    void m1(){
        System.out.println("Inner class m1 method");
    }
  }

 }


class Outer2 extends Outer.Inner{
Outer2(){
new Outer().super();
  }
}
class Test{
public static void main(String[] args) {
new Outer2().m1();
 }
}

输入:深(主*)JavaStuffs $ javac sample.java
deep(master *)JavaStuffs $ java测试
输出:内部类m1方法

程序2

interface Outer{
    abstract class Inner{
    void m1(){
        System.out.println("Inner class m1 method");
    }
  }
}
class J implements Outer{

}
class Outer2 extends J.Inner{

Outer2(){
    new J().super();
  }
}
class Test{
public static void main(String[] args) {
    new Outer2().m1();

  }
}

输入:深(主*)JavaStuffs $ javac sample.java
输出: sample.java:1309:错误:非法限定符;内部不是内部类
        新的J()。super();
               ^    1个错误

程序3

interface Outer{
abstract class Inner{
    void m1(){
        System.out.println("Inner class m1 method");
   }
 }
}
class J implements Outer{
class InnerJ extends Inner{

 }
}
class Outer2 extends J.Inner{
Outer2(){
new J().super();
 }
}
class Test{
public static void main(String[] args) {
    new J().new InnerJ().m1();
    new Outer2().m1();
 }
}

输入:深(主*)JavaStuffs $ javac sample.java
输出: sample.java:1372:错误:非法限定符;内部不是内部类
        新的J()。super();
               ^    1个错误

程序2 程序3 中,我希望该类在实现接口时将继承内部抽象类。但事实并非如此!谁能解释?一个确切的原因将受到高度赞赏!

2 个答案:

答案 0 :(得分:2)

在接口内部定义的成员类始终隐式地 static 。它不是内部类,而是静态成员类,并且没有与之关联的外部类实例。

Java Language Specification states this in section 9.5

  

接口中的成员类型声明是隐式公共的,并且   静态的。允许冗余地指定这两个或其中之一   修饰符。

因此,在程序2中,在类Outer2的构造函数中,您无法说出new J().super();,因为Outer2没有外部实例-它不是内部类。来自javac的错误说明了很多:“非法限定符;内部不是内部类”

答案 1 :(得分:1)

不。类从其父类继承实例变量和实例方法,并且它们实现相同的接口。他们可以访问其父类的静态成员,并且可以直接或间接实现接口 ,就像它们是继承的一样,但这在技术上是不同的。

嵌套类和接口既不从父类也不从已实现的接口继承,但是子类的实例可以用作其父类的内部类的包含实例。

在另一个内部嵌套一个类或接口首先会提供一个额外的命名空间。 Parent.InnerChild.Inner是不同的类-您无需考虑任何其他因素,因为它们的名称不同。因此,子类不继承嵌套类。没有好的方法,也没有特别的优势。