Java 为什么匿名类可以';不能实现两个分离的接口,但可以实现内部接口?

Java 为什么匿名类可以';不能实现两个分离的接口,但可以实现内部接口?,java,anonymous,Java,Anonymous,匿名类只能从一个类或接口扩展,因此我无法执行下一个操作: interface Enjoyable { public void enjoy(); } interface Exercisable { public void exercise(); } public class Test { public static void main(String[] args) { new Enjoyable implements Exercisable() {

匿名类只能从一个类或接口扩展,因此我无法执行下一个操作:

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

    }
}
它说:

令人愉快。无法将exerciseable解析为类型

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

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();
仅是可执行的的实现。您只是碰巧声明了一个名为
previous
的方法

您不能将其分配给类型为
的变量

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

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

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


我想要一个实现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();
仅是可执行的
的实现。您只是碰巧声明了一个名为
previous
的方法

您不能将其分配给类型为
的变量

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

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

    }
}; // nope, compile time error

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

您的可执行的不愉快:-) 以这种方式嵌套接口并不意味着内部接口是 外部接口的类型

你也可以写一些类似的东西

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 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
的类的新实例,并实现
exerciseable
。JCP站点承载一个文档(),属于关于内部类的JSL,其中说明:

如前所述,如果匿名类是从接口派生的 一、 实际的超类是Object,而该类实现了I 而不是扩展它。(显式实现子句是非法的。)这是 接口名称只能合法地跟随关键字new。在里面 在这种情况下,参数列表必须始终为空,以匹配 实际超类Object的构造函数


您的第二个示例构造了一个类型
exerciseable
,它扩展了
perfective
。创建该接口的匿名类同样合法。

您可以基于非最终类或具有

new Exerciseable(){
...
}
但是,Java不允许

new Object() implements Exercisable{
...
}

匿名内部类使用
new
关键字生成其超类为
Object
的类的新实例,并实现
exerciseable
。JCP站点承载一个文档(),属于关于内部类的JSL,其中说明:

如前所述,如果匿名类是从接口派生的 一、 实际的超类是Object,而该类实现了I 而不是扩展它。(显式实现子句是非法的。)这是 接口名称只能合法地跟随关键字new。在里面 在这种情况下,参数列表必须始终为空,以匹配 实际超类Object的构造函数


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

在第二个代码片段中,您的匿名类实现了
exerciseable
,不是
有趣的
。你问的不太清楚。我想要一个匿名类,它实现了一个2接口方法这是一个不同的问题,我想要复制实现两个匿名类型的接口不仅在你的第二个代码片段中,你的匿名类正在实现
可操作的
,不是很有趣
。不太清楚