2014-10-12 94 views
1

我正在尝试实现一个U.I.用户将在控制台中键入一个值,并且我的程序应该调用一个函数,该函数将执行并修改某个值或执行并返回一些值。无论哪种情况,这个函数都可以带参数或不带参数。Java如何使用可变参数方法和泛型返回类型实现接口

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

所以我的解决方案是创建一个有点像我这班里面和我想要运行的每个活动接口的,我创建一个使用此接口的它的实例:

private interface DoActivity <R> { 
    public R execute(Object... param); 
} 

这工作时,我不想指定类型的参数传递给execute方法,但是当我创建DoActivity的一个实例,像这样与它的执行方法:

private class setPerson implements DoActivity { 
    @Override 
    public Void execute(String name, String telephone) { 
     ... 
     return null; 
    } 
} 

我得到一个错误与上面的: method does not implement or override a method from supertype 有没有办法做到我想要的而不诉诸反思?

使用示例:

// 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]); 
+0

你的执行方法不具有相同类型的接口。一个用户不是(或不应该)有一个'setPerson'对象,而是他们应该有一个'DoActivity'对象,它恰好是用'setPerson'对象实例化的。从方法原型来看,它们应该能够放置任意数量的对象,而不仅仅是两个。 – Jared 2014-10-12 02:15:37

+0

我没有看到这是一个接口的正确使用。为了执行该方法,需要认识到它不是'DoActivity'对象,而是'setPerson'对象。这表明'setPerson'与'DoActivity'不同,因此不应该被等同(这就是接口本质上的含义 - 对象表示相同的东西,但行为不同)。 – Jared 2014-10-12 02:20:44

+0

@Jared'setPerson'与'DoActivity'没有区别,注意类声明旁边的'implements'?这意味着'setPerson'是一个'DoActivity'对象 – smac89 2014-10-12 03:26:16

回答

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

非常接近我所做的,但我注意到每个方法应该事实上不返回或返回一个字符串。所以我改变了返回类型为全部字符串,每当我调用一个方法时,我都会得到它的返回值;如果它不为空,我将打印方法返回的值。另外'params'被定义为'String ... params' – smac89 2014-10-12 15:11:52

1

好,误差是合理的。该接口说execute方法可以接受任意数量的Object参数,但是在实现中的尝试只能实际实现一个接受两个参数(特别是字符串)的变体。所有其他变体(正好一个参数或三个参数等)都未实现。

在避免大if/else方面,如何增加一个返回布尔值的方法canExecute?创建一个潜在的DoActivity实现列表,找到列表中的第一个返回truecanExecute,然后执行其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; 
    } 
} 
+0

我认为这是一个好方法,但是,我实际上会争辩说它现在应该更多地是抽象类而不是接口。此外,我认为'抽象canExecute'和我会补充说,'抽象doExecute'方法都应该被保护(它们不应该被允许被任何类调用)。然后你可以通过调用'canExecute'和(如果成功)'doExecute'方法来定义'execute'方法。 – Jared 2015-04-26 05:34:49