泛型类 - 运算符问题

时间:2013-06-03 16:31:31

标签: java operator-keyword generics

我正在尝试用Java做一个泛型类。 阅读一些指南,我找到了如何声明它以及如何调用它的功能。

我的课程是一个重点,没有方法就是这样:

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

现在,我正在尝试制作add方法,但我无法做到。

我尝试的是:

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

IDE对我大吼大叫+=未定义type变量......

我知道在Java中不可能像在C ++中那样定义一个新的运算符,所以我要求另一种方法来添加两个type变量!

P.S。我将使用的所有类型都是double s,floatint egers,这就是我试图制作简单瘾的原因。

2 个答案:

答案 0 :(得分:3)

当您说class Pnt<type>时,ti表示type是一个对象,而不是intdouble等原始数据类型。您可以对+=int等数字原始数据类型执行float操作,而不是对象。实际上,您无法使用任何通用对象执行+=操作。

IntegerFloat等对象支持+=运算符,因为它们是包装类,并且将取消装箱到原始类型并稍后自动装箱。但编译器无法确认type将是Integer还是Float。因此,它会生成编译时错误。

答案 1 :(得分:1)

有两个问题:首先,如果它应该很快,你必须直接使用基元,并且这些不作为泛型中的参数支持。这实际上意味着您必须分别为Point维护三个版本。

如果你想使用泛型,你可以使用相应的类(如Integer),但仍有一个问题:他们的超级类型Number没有add方法(更不用说+运算符或+=)。

所以我知道的唯一方法是实现你自己的支持add方法的数字类层次结构:

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());
    }
}

基于此,您可以实现至少一个通用点:

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

一起使用
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);

我修改了你的例子:数字和点是不可变的。它的实现方式与BigDecimal类似。因此add方法属于泛型类,它返回一个新实例。