我有一个数学类,用于存储n个数组列表中表达式的表示 我目前有三个类AdditionArray MultipleArray和Variable它们都实现了我的Number接口。
public interface Number {
public Number Multiply(Number number);
实现Number i的类中的重载了像Multiply这样的操作
public class MultipleArray extends ArrayList<Number> implements Number{
public Number Multiply(AdditionArray number);
public Number Multiply(Number number){throw new Exception("woops");}
事情是java不会在运行时自动调用正确的重载函数。它接缝在编译时搞清楚
例如
Number someNumber = new MultipleArray();
Number someOtherNumber = new AdditonArray();
MultipleArray result2 = someNumber.Multiply(someOtherNumber); //calls the correct function
Number result2 = someNumber.Multiply(someOtherNumber); // throws the woops exception
为什么java会这样做。还有另一种方法可以实现这一点。某种工厂,例如?
干杯, 标记
答案 0 :(得分:2)
在Java中,重载是一种编译时多态,而重写是一种运行时多态。请参阅What is the difference between method overriding and method overloading in Java?。
这意味着编译器将始终在编译时确定要调用的两个重载方法中的哪一个,而不是被覆盖的方法(这些方法具有与子类中定义的相同签名的方法作为祖先类),可以动态调度到基于调用该方法的类的运行时类型。
答案 1 :(得分:1)
我并没有真正查看您的代码,只是为了回答您的主要问题--Java确实根据最近的类型确定在编译时调用的内容。如果它在运行时完成,它将是一种动态语言。
Java的功能非常快 - 但它在运行时没有考虑到它的速度,因此它获得了很多速度。它往往比Python快10倍,比Ruby快100倍。
如果你想要更灵活,我建议你根本不使用Java的绑定,而是创建一个“Operation”对象并手动将它绑定到你的“Numbers”。通过这种方式,您可以从对象中制作出非常酷的代数树。如果没别的话它很有趣 - 我已经完成了几次。它仍然会很快。
答案 2 :(得分:1)
正如Bill K所说,Java在编译时确定了这一点,这是设计的。
实现这一点的真正标准方法是在重载方法中使用超类型来检查子类的类型,并使用强制转换委托或者根据需要抛出异常。
使用Generics是另一种选择,它可以提高你的类型安全性,但是我对你的代码知之甚少,不知道它是否会全面运作。通用数字界面可能如下所示:
public interface Number<T extends Number> {
public T multiply(Number<? extends T> number);
}
泛型可能会在边缘变得奇怪,所以放弃类型安全性并检查参数类型可能是值得的。