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变量

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

PS我将使用的所有类型都是doubles,floats和integers,这就是为什么我试图让一个简单的上瘾。

4

2 回答 2

3

当您说class Pnt<type>ti 时,表示它type是一个对象,而不是像intor这样的原始数据类型double。您可以+=对数字原始数据类型(如intfloat等)执行操作,而不是对对象执行操作。事实上,您无法+=使用任何通用对象执行操作。

Integer,等的对象Float支持+=操作符,因为它们是包装类,并被拆箱为原始类型并在以后自动装箱。但是编译器无法确认type将是Integeror Float。因此,它会生成编译时错误。

于 2013-06-03T16:36:44.067 回答
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方法属于泛型类,它返回一个新实例。

于 2013-06-03T19:05:56.790 回答