たまにはOOP

定期的にAda 95のRationaleを読み返したくなります。

http://web.archive.org/web/20020607043031/http://www.tsujiken.ee.kogakuin.ac.jp/jada95_02.html

このRectangle(四角)からCuboid(立方体)を派生させる例、OOPの入門としては犬猫動物並によくあると思うのですが、やっぱ間違ってますよねー。
そもそも2次元のものと3次元のものを混ぜていいのかというのをさて置いて全部3次元空間上のオブジェクトとして考えると、RectangleはCuboidの特殊な場合(Height = 0固定)ですので、Rectangle is a Cuboidですよねー。
でもRectangleにHeightを持たせたくないのは確かですので、こう。

type Any_Cuboid is abstract tagged
   record
      Length, Width : Float;
   end record;
function Get_Height (Item : Any_Cuboid) return Float is abstract;

type Rectangle is new Any_Cuboid with null record;
overriding function Get_Height (Item : Any_Cuboid) return Float is (0.0);

type Cuboid is new Any_Cuboid with
   record
      Height : Float;
   end record;
overriding function Get_Height (Item : Any_Cuboid) return Float is (Item.Height);

この手の逆転の間違いを犯してるのは結構あって、例えばimmutableなNSStringからmutableなNSMutableStringが派生してるとか……。(immutableと確信できる継承階層が無いので毎回copyしないとけない……どうせデータ本体はCOWで共有されてると思うけど←想像)