是否可以重载Enum抽象方法?
我在我的代码中试过这个没有效果。 提出课程
public class Test {
public void test(String string){
System.out.println(string);
}
public void test(Object object){
System.out.println("Test1");
}
public static void main(String[] args) {
Object object = new Object();
test.test(object);
test.test("what if?");
}
}
给出
的预期结果Test1
what if?
while enum
public enum TestEnum {
TEST1{
public void test(String string){
System.out.println(string);
}
public void test(Object object){
System.out.println("Test1");
}
},
TEST2{
public void test(Object object){
System.out.println("Test2");
}
};
public abstract void test(Object object);
}
public class Test {
public static void main(String[] args) {
Object object = new Object();
TestEnum.TEST1.test("what if?");
TestEnum.TEST1.test(object);
}
}
返回
Test1
Test1
甚至可能重载Enum方法还是我做错了什么?或者我应该检查覆盖方法内部的类型然后相应地采取行动?但是我只删除了switch语句以引入另一个switch语句。
答案 0 :(得分:3)
关于枚举的事情是,具有主体的值被实现为TestEnum
的匿名子类;所以他们看起来像这样:
final TestEnum TEST1 = new TestEnum() { /* body */ };
虽然TEST1
的具体类是,TestEnum$1
(或编译器决定给出的任何名称),但引用的类型为TestEnum
,因此身体外的任何代码都是TEST1
只能访问TestEnum
上定义的方法。
答案 1 :(得分:0)
是的可能,你不知道以某种方式实现这个......
你应该 使用要覆盖的方法定义接口interface Ifoo {
public void test(Object object);
public void test(String object);
}
然后删除枚举的抽象方法并使枚举实现该接口,但在枚举器的每个常量中覆盖这些方法......
enum TestEnum implements Ifoo {
TEST1 {
@Override
public void test(String string) {
System.out.println(string);
}
@Override
public void test(Object object) {
System.out.println("Test1");
}
},
TEST2 {
@Override
public void test(Object object) {
System.out.println("Test2");
}
@Override
public void test(String string) {
System.out.println(string);
}
};
}
最终像>
一样实现它Object object = new Object();
TestEnum.TEST1.test("what if?");
TestEnum.TEST1.test(object);
TestEnum.TEST2.test("why not?");
TestEnum.TEST2.test(object);
您的结果应如下所示:
怎么办?
测试1
为什么不呢?
的Test2
答案 2 :(得分:0)
您正在显示一个类的示例,然后您将显示一个包含枚举的示例。我相信你认为这些例子是等价的,然而,它们彼此完全不同。
如果您的类的示例与枚举示例相同,则应修改Test
类,以便扩展抽象AbstractTest
类:
public abstract class AbstractTest {
public abstract void test(Object object);
}
public class Test extends AbstractTest {
public void test(String string) {
System.out.println(string);
}
@Override
public void test(Object object) {
System.out.println("Test1");
}
}
现在,如果您尝试使用第一个main
尝试的相同行:
AbstractTest test = new Test();
Object object = new Object();
test.test(object);
test.test("what if?");
您会注意到输出现已变为:
Test1
Test1
这是可以预料到的,因为Java没有提供名为dynamic dispatch的功能。非正式地,动态分派意味着要根据参数的多态类型在运行时决定要执行的重载方法。相反,Java根据要调用其方法的对象的声明的类型决定在编译时执行的方法(在本例中为AbstractTest
)。
使用枚举,这正是发生的事情。枚举的所有元素(在您的示例中为TEST1
和TEST2
)属于枚举的类型(在您的情况下为TestEnum
),因此编译器始终使用的方法是宣称为抽象。
答案 3 :(得分:0)
你得到两次的原因" Test1"是因为你只声明了这种方法
public abstract void test(Object object);
确切地说,这种方法将会捕获"所有调用任何类型的参数。 String扩展Object(间接),因此String是Object,我们可以调用这个方法
换句话说,接收参数String的方法将被接收参数Object的方法隐藏。
解决方案是在枚举中添加下一个方法声明
public abstract void test(String string);
您必须将此方法的实现添加到TEST2
常量。
代码
public enum TestEnum {
TEST1 {
public void test(String string) {
System.out.println(string);
}
public void test(Object object) {
System.out.println("Test1");
}
},
TEST2 {
public void test(Object object) {
System.out.println("Test2");
}
@Override
public void test(String string) {
// TODO Auto-generated method stub
}
};
public abstract void test(Object object);
public abstract void test(String string);
}
此代码提供输出
what if?
Test1