【发布时间】:2015-04-29 22:45:22
【问题描述】:
假设我有以下课程:
public class MyClass {
/* Note: Timestamp extends date */
public doSomething(java.sql.Timestamp timestamp){
System.out.println("Timestamp");
...
}
public doSomething(java.util.Date date){
System.out.println("Date");
...
}
}
假设我现在像这样练习我的代码:
MyClass myClass = new MyClass();
Date realDate = new Date();
Timestamp timestamp = new Timestamp(0);
Date casted = new Timestamp(0);
myClass.doSomething(realDate); // prints Date
myClass.doSomething(timestamp); // prints Timestamp
myClass.doSomething(casted); // prints Date!!!!! What?!
我遇到的问题是,由于casted 实际上不是日期,所以当我使用它时它不起作用。
除此之外:通常,子类不工作应该不是问题,但是 Timestamp 的 javadoc 说:
由于上面提到的 Timestamp 类和 java.util.Date 类之间的差异,建议代码不要将 Timestamp 值一般视为 java.util.Date 的实例。 Timestamp 和 java.util.Date 的继承关系实际上是实现继承,而不是类型继承。
我知道我可以这样做:
public doSomething(java.util.Date date){
if(date instanceof type){
System.out.println("Timestamp");
...
}
System.out.println("Date");
...
}
但这看起来很讨厌。
有没有办法在不使用巨大的 switch 语句的情况下让子类的方法重载工作?
编辑:简而言之,Timestamp 似乎打破了Liskov substitution principle - 正如@Mick Mnemonic 所指出的那样。
【问题讨论】:
-
这是方法重载如何正确工作。方法重载是在编译时而不是运行时选择的。
-
(此外,正是由于这个原因,
foo(subtype)的行为与foo(supertype)不同,这通常被认为是一种严重的设计气味。) -
@LouisWasserman - 我不认为这是 我的 设计缺陷。我认为时间戳的作者是缺陷作者。你也读过吗?
-
这就是你引用的文档所说的,是的 - 你永远不应该将
Timestamp分配给Date。 -
简而言之,
Timestamp(还有java.sql.Date)打破了Liskov substitution principle。
标签: java oop inheritance polymorphism