我的讲师对里氏替换原理的定义是否不正确,或者我是否误解了?

发布于 2024-11-02 20:01:06 字数 726 浏览 0 评论 0原文

由于(里氏)替换原则,以下内容确实有效,该原则表示,如果需要某个类的实例的引用,那么您可以替换对该类的任何子类的实例的引用。

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

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

然后,我创建一个 Object 类型的 Object 引用变量,并将其指向 felix (Cat) 对象,该对象可以工作,但功能有限,如下所示JVM 现在看到的是 Object 类型的 felix 对象,因此,如果在 Cat 中定义了一个方法 purr()类,菲利克斯将无法再使用它。

因此,需要 Cat 类型的引用,但我们正在为 cat 类型的超类(而不是上面定义中所说的子类)提供引用,这是允许的,但要使用功能有限(除非您进行强制转换)。

我是正确的还是偏离的?

The following does work because of the (Liskov) substitution principle, which says that if a reference is expected of an instance of a certain class then you may substitute a reference to an instance of any subclass of that class.

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

Now, as far as I understand it, in this case, I am creating a Cat object (so memory space is being created in the heap), I am then assigning an object reference variable called "felix" to the newly created Cat object. The reference variable is of type Cat, and so, can only control Cat and any subclasses of Cat.

I am then creating an Object reference variable of type Object, and pointing it at felix (Cat) object, which works but with limited functionality as the JVM now sees the felix object of being of type Object, so, if for instance there was a method purr() defined in the Cat class, felix would no longer be able to use it.

So a reference is expected of the type Cat, but we are providing a reference for a superclass of type cat (rather than a subclass as it says in the definition above), and this is allowed, but with limited functionality(unless you do a cast).

Am I correct or way off ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尤怨 2024-11-09 20:01:06

你所做的与里氏替换原理没有什么关系。

这个原则是判断继承是否是一个好主意,或者使用继承是否是一个错误的规则。显然,每个对象都继承自“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() 方法会有所不同。

What you are doing has very little to do with the Liskov Substitution Principle.

This principle is a rule to know if an inheritance is a good idea, or if it's a mistake to use inheritance. Obviously, every objects inherits from "Object" : it's never a mistake to inherit from Object.

Here is an example where the LSP applies :

If you have :

abstract class Shape {
  abstract public area();
}

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

and

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

it's a mistake to think Shape2 inherits Shape1 (putting the "width" attribute as a common attribute) because the area() method will be different for Shape1 and Shape2.

━╋う一瞬間旳綻放 2024-11-09 20:01:06

在我看来,您是根据引用来思考,而不是根据对象来思考,这就是为什么您颠倒了规则的定义。

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

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

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

在您的示例中,T 是 Object,S 是 Cat代码>.当你有一个 T 类型的引用时,

Object copyCat;

替换原则说的是,这个引用可以指向 T 类型的对象或任何类型 T 的子类 S 类型的对象。因此,以下任一情况都是有效的:(

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

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

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

It seems to me that you are thinking in terms of the references, not in terms of the objects, and that is why you are inverting the definition of the rule.

Quoting Wikipedia's version of the principle:

if S is a subtype of T, then objects
of type T may be replaced with objects
of type S

(which seem to say the same thing as the definition you provided, which I take it is from your instructor)

In your example, T is Object, and S is Cat. When you have a reference of type T

Object copyCat;

what the substitution principle says is that this reference can point to an object of type T or of any type S that is a subclass of type T. So either of the following would be valid:

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

(and since we're using Object here, which is by definition a superclass of any Java class, the copyCat reference could point to any type of object at all.)

I think an important point here is that the type of the reference determines what methods can be called, regardless of what methods the actual object pointed to supports. This is why an instance of any subclass can be assigned to the reference.

灯角 2024-11-09 20:01:06

它表示 Cat 类是 Object 类的有效替代品。因此,每当某个方法需要 Object 类型的对象时,您都可以替换 Cat 类型的对象。

What it says is that the Cat class is a valid substitute for the Object class. So that anytime some method needs an object of type Object, you can substitute an object of type Cat.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文