Правильно ли сформулировано моим лектором определение принципа подстановки Лискова или я неправильно понял? - PullRequest
3 голосов
/ 19 апреля 2011

Следующее работает из-за принципа подстановки (Лискова), который говорит, что если ожидается ссылка на экземпляр определенного класса, вы можете заменить ссылку на экземпляр любого подкласса этого класса.

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

Теперь, насколько я понимаю, в данном случае я создаю объект Cat (поэтому в куче создается пространство памяти), затем я назначаю переменную ссылки на объект, называемую "felix"."к только что созданному Cat объекту.Ссылочная переменная имеет тип Cat, и поэтому может управлять только Cat и любыми подклассами Cat.

. Затем я создаю Object ссылочную переменную типа Object, иуказывая его на объект felix (Cat), который работает, но с ограниченными функциональными возможностями, поскольку JVM теперь видит объект felix типа Object, поэтому, если, например, в * 1016 был определен метод purr()* class, felix больше не сможет его использовать.

Так что ожидается ссылка на тип Cat, но мы предоставляем ссылку на суперкласс типа cat (а не на подкласс, так какговорится в определении выше), и это разрешено, но с ограниченными функциональными возможностями (если вы не выполняете приведение).

Я прав или нет?

Ответы [ 3 ]

2 голосов
/ 19 апреля 2011

То, что вы делаете, имеет мало общего с принципом подстановки Лискова.

Этот принцип является правилом, позволяющим узнать, является ли наследование хорошей идеей или ошибочно использовать наследование. Очевидно, что каждый объект наследует от «Объекта»: никогда не ошибочно наследовать от Объекта.

Вот пример, где применяется LSP:

Если у вас есть:

abstract class Shape {
  abstract public area();
}

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

и

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

Ошибочно думать, что Shape2 наследует Shape1 (помещая атрибут "width" в качестве общего атрибута), потому что метод area () будет различным для Shape1 и Shape2.

1 голос
/ 19 апреля 2011

Мне кажется, что вы думаете с точки зрения ссылок, а не с точки зрения объектов, и именно поэтому вы инвертируете определение правила.

Цитирую версию принципа из Википедии:

если S является подтипом T, то объекты типа T можно заменить объектами типа S

(которые, кажется, говорят то же самое, что и определение, которое вы дали, я полагаю, это от вашего инструктора)

В вашем примере T - Object, а S - Cat. Когда у вас есть ссылка типа T

Object copyCat;

принцип подстановки говорит о том, что эта ссылка может указывать на объект типа T или любого типа S, который является подклассом типа T. Поэтому допустимо любое из следующего:

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

(и поскольку мы используем Object здесь, который по определению является суперклассом любого класса Java, ссылка copyCat может вообще указывать на любой тип объекта.)

Я думаю, что важным моментом здесь является то, что тип ссылки определяет, какие методы могут быть вызваны, независимо от того, какие методы поддерживает реальный объект, на который указывает объект. Вот почему экземпляр любого подкласса может быть присвоен ссылке.

0 голосов
/ 19 апреля 2011

Это говорит о том, что класс Cat является допустимой заменой класса Object.Так что в любое время для какого-либо метода требуется объект типа Object, вы можете заменить объект типа Cat.

...