2010-01-04 9 views
3

가 나는 두 클래스 아래 정의 : 클래스 이름을 모른 채 메서드를 호출하는 방법은 무엇입니까?

public class junk { 
    private BigInteger a = BigIngeger.valueOf(1), b=BigInteger.valueOf(2), c; 

    public void DoSomething() { 
     c = a.add(b); 
    } 

    // ... other stuff here 
} 

public class junkChild extends junk { 
    private BigDecimal a = BigDecimal.valueOf(1), b=BigDecimal.valueOf(2), c; 
    // I want a, b, c to override the original BigInteger a,b,c 
    // ... other stuff here 
}  

public class myClass { 
    public static void main(String args[]) { 
     junk a1 = new junkChild(); 
     a1.DoSomething(); 
    } 
} 

는 불행하게도 위에서 작동하지 않습니다. 내가 원하는 무엇

단순히 다시 DoSomething()을 다시 작성하지 않고도 junkChilda, b, cBigDecimal로 변경하는 것입니다. 코드를 다시 작성해야하더라도 코드는 정확히 동일하므로 작성하지 않고이 작업을 수행 할 수있는 방법이 있어야합니다. DoSomething 함수는 유형 a1에 올바른 입력 및 반환 유형의 add 메소드가 있는지 확인해야하며, 그렇다면 a, b, c 유형을 걱정하지 않고 호출합니다.

이 작업을 수행 할 수 있습니까?

+0

리플렉션에서 읽어야합니다. 그것은 귀하의 질문의 두 번째 부분을 수행합니다. 첫 번째 부분에서는'a', b' 및'c' 필드를 직접 사용하지 말고 대신 하위 클래스에서 재정의하는 getA','getB' 및'getC' 메서드를 사용하십시오. –

+0

정말로 원하는 것은 C++과 같은 템플릿입니다. –

+2

그가 정말로 원하는 것은 "오리 타이핑"이라고 들리는 것 같습니다. – Asaph

답변

4

아니요,이 작업을 수행 할 수 없습니다. 적어도 컴파일 타임에는 수행 할 수 없습니다. 두 개의 add 메소드는 효과적으로 관련이 없습니다. 인터페이스 나 그와 같은 것이 아닙니다.

당신은 반사와 함께 할 수있는 (a, bc 또는 이와 유사한 속성을 추가 한 후 - 필드는이 같은 "오버라이드"할 수 없다)하지만 정말 좋지 않을까.

+0

가장 to-the-point 대답. 호기심 때문에 'System.out.print'로 왜이 일을 할 수 있습니까? (모든 임의의 클래스에 대해'toString' 메소드를 정의 할 수 있습니다.) – Jus12

+0

@ Jus12 :'toString()'은 모든 클래스가 궁극적으로 상속받은'Object'를 상속받습니다. 모든 클래스는'toString()'을 오버라이드 (override) 할 수 있습니다. – Asaph

2

당신이 묻는 프로그래밍 언어 기능은 duck typing이며 Java는이를 지원하지 않습니다. 원래 래퍼 메서드 전략을 고수해야합니다.

1

번호 (추가 방법이없는 두 클래스의 가장 가까운 조상), 처음의 BigDecimal로 BigInteger를 변환 할 수 있기 때문에 : 말했습니다 한 바와 같이

new BigDecimal(bi) 
2

는, 자바는하지 않는다 "오리 두 가지 유형이 유용한 인터페이스를 공유하지 않는 "타이핑" BigDecimal과 BigInteger는 모두 Number를 확장하지만 add() 메서드는 해당 인터페이스의 일부가 아니므로 도움이되지 않습니다.

doSomething()의 메서드 매개 변수에서 작업중인 내용을 명시 적으로 지정해야한다고 생각합니다. 그런 다음 해봐요()는 두 가지 유형에서 작동하도록 설정을 무시 할 수

public BigDecimal doSomething(BigDecimal a, BigDecimal b) { 
     return a.add(b); 
} 

public BigInteger doSomething(BigInteger a, BigInteger b) { 
    BigDecimal x = new BigDecimal(a); 
    BigDecimal y = new BigDecimal(b); 
    BigDecimal z = doSomething(x, y); 
    return z.toBigInteger(); 
} 

두 번째 방법은 다음 첫 번째 방법에서 실제 로직을 호출 단순히 변환 방법이다.

+0

그 이후로 스칼라로 옮겼습니다. 스칼라에서 이런 것들은 매우 쉽습니다. def foo [T <: {def {T (a : T, b : T) : 단위; val a : T}] (bar : T) : T = ???' – Jus12