我的讲师对Liskov替代原则的定义是否不正确,还是我误解了?

时间:2011-04-19 12:01:37

标签: java object reference liskov-substitution-principle

以下是可行的,因为(Liskov)替换原则,即如果期望引用某个类的实例,那么您可以将引用替换为该类的任何子类的实例。

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

现在,据我所知,在这种情况下,我正在创建一个Cat对象(因此在堆中创建了内存空间),然后我分配了一个名为“felix”的对象引用变量到新创建的Cat对象。引用变量的类型为Cat,因此,只能控制CatCat的任何子类。

然后我创建一个类型为Object的{​​{1}}引用变量,并将其指向felix(Object)对象,该对象工作但功能有限,因为JVM现在看到了felix属于Cat类型的对象,因此,如果Object类中定义了方法purr(),则felix将无法再使用它。

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

我是正确还是离开?

3 个答案:

答案 0 :(得分:2)

你所做的事与Liskov Substitution Principle没什么关系。

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

以下是LSP适用的示例:

如果你有:

abstract class Shape {
  abstract public area();
}

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

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

认为Shape2继承Shape1(将“width”属性作为公共属性)是错误的,因为对于Shape1和Shape2,area()方法会有所不同。

答案 1 :(得分:1)

在我看来,你正在考虑引用,而不是根据对象,这就是你反驳规则定义的原因。

引用维基百科的原则版本:

  

如果S是T的子类型,则为对象   T型可以用物体代替   S型

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

在您的示例中,T为Object,S为Cat。如果您有类型T的引用

Object copyCat;

替换原则所说的是这个引用可以指向类型为T的对象,或者是类型为T的子类的任何类型的S。所以下列任何一个都是有效的:

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

(因为我们在这里使用Object,根据定义,它是任何Java类的超类,copyCat引用可以指向任何类型的对象。)

我认为这里重要的一点是,无论实际对象指向哪种方法支持,引用的类型都决定了可以调用哪些方法。这就是为什么可以将任何子类的实例分配给引用。

答案 2 :(得分:0)

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

类型的对象