超载枚举抽象方法



是否可以超载枚举抽象方法?

我在代码中尝试了这一点,但无效。提出的班级

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?

枚举

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

甚至有可能超载枚举方法还是我做错了什么?还是我应该检查Overriden方法内部的类型,然后采取相应的行动?但是随后我删除Switch语句仅引入另一个交换机语句。

关于枚举的事情是,带有身体的值作为TestEnum的匿名子类实现;所以他们看起来像这样:

final TestEnum TEST1 = new TestEnum() { /* body */ };

TEST1的混凝土类是TestEnum$1(或编译器决定给出的任何名称(,而引用为TestEnum类型,因此TEST1外部的任何代码都只能在TestEnum上定义的访问方法。

是的,是可能的,您以某种方式不以特定方式实现它..

你应该使用要覆盖的方法定义接口

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

您的结果应该看起来像:

如果呢?

test1

为什么不呢?

test2

您正在显示一个类示例,然后您展示了一个枚举示例。我相信您认为这些例子是等效的,但是,它们彼此完全不同。

为了等同于枚举的示例,您应该修改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(。

,Java决定要在编译时间执行的方法。

用枚举,这正是发生的。枚举的所有元素(您的示例中的TEST1TEST2(属于枚举类型(在您的情况下,TestEnum(,因此编译器始终使用称为抽象的方法。

获得两次" test1"的原因是因为您仅声明了此方法
public abstract void test(Object 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

最新更新