访问泛型类型的静态字段

Khu*_*rya 6 java generics inheritance interface

我是否可以要求实现接口的类具有某个静态字段或方法,并通过泛型类型参数访问/调用该字段或方法?

我有一个接口,Arithmetical<T>它指定了几个函数,如T plus(T o)T times(T o).我也有一个Vector<N extends Arithmetical<N>>类,它用于具有类型组件的向量(可变维度)N.然而,当我尝试实现点积时,我遇到了一个问题.

我想实现这个方法N dot(Vector<N> o).对于这一点,我打算开始与任何N的零是通过这两个迭代Vector<N>S' List<N>S,将每一对元素的产品给我的总.有没有一种方法可以指定Arithmetical<T>所有实现类必须有一个静态(最好是最终的)字段,ZERO并且开始dot(Vector<N> o)的主体有一些类似的东西N sum = N.ZERO;

如果没有,那么这个问题还有什么其他方法呢?我想允许0维向量,所以我不能仅仅通过将向量的第一个组件相乘来开始.有没有办法实例化泛型类型的对象,所以我只能指定一个T zero()方法Arithmetical<T>

我有理由不使用Java的数字类型 - 我希望有复杂组件的向量.

这是算术:

public interface Arithmetical<T> {
    public T plus(T o);
    public T minus(T o);
    public T negate();
    public T times(T o);
    public T over(T o);
    public T inverse();
    // Can I put a line here that requires class Complex (below) to define ZERO?
}
Run Code Online (Sandbox Code Playgroud)

向量:

public class Vector<N extends Arithmetical<N>> {

    private List<N> components;
    public Vector<N>(List<N> cs) {
        this.components = new ArrayList<N>(cs);
    }

    public N dot(Vector<N> o) {
        // Here's where I need help.
    }

}
Run Code Online (Sandbox Code Playgroud)

复杂:

public class Complex implements Arithmetical<Complex> {

    public static final Complex ZERO = new Complex(0, 0); // Can I access this value through N if <N extends Arithmetical<N>>?

    private double real;
    private double imag;
    public Complex(double r, double i) {
        this.real = r;
        this.imag = i;
    }

    /* Implementation of Arithmetical<Complex> (and some more stuff) not shown... */

}
Run Code Online (Sandbox Code Playgroud)

我对Java(以及一般的编程)很陌生; 我可能不会理解复杂的(ha)解释和解决方法.

谢谢!

(Python是建议的标签...... 嗯.)

rge*_*man 6

每种可能的实现类型都需要"零".接口中的常量不会,因为常量不能被覆盖并且必须保持不变.

解决方案是为您的Arithmetical界面添加一个新方法:

public T zero();
Run Code Online (Sandbox Code Playgroud)

每个实现都被迫实现它并返回自己的零版本.在这种情况下,您将其用作添加的起点; 这是附加的身份.

Complex类的实现是这样的.

@Override
public Complex zero() {
    return ZERO;
}
Run Code Online (Sandbox Code Playgroud)

如果你的实例是可变的,那么不要使用常量; 刚刚返回new Complex(0, 0).

另一个想法是借用-ing项目Stream时的操作reduce并将它们组合到一个项目中 - 获取表示初始状态的标识值,即没有收集的项目 - 零.

public N dot(Vector<N> o, N identity) {
    N dotProduct = identity;
    // Perform operations on each item in your collection
    // to accumulate and return a dot product.
}
Run Code Online (Sandbox Code Playgroud)

调用者必须提供标识值.

Complex dotProduct = vectorOfComplex.dotProduct(otherVector, new Complex(0, 0));
Run Code Online (Sandbox Code Playgroud)