繁体   English   中英

为什么匿名类不能实现两个单独的接口,但可以实现内部接口?

[英]Why an anonymous class can't implement two separated interfaces but can implement inner interfaces?

匿名类只能从一个类或接口扩展,所以我不能做下一个:

interface Enjoyable {
    public void enjoy();
}

interface Exercisable {
    public void exercise();
}

public class Test {
    public static void main(String[] args) {
        new Enjoyable implements Exercisable() {
            public void enjoy() {
                System.out.println(":D");
            }
        }.enjoy();

    }
}

它说:

愉悦的,无法解决的类型

我正在尝试复制这种行为,并编写了下一个代码:

interface Enjoyable {
    interface Exercisable {
        public void exercise();
    }
    public void enjoy();
}

public class Test {
    public static void main(String[] args) {
        new Enjoyable.Exercisable() {
            public void enjoy() {
                System.out.println(":D");
            }

            public void exercise() {
                System.out.println("Doing exercise !!!");

            }
        }.exercise();

        new Enjoyable.Exercisable() {
            public void enjoy() {
                System.out.println(":D");
            }

            public void exercise() {
                System.out.println("Doing exercise !!!");

            }
        }.enjoy();

    }
}

然后我得到:

做运动 !!! :D

还有另一种模拟它的方法吗? 而且我要在匿名类中实现这两种方法吗?

谢谢

我想要一个实现2个接口方法的匿名类

我假设您的意思是您想要一个实现两个接口的匿名类。 您不能直接这样做。

你可以做

interface EnjoyableAndExercisable extends Enjoyable, Exercisable {
}

然后创建一个实现它的匿名类。

EnjoyableAndExercisable o = new EnjoyableAndExercisable() {
    @Override
    public void enjoy() {
        System.out.println(":D");
    }
    @Override
    public void exercise() {
        System.out.println("Doing exercise !!!");

    }
};

注意@Override ,它将始终验证您是否实际上是在重写方法。

但是在您的代码中,该匿名类

new Enjoyable.Exercisable() {
    public void enjoy() {
        System.out.println(":D");
    }

    public void exercise() {
        System.out.println("Doing exercise !!!");

    }
}.enjoy();

只是Exercisable的实现。 您只是碰巧在其中声明了一个名称为“ enjoy的方法。

您不能将其分配给“令人Enjoyable ”类型的变量

Enjoyable ref = new Enjoyable.Exercisable() {
    public void enjoy() {
        System.out.println(":D");
    }

    public void exercise() {
        System.out.println("Doing exercise !!!");

    }
}; // nope, compile time error

您只能在声明此匿名类型的新实例创建表达式上调用该方法。 您不能以其他任何方式调用它(因为它是以匿名类型声明的)。

您的Exercisable不能令人愉快:-)这样的嵌套接口并不意味着内部接口属于外部接口!

你可能还写了类似

new Object() {
            public void enjoy() {
                System.out.println(":D");
            }

            public void exercise() {
                System.out.println("Doing exercise !!!");

            }
        }.enjoy()
// same for .excercise()

因此,您实际上并不是在模拟实现两个接口的匿名类。

当您实际尝试将匿名实例分配给接口类型的变量时,您会看到此信息

// this WILL NOT COMPILE !
Enjoyable enjoyable=new Enjoyable.Exercisable() {
            public void enjoy() {
                System.out.println(":D");
            }

            public void exercise() {
                System.out.println("Doing exercise !!!");

            }
        }.enjoy();

您当然可以做这样的事情:

interface Enjoyable {
    public void enjoy();
}

interface Exercisable extends Enjoyable {
   public void exercise();
}

然后使用这些接口创建匿名实例不幸的是,无法创建实现您试图实现的两个接口的匿名实例。

您可以基于非最终类或具有以下内容的接口创建匿名内部类

new Exerciseable(){
...
}

但是,Java不允许

new Object() implements Exercisable{
...
}

要么

new Object implements Exercisable(){
...
}

匿名内部类使用new关键字生成类的新实例,该类的超类为Object并实现Exercisable JCP站点托管一个文档( https://jcp.org/aboutJava/communityprocess/maintenance/JLS/innerclasses.pdf ),属于内部类的JSL,其中说:

如前所述,如果匿名类是从接口I派生的,则实际的超类是Object,并且该类将实现I而不是对其进行扩展。 (显式的实现子句是非法的。)这是接口名称合法地跟随关键字new的唯一方法。 在这种情况下,参数列表必须始终为null,以匹配实际超类Object的构造函数。

您的第二个示例构造了一个Exercisable类型,该类型扩展了Enjoyable 创建该接口的匿名类再次合法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM