我确信我以错误的方式处理这个问题,但是我想实现一个通用模式,其中某个类的实例代表集合的元素,并且该类的静态方法给出以下属性集合作为一个整体。我一开始只有一个类,因此只有一组,但我想将其扩展到类似的组,并拥有适用于所有类的通用方法。我正在考虑创建更多的类并让它们都扩展相同的接口(interface),但这将涉及指定静态方法的接口(interface)和覆盖它们的实现类。
我认为这个问题最好用群论来解释。对于那些不知道的人来说,群是一个数学对象,包含一组元素以及组合两个元素并返回第三个元素的群运算(用 * 表示)。在其他条件中,必须有一个单位元素 e,使得对于所有 e,a * e = a,并且每个元素 a 必须有一个逆 ai,使得 a * ai = e。最简单的例子是整数,其中加法是群运算,单位元素为零,元素的逆是其否定。如果我有一个操作组元素的泛型类,则在某些情况下我需要知道该组的标识元素是什么。
所以我的组示例界面可能类似于
public interface GroupElement {
public GroupElement operate(GroupElement element);
public static GroupElement identity();
}
整数实现是这样的(忽略与预先存在的 Integer 类的明显冲突):
public class Integer implements GroupElement {
private int i;
public Integer(int i) {
this.i = i;
}
public Integer operate(Integer other) {
return new Integer(i + other.i);
}
public static Integer identity() {
return new Integer(0);
}
}
然后是一个通用对象,用于检查一个元素是否是另一个元素的逆:
public class InverseChecker <E implements GroupElement> {
public boolean isInverse(e element1, e element2) {
return element1.operate(element2).equals(E.identity());
}
}
显然上面的代码有很多错误。第一个问题是我无法在接口(interface)中声明静态方法,即使我使用抽象父类,子类也无法覆盖静态方法。我可以将 Identity() 方法设为非静态,但随后我需要一个我并不总是拥有的实例。另外,我也无法从泛型类型 E 调用静态方法。我想我可以创建两个接口(interface),一个用于组,一个用于组的元素,但是看起来这确实会使 InverseChecker 对象之类的代码变得复杂(所有内容都需要两个类型参数,我将不得不重新编写我的很多代码,我不确定如何指定两个接口(interface)之间的关系)。另外,我刚刚意识到,在输入此内容时,构建界面的方式必须允许来自不同组的两个元素之间的组操作,这是没有意义的。那么,实现这种结构的正确方法是什么呢?
最佳答案
这里的解决方案——事实上就是这样——是从不同的方向看待事物。该组应该是与其元素分开的对象,并且组对象应该有一个 T operate(T, T)
和一个 T identity()
方法。
换句话说,停止尝试拥有 GroupElement
接口(interface)并有一个 Group
界面。
此外,泛型可能会简化问题:a Group<T>
具有 T
类型的元素.
关于java - 我知道抽象/重写的静态方法在 Java 中是不可能的,但我的代码似乎需要它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14225515/