简体   繁体   English

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

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

An anonymous class can extend only from one class or interface, so I can't do the next : 匿名类只能从一个类或接口扩展,所以我不能做下一个:

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();

    }
}

It says that : 它说:

Enjoyable.Exercisable cannot be resolved to a type 愉悦的,无法解决的类型

I'm trying to replicate this behavior and I wrote the next code: 我正在尝试复制这种行为,并编写了下一个代码:

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();

    }
}

And then I get : 然后我得到:

Doing exercise !!! 做运动 !!! :D :D

Are there another way to simulate It? 还有另一种模拟它的方法吗? And way i hace to implement both metods un the anonymous class ? 而且我要在匿名类中实现这两种方法吗?

Thanks 谢谢

I want an anonymous class who implements 2 interfaces methods 我想要一个实现2个接口方法的匿名类

I assume you mean you want an anonymous class which implements two interfaces. 我假设您的意思是您想要一个实现两个接口的匿名类。 You can't, directly. 您不能直接这样做。

You can do 你可以做

interface EnjoyableAndExercisable extends Enjoyable, Exercisable {
}

and then create an anonymous class that implements that. 然后创建一个实现它的匿名类。

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

    }
};

Note the @Override which will always validate whether you are actually overriding a method or not. 注意@Override ,它将始终验证您是否实际上是在重写方法。

In your code however, this anonymous class 但是在您的代码中,该匿名类

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

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

    }
}.enjoy();

is only an implementation of Exercisable . 只是Exercisable的实现。 You just happen to declare a method with the name enjoy within it. 您只是碰巧在其中声明了一个名称为“ enjoy的方法。

You cannot assign it to a variable of type Enjoyable 您不能将其分配给“令人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

You can only invoke that method on the new instance creation expression that declares this anonymous type. 您只能在声明此匿名类型的新实例创建表达式上调用该方法。 You cannot invoke it any other way (since it's declared in an anonymous type). 您不能以其他任何方式调用它(因为它是以匿名类型声明的)。

your Exercisable's are not Enjoyable :-) nesting interfaces this way does not mean that the inner interface is of the type of the outer interface ! 您的Exercisable不能令人愉快:-)这样的嵌套接口并不意味着内部接口属于外部接口!

you could just as well have written something like 你可能还写了类似

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

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

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

so you are not actually simulating an anonymous class that implements two interfaces. 因此,您实际上并不是在模拟实现两个接口的匿名类。

you can see this when you actually try to assign your anonymous instance to a variable of a type of your interfaces 当您实际尝试将匿名实例分配给接口类型的变量时,您会看到此信息

// 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();

you could of course do something like this : 您当然可以做这样的事情:

interface Enjoyable {
    public void enjoy();
}

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

and then create anonymous instances using those interfaces Unfortunately creating an anonymous instance that implements two interfaces like you are trying to do is not possible. 然后使用这些接口创建匿名实例不幸的是,无法创建实现您试图实现的两个接口的匿名实例。

You can create anonymous inner classes based on a non-final class or an interface with 您可以基于非最终类或具有以下内容的接口创建匿名内部类

new Exerciseable(){
...
}

However, Java does not allow 但是,Java不允许

new Object() implements Exercisable{
...
}

or 要么

new Object implements Exercisable(){
...
}

The anonymous inner class produces with the new keyword a new instance of a class whose superclass is Object and implements Exercisable . 匿名内部类使用new关键字生成类的新实例,该类的超类为Object并实现Exercisable The JCP site hosts a document ( https://jcp.org/aboutJava/communityprocess/maintenance/JLS/innerclasses.pdf ), belonging to the JSL about inner classes which says: JCP站点托管一个文档( https://jcp.org/aboutJava/communityprocess/maintenance/JLS/innerclasses.pdf ),属于内部类的JSL,其中说:

As already hinted, if an anonymous class is derived from an interface I, the actual superclass is Object, and the class implements I rather than extending it. 如前所述,如果匿名类是从接口I派生的,则实际的超类是Object,并且该类将实现I而不是对其进行扩展。 (Explicit implements clauses are illegal.) This is the only way an interface name can legally follow the keyword new. (显式的实现子句是非法的。)这是接口名称合法地跟随关键字new的唯一方法。 In such cases, the argument list must always be null, to match the constructor of the actual superclass, Object. 在这种情况下,参数列表必须始终为null,以匹配实际超类Object的构造函数。

Your second example constructs a type Exercisable which extends Enjoyable . 您的第二个示例构造了一个Exercisable类型,该类型扩展了Enjoyable Creating anonymous classes of that interface is legal again. 创建该接口的匿名类再次合法。

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

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