inheritance: is circle an ellipse?
Jan. 24th, 2011 11:46 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
It's a known puzzle from the depths of object-oriented teaching: is Circle a subclass or Ellipse. From school we know it is; but as we read in books, for programmers, it is not. How come? Oh, "Liskov principle". They use Liskov principle to scare kids.
Actually we know that a circle is an ellipse with both axes being the same length.
But in programming, an ellipse is something different. It is at least stretchable. And it is also moveable. Somehow it is not rotatable, but we can skip it for simplicity.
An ellipse in programming is (almost) always horizontal; it can be moved (by changing coordinates of its center) and it can be stretched/compressed by changing its height and width. Sure a stretchable ellipse is neither an ellipse nor a circle, not even a stretchable circle. A stretchable circle stretches equally in all directions.
That's it, no? Questions? Objections?
Actually we know that a circle is an ellipse with both axes being the same length.
But in programming, an ellipse is something different. It is at least stretchable. And it is also moveable. Somehow it is not rotatable, but we can skip it for simplicity.
An ellipse in programming is (almost) always horizontal; it can be moved (by changing coordinates of its center) and it can be stretched/compressed by changing its height and width. Sure a stretchable ellipse is neither an ellipse nor a circle, not even a stretchable circle. A stretchable circle stretches equally in all directions.
That's it, no? Questions? Objections?
no subject
Date: 2011-01-24 08:07 pm (UTC)BTW, when I was a kid, I was being scared by sqare-rectangle example, not circle-ellipse.
"pessimist is a well-informed optimist"
From:no subject
Date: 2011-01-24 08:23 pm (UTC)Liskov principle corresponds to contravariance.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2011-01-24 08:45 pm (UTC)В одной онтологии ont1:Круг и ont1:Эллипс могут быть отдельными классами, элементы которых частично пересекаются. В другой классы ont2:Круг и ont2:Эллипс не пересекаются - "если Круг, то уже не Эллипс". В третьей ont3:Круг явно описывается как подкласс ont3:Эллипс.
Разные определения эллипсов это разные классы, нельзя заявлять об их идентичности. Но тройка классов ont1:Круг, ont2:Круг и ont3:Круг содержит одни и те же элементы. Как и классы ont1:Эллипс и ont3:Эллипс содержат те же элементы, что объединение классов ont2:Эллипс и ont2:Круг.
Далее смотрим: про эллипсы нигде не указано, что они могут или не могут двигаться. Но даже подвижность и неподвижность могут рассматриваться и как возможности, и как ограничения. Тогда появляются, например, ont4:НеподвижныйЭллипс (пересечение классов ont4:Эллипс и ont4:НеподвижныйПримитив) или ont5:ПодвижныйЭллипс (пересечение классов ont5:Эллипс и ont5:ПодвижныйПримитив).
При переходе к архитектуре ПО выбор между ont4 и ont5 начинает сильно зависеть от используемых средств (языков программирования, etc). А верхняя онтология "что есть Примитив" (как онтология, API или описание формата данных) тоже может быть задана извне, где-то в требованиях по interoperability продукта.
А дальше - с чем удобнее работатьь в коде. Из первых трёх онтологий я бы выбрал ont1. :)
no subject
Date: 2011-01-24 09:05 pm (UTC)We do, but in schools they teach 'constant' circles and ellipses (functional style :-), so say, objects with quite limited interfaces. For which Liskov's works pretty well.
> sure a stretchable ellipse is neither an ellipse nor a circle
Stretchable ellipse is an ellipse. Why not?
> A stretchable circle stretches equally in all directions.
It may stretch unequally, but then it changes its type, if we are smart enough to implement consistently such a magic.
Bottom line: how would I design stuff like that? No idea. One approach is to abandon type system and use dynamic languages. If we want to have static type system... I have no idea whether such a thing has been designed already. Luca Cardelli might have wrote something about it. And... nobody said a perfect object-oriented type system is possible for design. OOP is not exactly about the real world, it is not promised to always work and always solve our problems, especially in compile time.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2011-01-24 09:18 pm (UTC)Вот у окружности есть центр (две координаты) и радиус (положительное число); у эллипса центр, две полуоси и (при большой удаче) угол наклона. Ага, значит, варьируя центр (две координаты) и радиус, можно из окружности получить другие окружности; варьируя центр, две полуоси и (при большой удаче) угол наклона, можно получить другие эллипсы, которые иногда вырождаются в окружности, которые можно опять превратить в эллипсы (а те, настоящие окружности, нельзя).
То есть для окружностей одни законы преобразования, для эллипсов другие, и удивительное дело — те и другие хорошо соответствуют внутреннему представлению данных. С чего бы это?
Ну, если мы пишем MS Paint, это нормально. Но в Paint эллипс и окружность не обязаны быть подтипами ни друг друга, ни чего-то третьего (разве что абстрактного типа Shape). Там это просто не нужно.
Настоящие геометрические программы (не Paint) часто применяют настоящие геометрические преобразования. Я знаю, я это десять лет программировал за кусок хлеба с маслом. Например, преобразование подобия, при которых эллипсы, не являющиеся окружностями, никогда ими и не становятся. Или, например, произвольные аффинные преобразования, при которых окружности свободно переходят в эллипсы, и тогда отдельная сущность для окружностей просто не нужна.
Настоящие геометрические программы производят и другие геометрически осмысленные действия — пересекают кривые и поверхности и прочее. Вот при такой работе с геометрией полезно выделить общие свойства у эллипса и окружности (это частные случаи, то есть подтипы, квадратичной кривой). Но у геометрических кривых никакой мутабельности, то есть объектно-ориентированного «поведения», нет. Никто там не растягивается и не сжимается.
Как-то так.
(no subject)
From:no subject
Date: 2011-01-24 09:51 pm (UTC)A circle cannot be a subclass, because eclipse can have radii of different lengths, but circles cannot.
An elipse cannot be a subclass, because circles know their radius, but elipses cannot (they do not even have such a concept).
(no subject)
From:(no subject)
From:no subject
Date: 2011-01-24 10:57 pm (UTC)Looks like this whole idea of designing class hierarchies is not very useful, other than as far as refactoring goes. With the addition of the "you ain't gonna need it" principle, that means that if you can make the code clearer/more compact, then use the inheritance, otherwise don't bother.
Also, I find myself using inheritance not at the design stage, but at the refactoring stage. Code it up first, extract superclasses later if that makes sense.
So, to me this question is more of a "how many angels can dance on the head of a pin?" thing.
(no subject)
From:(no subject)
From:no subject
Date: 2011-01-25 03:20 am (UTC)Thus, blindly transferring mathematical concepts to programming can create a lot of confusion.
Immutable circle is an immutable ellipse, and LSP here holds just fine. Mutable circle may or may not be a mutable ellipse, depending on the nature of allowed mutations. E.g. movable circle is a movable ellipse, but stretchable circle is not a stretchable ellipse, because a circle cannot be stretched the way an ellipse can be.
So, yes, you a right. The culprit is stretchability, as a particular case of mutability. This destroys the IS-A relationship between immutable objects.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2011-01-25 04:11 am (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From::-)
Date: 2011-01-25 08:01 am (UTC)movable и stretchable
Date: 2011-01-25 11:48 am (UTC)no subject
Date: 2011-01-25 01:07 pm (UTC)(no subject)
From:no subject
Date: 2011-01-27 02:30 pm (UTC)Описать интерфейс класса можно терминальной коалгеброй или изящнее, терминальной диалгеброй.
В таком понимании, вполне очевидно, что от класса "окружность" есть мономорфизм в "эллипс".
Правильно выше сказали - "долой классы, да здравствуют интерфейсы", с ними-то всё ясно.
(no subject)
From: