juan_gandhi: (Default)
[personal profile] juan_gandhi
Year 1999 Definition: "Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T."

Original definition looked like this: if for each object o of class S there is an object o1 of class T such that in any program expressed in terms of T o1 can be replaced with o without altering the behavior, then S is a subtype of T.

Which means, you cannot put additional restrictions on a subclass. That is, in programming, a square is not a rectangle - but a parallelepiped is, which is, of course against all our intuition.

How come?

The problem is that in programs objects may change. If they were not, we could safely substitute, in any formula involving a parallelepiped, a parallelepiped P with a cube C, and it will still be valid. If the object does not change, its timeline can be reduced to a point. But for things that change, things change.

Say, we have a parallelepiped that is being deformed; at one moment it can become a cube, but there's no quaranty it will remain one forever. In programming terms, a piece of code may change the length of the parallelepiped, and expect that other dimensions remain the same.

Following this principle, a Timestamp is Java is a subclass of Date, and SortedSet is a subinterface of Set - they add new structure but do not (vaguely speaking) add any new restrictions.

Date: 2007-04-10 10:10 pm (UTC)
From: [identity profile] 109.livejournal.com
"subclass - superclass" relationship is also called "generalization - specialization" one. which makes alleged problem of "additional restrictions" a non-issue. of course specialized class is "more restrictive"; it can only cover a subset of what superclass can cover. so yes, квадрат - это сабкласс прямоугольника, а прямоугольник - сабкласс четырёхугольника. при чём тут параллелепипед - вообще непонятно, он вообще из другой ветки - из ветки трёхмерных фигур.

Date: 2007-04-10 10:49 pm (UTC)
From: [identity profile] ex-ex-zhuzh.livejournal.com
«квадрат - это сабкласс прямоугольника»

рассказывают, один военрук давал такое определение эллипса: «эллипс — это круг, вписанный в квадрат со сторонами 3 на 4». это можно смоделировать следующим образом:

Rectangle r; r.setSides (3, 4); // прямоугольник 3х4
Square s; s.setSides (3, 4); // квадрат 3х4

у военрука, правда, отношение суб/супер инвертировано, но разницы на самом деле мало.

Date: 2007-04-11 01:30 am (UTC)
From: [identity profile] 109.livejournal.com
да ну всё просто же. если мы непременно хотим замоделировать отношение между прямоугольником и квадратом через наследование, мы либо должны быть готовы, что setSides бросит эксепшн, либо вместо него иметь отдельные методы setHeight, setWidth.

в общем виде, если один потомок умеет процессировать сообщения А и Б, а другой потомок - Б и В, то мы либо объявляем, что processMessage() в родителе принимает А, Б и В, но мы в случае чего готовы получить и обработать исключение, либо мы в родителе объявляем, что готовы принимать только Б, а если вам надо послать А или В - это ваши проблемы. в зависимости от размера пересечения множеств более полезным будет либо один, либо другой подход. например, если у нас есть третий потомок, который умеет обрабатывать только А и В, то полезность второго подхода устремляется к нулю (родительский processMessage не может гарантированно принять ничего).

Date: 2007-04-11 03:36 pm (UTC)
From: [identity profile] ex-ex-zhuzh.livejournal.com
//если мы непременно хотим замоделировать отношение между прямоугольником и квадратом через наследование//

так мы не непременно хотим. мы хотим понять, как надо. в частности, кто нам сказал, что у квадрата и прямоугольника должен быть какой-то нетривиальный общий родитель? откуда мы его взяли?

Date: 2007-04-11 06:11 pm (UTC)
From: [identity profile] 109.livejournal.com
мы хотим понять, как надо.

а в рамках ООД выбора особенного нет.

общий родитель взялся от того, что у них обоих по 4 стороны и все углы прямые.

Date: 2007-04-11 09:43 pm (UTC)
From: [identity profile] ex-ex-zhuzh.livejournal.com
//общий родитель взялся от того, что у них обоих по 4 стороны и все углы прямые.//

почему от этого должен браться общий родитель? кто нам это сказал? общий родитель бывает, когда у двух объектов есть методы, которые мы готовы считать попарно «одинаковыми» (в том смысле, что объекты «одинаково» реагируют на «одинаковые» вызовы). пока неясно, как из одинакового количества углов следует одинаковость методов.

Date: 2007-04-11 09:51 pm (UTC)
From: [identity profile] 109.livejournal.com
общий родитель может случиться, когда есть что-то общее. а уж методы, или данные, или что-то ещё - это детали.

пример: в обоих классах есть совершенно одинаковый кусок некой сложной логики. сам по себе этот кусок не экспозится наружу в виду публичного метода. то, что экспозится - отличается. тем не менее, вполне может иметь смысл выделить этот кусок и запихнуть в родителя в виде protected метода, который будет вызывать ребёнко-специфичные вещи, определённые в родителе как абстрактные. это, на самом деле, и есть основная причина появления на свет родителей, и иерархий вообще, а не "у двух объектов есть методы, которые мы готовы считать попарно одинаковыми".

Date: 2007-04-11 10:16 pm (UTC)
From: [identity profile] ex-ex-zhuzh.livejournal.com
ага, вот тут и появляются отличия иерархии классов от иерархии типов. типа, классика ;) когда пересекаются интерфейсы, это одно дело, а когда имплементации, совсем другое.

Date: 2007-04-12 01:19 am (UTC)
From: [identity profile] 109.livejournal.com
интерфейсы тут как бы совсем ни при чём. с интерфейсами вообще никаких проблем нет, кроме, может быть, алмазного наследования.

вспомним, что изначальная проблема, таковой на самом деле не являющаяся, возникла при рассмотрении метода setSides(x, y). имплементации, то бишь.

Date: 2007-04-11 09:24 am (UTC)
From: [identity profile] cmm.livejournal.com
> Which means, you cannot put additional restrictions on a subclass.

this is incorrect.
as long as the subclass plays well with all the protocols with which its parent plays well (i.e. instances of it are freely substitutable for instances of the parent within the relevant context), it can have any additional restrictions it wants.

in general, viewing such problems in the "protocol compatibility" frame of discourse tends to make thinking about them easier.

Date: 2007-04-11 04:42 pm (UTC)
From: [identity profile] furia-krucha.livejournal.com
Which means, you cannot put additional restrictions on a subclass.
Данные цитаты, вообще-то, говорят о подтипах, а не подклассах. Разумеется, это в общем случае разные иерархии. Квадрат может быть реализован как подкласс прямоугольника, но его подтипом являться не будет.

Date: 2007-04-12 01:49 am (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Это верно; спасибо. У меня довольно мутно получилось... ну, я просто пытался рассуждать.

Date: 2007-04-16 09:41 pm (UTC)
From: [identity profile] ex-chrobin.livejournal.com
Original definition looked like this: if for each object o of class S there is an object o1 of class T such that in any program expressed in terms of T o1 can be replaced with o without altering the behavior, then S is a subtype of T.
вот это вот can be replaced же только в контравариантных позициях верно, разве нет?

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

May 2025

S M T W T F S
    1 2 3
456 7 8 9 10
11 121314151617
181920 21 222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 25th, 2025 11:05 pm
Powered by Dreamwidth Studios