如何在枚举之外调用枚举值特定方法?

时间:2017-11-15 15:34:09

标签: java enums

我有这样的枚举:

  public enum Email{
        WELCOME,
        LOGIN       
    }

EmailService具有以下方法签名:

public void sendEmail(String from, String subject, String[] to, Map<String, String> props, String templateFileName)

我希望有这样的API:

Email.WELCOME.send(from, subject, to, welcomeProp1, welcomeProp2....)



Email.LOGIN.send(from, subject, to, loginProp1, loginProp2....)

为了解决这个问题,我尝试为枚举字段添加特定方法:

public enum Email{
    WELCOME{
        public void send(String param1,String param2,String param3,String param4){
           ....    
        }
    },
    LOGIN{
        public void send(String anotherParam1,String anotherParam2,String anotherParam3){
            .... 
        }
    }
}

但是我发现我无法在枚举之外调用这些方法。为了实现它,我需要在每个枚举值中创建抽象方法和覆盖。但是这些方法的签名不同而且不可能做到的问题。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

在这种情况下,您可以使用多态性。首先,定义一些接口,例如:

public interface Message {
}

然后你应该在枚举中添加一个抽象方法:

public abstract void send(Message message);

之后,创建两个子类 - 第一个用于WELCOME,第二个用于LOGIN:

class WelcomeMessage implements Message {
    private String param1;
    private String param2;
    private String param3;
    private String param4;

    // constructor, getters
}

class LoginMessage implements Message {
    private String anotherParam1; 
    private String anotherParam2; 
    private String anotherParam3;

    // constructor, getters
}

然后添加send()方法的实现:

public enum Email {
    WELCOME {
        public void send(Message message) {
            WelcomeMessage wm = (WelcomeMessage) message;
            ....    
        }
    },
    LOGIN {
        public void send(Message message) {
            LoginMessage lm = (LoginMessage) message;
            .... 
        }
    }
}

UPD。 @gstackoverflow提到可以使用&#34;不正确的&#34;来调用方法。实现。我想我知道如何防止这种情况。

public enum Email {
    WELCOME {
        protected void sendInternal(Message message) {
            WelcomeMessage wm = (WelcomeMessage) message;
            ....    
        }

        protected Class<? extends Message> getSupportedClass() {
            return WelcomeMessage.class;
        }
    },
    LOGIN {
        protected void sendInternal(Message message) {
            LoginMessage lm = (LoginMessage) message;
            .... 
        }

        protected Class<? extends Message> getSupportedClass() {
            return LoginMessage;
        }
    };

    public static void send(Message message) {
        for (Email email : values()) {
            if (email.getSupportedClass().equals(message.getClass()) {
                email.sendInternal(message);
            }
        }
    }
    protected abstract void sendInternal(Message message);
    protected abstract Class<? extends Message> getSupportedClass();
}

答案 1 :(得分:1)

一种解决方案是让所有方法都采用完全相同的对象,它们只使用不同的参数。

class EmailDetails {
    String param1;
    String param2;
    String param3;
    String param4;
    String anotherParam1; 
    String anotherParam2; 
    String anotherParam3;
}

public enum Email {
    WELCOME {
        public void send(EmailDetails details) {
            System.out.println("Welcome!!");
        }
    },
    LOGIN {
        public void send(EmailDetails details) {
            System.out.println("Log in!!");
        }
    };

    public abstract void send(EmailDetails details);
}

public void test(String[] args) {
    Email.WELCOME.send(new EmailDetails());
    Email.LOGIN.send(new EmailDetails());
}

您通常会发现许多字段对所有用途都是通用的。