Abstract overload method

Is it possible to overload an abstract Enum method?

I've tried this in my code with no effect. Introduced class

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?");
    }
}

      

gives the expected result

Test1
what if?

      

while the enumeration

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

      

returns

Test1
Test1

      

Is it even possible to overload the Enum methods or am I doing something wrong? Or maybe I should check the type inside the overriden method and then act accordingly? But then I remove the switch statement just to introduce another switch statement.

+3


source to share


4 answers


The point about enums is that values ​​with bodies are implemented as anonymous subclasses TestEnum

; so they look like this:

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

      



While a particular class TEST1

is, say, TestEnum$1

(or whatever name the compiler decides to give), the reference is of type TestEnum

, so any code outside the body TEST1

can only access the accessor methods defined in TestEnum

.

+3


source


Yes, you may not be implementing this in a certain way somehow ....

you must define an interface with the methods you want to override

interface Ifoo {
    public void test(Object object);

    public void test(String object);
}

      

then remove the abstract enumeration method and make enum implement that interface, but override those methods in every enumerator constant ...

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

      



finally implement it like>

Object object = new Object();
TestEnum.TEST1.test("what if?");
TestEnum.TEST1.test(object);
TestEnum.TEST2.test("why not?");
TestEnum.TEST2.test(object);

      

your result should look like this:

what if?

Test1

why not?

Test2

0


source


You show an example with a class, and then you show an example with an enum. I believe you think these examples are equivalent, however they are completely different.

For your class example to be equivalent to your enum example, you should modify your class Test

to extend the abstract class 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");
    }
}

      

Now if you try the same lines you tried in your first one main

:

AbstractTest test = new Test();
Object object = new Object();
test.test(object);
test.test("what if?");

      

You will notice that the result is now:

Test1
Test1

      

Which can be expected because Java does not provide a dynamic mailing feature . Informally, dynamic dispatch means that the overloaded method to be executed is determined at runtime based on the polymorphic types of the parameters. Instead, Java decides the method to be executed at compile time based on the declared type of the object whose method is to be called (in this case AbstractTest

).

With enums, this is exactly what happens. All elements of an enum ( TEST1

and TEST2

in your example) are of an enum type ( TestEnum

in your case), so the compiler always goes for a method declared as abstract.

0


source


The reason you get "Test1" twice is because you only declared this method.
public abstract void test(Object object);


This method will "catch" all calls with any parameter type. String extends Object (indirectly), so String is Object and we will call this method.
In other words, the method that receives the String parameter will be hidden by the method that receives the Object parameter.

The solution is to add the following method declaration to the enum.
public abstract void test(String string);


You will need to add the implementation of this method to the constant TEST2

.

Code

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

      

This code outputs

what if?
Test1

      

0


source







All Articles