2014-10-12 4 views
1

저는 U.I.을 구현하려고합니다. 여기서 사용자는 콘솔에 값을 입력하고 내 프로그램은 단지 일부 값을 실행 및 수정하거나 실행하고 반환 할 함수를 호출해야합니다. 두 경우 모두이 함수는 매개 변수를 취할 수도 있고 그렇지 않을 수도 있습니다.Java 가변 메서드 및 일반 반환 형식을 사용하여 인터페이스를 구현하는 방법

이 시점에서 이것은 기본적으로 getters와 setter처럼 들리지만, 완전히 구현하고 싶지는 않습니다. 그리고 이것은 10+ if 문을 통과하지 않아도되는 것을 방지하기위한 것입니다. 주어진 사용자 입력.

그래서 내 솔루션은, 내가이 인터페이스를 사용하여 인스턴스 생성 내 수업 내부와 내가 실행하려는 각 활동에 대한이 같은 인터페이스의 종류를 만드는 것입니다 :

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

이 때 작동을 I 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' 객체를 가지고 있지 않거나 갖지 않아야합니다. 오히려'setPerson' 객체로 인스턴스화 된'DoActivity' 객체를 가져야합니다. 메소드 프로토 타입에서 정확히 두 개가 아닌 원하는 수의 객체를 넣을 수 있어야합니다. – Jared

+0

이것이 인터페이스를 적절하게 사용하는 것이 아닙니다. 이 메소드를 실행하려면, 그것이 DoActivity 객체가 아니라'setPerson' 객체라는 것을 알아야합니다. 이것은'setPerson'이'DoActivity'와는 다르다는 것을 나타냅니다. 따라서 인터페이스가 본질적으로 의미하는 것 - 객체가 똑같은 것을 나타내지 만 다르게 행동한다는 것입니다. – Jared

+0

@Jared'setPerson'은 DoActivity와 다르지 않습니다. 클래스 선언 옆에'implements'이 있습니까? 이것은'setPerson'이 DoActivity 객체라는 것을 의미합니다. – smac89

답변

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

내가 한 일에 매우 가깝지만, 각 메소드가 실제로 아무것도 반환하지 않거나 문자열을 리턴해야한다는 것을 알았다. 그래서 리턴 타입을 모든 문자열로 변경했고 메소드를 호출 할 때마다 리턴 값을 얻습니다. null가 아닌 경우 메서드에서 반환 한 값을 인쇄합니다. 또한'params'는'String ... params'로 정의됩니다. – smac89

1

음, 오류가 합리적이다. 인터페이스는 execute 메서드가 임의의 수의 Object 인수를 취할 수 있지만 구현시 실제로는 두 개의 인수 (Strings, 구체적으로)를 취하는 변형을 실제로 구현한다고합니다. 다른 모든 변형 (정확하게 하나의 인수 또는 세 개의 인수 등)은 구현되지 않습니다.

큰 if/else를 피하는 관점에서 보면 부울을 반환하는 canExecute 메서드를 추가하는 것은 어떻습니까? 잠재적 인 DoActivity 구현 목록을 작성하고 목록에서 canExecute에 대해 true을 리턴하는 첫 번째 항목을 찾은 다음 인수 유형 및 수를 가정하는 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

이것이 좋은 접근 방법이라고 생각하지만 실제로 인터페이스가 아닌 추상 클래스 여야한다고 주장 할 것입니다. 또한,'abstract canExecute'라고 생각하고'abstract doExecute' 메소드를 둘 다 보호해야한다고 덧붙입니다 (모든 클래스에서 호출 할 수 없어야 함). 그런 다음'canExecute' 메소드와 (성공할 경우)'doExecute' 메소드를 호출하여'execute' 메소드를 정의 할 수 있습니다. – Jared