开发者

Is my lecturers definition of the Liskov Substitution Principle incorrect, or am I misunderstanding?

开发者 https://www.devze.com 2023-02-26 16:02 出处:网络
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

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 t开发者_StackOverflow社区ype 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 ?


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消