您可以使用双重调用。没有承诺这是一个更好的解决方案,但它是一个替代方案。
代码示例
import java.util.HashMap;
public class Example {
public static void main(String[] argv) {
Example ex = new Example();
ICacheable[] cacheableObjects = new ICacheable[]{new MyObject(), new OtherObject()};
for (ICacheable iCacheable : cacheableObjects) {
// depending on whether the object is a MyObject or an OtherObject,
// the .put(Example) method will double dispatch to either
// the put(MyObject) or put(OtherObject) method, below
iCacheable.put(ex);
}
System.out.println("myObjects: "+ex.myObjects.size());
System.out.println("otherObjects: "+ex.otherObjects.size());
}
private HashMap<String, MyObject> myObjects = new HashMap<String, MyObject>();
private HashMap<String, OtherObject> otherObjects = new HashMap<String, OtherObject>();
public Example() {
}
public void put(MyObject myObject) {
myObjects.put(myObject.getKey(), myObject);
}
public void put(OtherObject otherObject) {
otherObjects.put(otherObject.getKey(), otherObject);
}
}
interface ICacheable {
public String getKey();
public void put(Example ex);
}
class MyObject implements ICacheable {
public String getKey() {
return "MyObject"+this.hashCode();
}
public void put(Example ex) {
ex.put(this);
}
}
class OtherObject implements ICacheable {
public String getKey() {
return "OtherObject"+this.hashCode();
}
public void put(Example ex) {
ex.put(this);
}
}
这里的想法是 - 而不是强制转换或使用instanceof
- 您调用iCacheable
对象的.put(...)
方法,该方法将自身传递回Example
对象的重载方法。调用哪个方法取决于该对象的类型。
另请参阅访问者模式。我的代码示例有异味,因为该ICacheable.put(...)
方法没有凝聚力 - 但是使用访问者模式中定义的接口可以清除这种异味。
为什么我不能直接this.put(iCacheable)
从Example
课堂上打电话?
在 Java 中,覆盖总是在运行时绑定,但重载稍微复杂一些:动态调度意味着方法的实现将在运行时选择,但方法的签名仍然在编译时确定。(查看Java 语言规范,第 8.4.9 章了解更多信息,还可以查看Java Puzzlers书第 137 页上的谜题“Making a Hash of It” 。)