Java如何使用可变方法和泛型返回类型实现接口

Java如何使用可变方法和泛型返回类型实现接口,java,functional-programming,generic-programming,Java,Functional Programming,Generic Programming,我正在尝试实现一个U.I.,其中用户将在控制台中键入一个值,我的程序应该调用一个函数,该函数要么执行并修改某个值,要么执行并返回某个值。在任何一种情况下,此函数都可以接受参数,也可以不接受参数 所以在这一点上,这基本上听起来像getter和setter,但我不想以那种方式完全实现它,这是为了避免必须通过10+if语句来确定对任何给定的用户输入做什么 因此,我的解决方案是在我的类中创建一种类似这样的接口,对于我想要运行的每个活动,我使用该接口创建一个实例: private interface Do

我正在尝试实现一个U.I.,其中用户将在控制台中键入一个值,我的程序应该调用一个函数,该函数要么执行并修改某个值,要么执行并返回某个值。在任何一种情况下,此函数都可以接受参数,也可以不接受参数

所以在这一点上,这基本上听起来像getter和setter,但我不想以那种方式完全实现它,这是为了避免必须通过10+if语句来确定对任何给定的用户输入做什么

因此,我的解决方案是在我的类中创建一种类似这样的接口,对于我想要运行的每个活动,我使用该接口创建一个实例:

private interface DoActivity <R> {
    public R execute(Object... param);
}
我发现上面的错误:
方法不实现或重写超类型中的方法
有没有一种方法可以做我想做的事而不去思考

样本使用:

// at prompt
>> Enter an operation: 1 Bumble Bee
>> ...

// In program
String input = "1 Bumble Bee";
String split[] = input.split();
int operation = Integer.parseInt(split[0]);
DoActivityArray[operation - 1].execute(split[1], split[2]);

嗯,这个错误是合理的。接口表示
execute
方法可以接受任意数量的对象参数,但尝试实现时实际上只实现了一个变量,该变量正好接受两个参数(具体来说是字符串)。所有其他变量(仅一个参数或三个参数,等等)都没有实现

为了避免大的if/else,添加一个返回布尔值的
canExecute
方法怎么样。创建一个潜在的
DoActivity
实现列表,在列表中找到第一个返回
true
canExecute
,然后执行其
execute
方法,该方法假定参数的类型和数量

interface DoActivity<R> {

    public boolean canExecute(Object... param);

    public R execute(Object... param);
}

class SetPerson implements DoActivity {

    @Override
    public Void execute(Object... param) {
        String name = (String)param[0];
        String telephone = (String)param[1];        
        ...
    }

    @Override
    public boolean canExecute(Object... param) {
        return param != null && param.length == 2;
    }
}
接口有效性{
公共布尔canExecute(对象…参数);
公共R执行(对象…参数);
}
类SetPerson实现DoActivity{
@凌驾
public Void execute(对象…参数){
字符串名称=(字符串)参数[0];
字符串电话=(字符串)参数[1];
...
}
@凌驾
公共布尔canExecute(对象…参数){
返回参数!=null&¶m.length==2;
}
}

对于您的特定示例,解决方案实际上非常简单:

private class setPerson implements DoActivity{
    @Override
    public Object execute(final Object ...params){
        if(params.length != 2)
            throw new RuntimeException(
                "setPerson must take an array of exactly two strings");
        try{
            final String name = (String)params[0];
            final String telephone = (String)params[1];
            ...
            return null;
        } catch(ClassCastException cce){
            throw new RuntimeException(
                "setPerson must take an array of exactly two strings");
        }
    }
}

您的execute方法与接口的类型不同。用户没有(或不应该)拥有
setPerson
对象,而是应该拥有一个
DoActivity
对象,该对象恰好被
setPerson
对象实例化。从方法原型来看,他们应该能够放置任意数量的对象,而不是两个。我不认为这是接口的正确使用。要执行该方法,需要认识到它不是
DoActivity
对象,而是
setPerson
对象。这表明
setPerson
DoActivity
不同,因此不应等同(这就是接口的本质含义——对象表示相同的事物,但行为不同)。@Jared
setPerson
DoActivity
没有区别,注意类声明旁边的
实现
?这意味着
setPerson
是一个
DoActivity
object1)仅仅因为您使用接口编写可编译代码并不意味着您根据OO原则正确使用了接口,2)您没有呈现可编译代码,所以你的
setPerson
类根本不存在——不存在的东西不可能是
DoActivity
的实例。我真的不明白你想要实现什么。提供一个示例会话来解释您正试图完成的不同任务将是很有帮助的。在我看来,您真正需要的是一个
Map
,它将
String
s映射到接受参数的对象(它们本身看起来像
String
对象)。这与我所做的非常接近,但我注意到每个方法实际上应该不返回任何内容或返回字符串。因此,我将返回类型更改为所有字符串,每当我调用一个方法时,我都会得到它的返回值;如果不为null,我将打印该方法返回的值。另外,
参数
被定义为
字符串。。。params
我认为这是一种很好的方法,然而,我实际上认为它现在应该更像是一个抽象类而不是接口。此外,我认为
abstract-canExecute
abstract-doExecute
方法都应该受到保护(它们不应该被任何类调用)。然后可以通过调用
canExecute
和(如果成功)
doExecute
方法来定义
execute
方法。
private class setPerson implements DoActivity{
    @Override
    public Object execute(final Object ...params){
        if(params.length != 2)
            throw new RuntimeException(
                "setPerson must take an array of exactly two strings");
        try{
            final String name = (String)params[0];
            final String telephone = (String)params[1];
            ...
            return null;
        } catch(ClassCastException cce){
            throw new RuntimeException(
                "setPerson must take an array of exactly two strings");
        }
    }
}