2013-06-03 4 views
3

Java에서 제네릭 클래스를 수행하려고합니다. 일부 가이드를 읽었을 때이를 선언하는 방법과 해당 기능을 호출하는 방법도 발견했습니다.일반 클래스 - 연산자 문제

내 클래스는 포인트 앤 방법없이이 방법으로 다음과 같습니다

class Pnt<type>{ 
    protected type x, y; 
    protected int col; 
} 

이제 나는 add 방법을 만들려고 노력하고있어,하지만 난 그것을 할 수 없습니다입니다. 내가 뭘하려

은 다음과 같습니다

void add(type x_, type y_){ 
    x += x_; 
    y += y_; 
    } 

IDE는 +=type 변수에 대한 정의라고 소리지르는 ...

나는 자바에서 new 연산자를 정의 할 수없는 것을 알고 C++에서와 마찬가지로 두 개의 변수를 추가하는 다른 방법을 묻습니다. type 변수!

P. 내가 사용할 모든 타입은 doubles, floats 그리고 int egers가 될 것입니다. 그래서 나는 간단한 중독을하려고합니다.

답변

1

두 가지 문제점이 있습니다. 첫째, 속도가 빠르면 프리미티브를 직접 사용해야하며 제네릭에서는 매개 변수로 지원되지 않습니다. 이는 Point에 대해 세 가지 버전을 별도로 유지 관리해야한다는 것을 의미합니다.

당신이 제네릭을 사용하려는 경우, 해당 클래스 (같은 Integer)를 사용할 수 있지만, 한 가지 문제는 여전히 존재한다 : 그들의 슈퍼 타입 Numberadd 방법 (고사하고 + 운영자 또는 +=)를 가지고 있지 않습니다.

class NumericPoint<T extends Number> { 
    public final Numeric<T> x; 
    public final Numeric<T> y; 

    public NumericPoint(Numeric<T> _x, Numeric<T> _y) { 
     super(); 
     this.x = _x; 
     this.y = _y; 
    } 

    public NumericPoint<T> add(NumericPoint<T> other) { 
     return new NumericPoint<T>(this.x.add(other.x), this.y.add(other.y)); 
    } 

    @Override 
    public String toString() { 
     return "(" + this.x + "/" + this.y + ")"; 
    } 
} 

: 당신이 적어도 일반적인 점을 구현할 수 있습니다이를 바탕으로

abstract class Numeric<T extends Number> { 
    public abstract T getValue(); 

    public abstract Numeric<T> add(Numeric<T> other); 

    @Override 
    public String toString() { 
     return getValue().toString(); 
    } 
} 

class MyInt extends Numeric<Integer> { 
    public final Integer value; 

    public MyInt(Integer _value) { 
     super(); 
     this.value = _value; 
    } 

    @Override 
    public Integer getValue() { 
     return this.value; 
    } 

    @Override 
    public Numeric<Integer> add(Numeric<Integer> other) { 
     return new MyInt(this.value + other.getValue()); 
    } 
} 

class MyDouble extends Numeric<Double> { 
    public final double value; 

    public MyDouble(Double _value) { 
     super(); 
     this.value = _value; 
    } 

    @Override 
    public Double getValue() { 
     return this.value; 
    } 

    @Override 
    public Numeric<Double> add(Numeric<Double> other) { 
     return new MyDouble(this.value + other.getValue()); 
    } 
} 

:

그래서 내가 알고있는 유일한 방법은 add 방법을 지원 자신의 숫자 클래스 계층 구조를 구현하는 것입니다 함께 사용하십시오

NumericPoint<Integer> ip1 = 
    new NumericPoint<Integer>(new MyInt(1), new MyInt(2)); 
NumericPoint<Integer> ip2 = 
    new NumericPoint<Integer>(new MyInt(3), new MyInt(4)); 
NumericPoint<Integer> ip = ip1.add(ip2); 
System.out.println(ip); 

NumericPoint<Double> dp1 = 
    new NumericPoint<Double>(new MyDouble(1.1), new MyDouble(2.1)); 
NumericPoint<Double> dp2 = 
    new NumericPoint<Double>(new MyDouble(3.1), new MyDouble(4.1)); 
NumericPoint<Double> dp = dp1.add(dp2); 
System.out.println(dp); 

나는 귀하의 견본을 수정했습니다. le : 숫자와 점은 불변입니다입니다. 예를 들어 BigDecimal과 같이 구현됩니다.따라서 add 메서드는 제네릭 클래스에 속하며 새 인스턴스를 반환합니다.

+0

무겁고, 무겁고, 나는 3 개의 다른 클래스를 대신 가질 것이다라고 생각한다. 불행하게도 그것은 나의 요구에 맞지 않는다. 그러나 헤이! 당신이 가능하게 만들었습니다! = D – ingroxd

+0

동의합니다. 무겁습니다. 이 문제를 해결하는'C++ templates '입니다 (C++ 템플릿은'int'를 템플릿 매개 변수로 허용합니다). – Beryllium

+0

그래,하지만 Processing은 C++을 지원하지 않습니다! – ingroxd

3

class Pnt<type>이라고 말하면 ti는 type이 개체이며 int 또는 double과 같은 원시 데이터 형식이 아니라는 것을 의미합니다. int, float 등과 같은 숫자 원시 데이터 형식에 대해서는 += 연산을 수행 할 수 있지만 개체에는 수행 할 수 없습니다. 실제로 모든 일반 객체로 += 작업을 수행 할 수 없습니다.

Integer, Float 등의 객체는 래퍼 클래스이고 기본 유형을 언 박싱하고 나중에 자동 저장되므로 += 연산자를 지원합니다. 그러나 컴파일러는 typeInteger 또는 Float이 될지 확인할 방법이 없습니다. 따라서 컴파일 시간 오류가 발생합니다.

+0

오브젝트 유형과도 작동하지 않습니다. 실제로이 명령문은 x + = x_에서 실패합니다. 이상합니다. 나는 그것이 프리미티브와 아무런 관련이 없다고 생각한다. – ankurtr

+0

그게 왜'double' 대신에'Double'을 사용해야하는지 설명합니다 ... 하지만'Double','Float' 및'Integer' 객체는'+ ='중 하나를 지원합니다! – ingroxd

+0

네,'Integer'는'+ ='연산자를 지원하지만, 컴파일러는'type'이'Integer'인지 여부를 확인할 방법이 없습니다. 'File' 또는 다른 클래스가 될 수 있습니다. –