2011-04-19 15 views
3

由于(Liskov)替换原则,下列方法确实起作用,它说如果希望某个类的实例有引用,那么您可以将引用替换为该类的任何子类的实例。我的讲师对Liskov替换原则的定义不正确,还是我误解?

public static void main(String[] args) { 
Cat felix = new Cat(); 
Object copyCat = felix; 
} 

现在,据我所知,在这种情况下,我创建一个Cat对象(因此存储器空间被在堆中创建),我然后分配称为“菲利克斯”一个对象引用变量到新创建的Cat对象。参考变量的类型为Cat,因此只能控制CatCat的任何子类。

我然后创建Object类型的Object参考变量,并且在费利克斯指向它(Cat)对象,它具有有限功能的工作原理,但作为JVM现在看到的是Object类型的菲利克斯对象,因此,如果用于例如Cat类中定义的方法purr(),felix将不再能够使用它。

因此,期望Cat类型的参考,但是我们提供了cat类型的超类(而不是像上面定义中所述的子类)的引用,并且这是允许的,但功能有限除非你做演员)。

我是正确还是离开?

+2

当然'felix'仍然可以发声,但'copyCat'不能。内存不变,但不同的类型告诉编译器如何看待这段内存。 – DarkDust 2011-04-19 12:18:00

回答

2

你在做什么与Liskov替代原则很少有关。

这个原则是知道继承是一个好主意,还是使用继承是错误的规则。显然,每个对象都从“对象”继承:从Object继承是永远不会失误的。

这里就是LSP适用的例子:

如果您有:

abstract class Shape { 
    abstract public area(); 
} 

class Shape1 extends Shape { 
    private width; 
    (...) 
} 

class Shape2 extends Shape { 
    private width; 
    private length; 
    (...) 
} 

它认为Shape2继承Shape1一个错误(把 “宽度”属性作为通用属性),因为Shape1和Shape2的area()方法将不同。

0

它说的是Cat类是Object类的有效替代品。因此,任何时候某个方法需要一个Object类型的对象时,您可以替换Cat类型的对象。

1

在我看来,你在考虑引用,而不是在对象方面,这就是为什么你要颠倒规则的定义。

引用Wikipedia的版本的原理:

如果S是T的子类型,则对象类型T的 可以用型S的对象 替换

(这似乎与你提供的定义相同,我认为它是来自你的教师)

在你的例子中,T是Object,而S是Cat。当你有类型T的参考

Object copyCat; 

什么代换原则说的是,这个引用可以指向类型T的或任何类型为S就是类型T的子类的对象所以下面的任是有效的:

copyCat = new Object(); 
copyCat = new Cat(); 

(因为我们正在使用Object在这里,这是定义的任何Java类的父类,在copyCat参考可能指向任何类型的对象在所有)

我认为重要的一点这里的引用类型决定了可以调用什么方法,而不管实际对象指向的方法是什么。这就是为什么可以将任何子类的实例分配给引用的原因。

相关问题