4.3.5.2. クラス優先順位リストの決定の例
これは、クラスpie
のクラス優先順位リストを決定する例です。 下記のクラスを定義します。
defclass pie (apple cinnamon) ())
(
defclass apple (fruit) ())
(
defclass cinnamon (spice) ())
(
defclass fruit (food) ())
(
defclass spice (food) ())
(
defclass food () ()) (
集合S_pie
と集合R
は次のようになります。
S_pie = {pie, apple, cinnamon, fruit, spice, food, standard-object, t}
R = {(pie, apple), (apple, cinnamon), (apple, fruit), (cinnamon, spice), (fruit, food), (spice, food), (food, standard-object), (standard-object, t)}
クラスpie
に先行するものはないので、 これを最初に配置し、この時点の結果は(pie)
です。 S
からpie
を取り除き、R
からpie
に関係するペアを取り除くと、 次のようになります。
S_pie = {apple, cinnamon, fruit, spice, food, standard-object, t}
R = {(apple, cinnamon), (apple, fruit), (cinnamon, spice), (fruit, food), (spice, food), (food, standard-object), (standard-object, t)}
クラスapple
に先行するものはないので、 その次に配置を行い、この時点での結果は(pie apple)
になります。 apple
を関係するものから取り除くと、 次のようになります。
S_pie = {cinnamon, fruit, spice, food, standard-object, t}
R = {(cinnamon, spice), (fruit, food), (spice, food), (food, standard-object), (standard-object, t)}
クラスcinnamon
とfruit
に先行するものはないので、 これまでに計算されたクラス優先順位リストの中で 一番右にあるダイレクトサブクラスを持つものが次に配置されます。 クラスapple
はfruit
のダイレクトサブクラスであり、 クラスpie
はcinnamon
のダイレクトサブクラスです。 クラス優先順位リストにおいて apple
がpie
の右に現れているため、 fruit
が次に配置され、 この時点での結果は(pie apple fruit)
になります。 集合から取り除くと次のようになります。
S = {cinnamon, spice, food, standard-object, t}
R = {(cinnamon, spice), (spice, food), (food, standard-object), (standard-object, t)}.
クラスcinnamon
が次に配置され、 この時点での結果は(pie apple fruit cinnamon)
です。 集合は次のようになります。
S = {spice, food, standard-object, t}
R = {(spice, food), (food, standard-object), (standard-object, t)}.
クラスspice
, food
, standard-object
, t
は この順番で追加され、クラス優先順位リストは次のようになります。
(pie apple fruit cinnamon spice food standard-object t)
順番付けできないクラス定義の集合を書くことも可能です。 例えば次の通り。
defclass new-class (fruit apple) ())
(
defclass apple (fruit) ()) (
局所的なスーパークラスの順序を保つためには、 クラスfruit
はapple
に先行しなければいけません。 クラスapple
はfruit
先行しなければならず、 なぜならクラスはそれ自身のスーパークラスに対して 常に先行しなければいけないからです。 このような状況が生じたとき、 システムがnew-classのクラス優先順位リストを 計算しているときにこの状況が発生した時点でエラーを通知します。
下記の例は衝突が生じる定義の集合です。
(defclass pie (apple cinnamon) ())
(defclass pastry (cinnamon apple) ())
(defclass apple () ())
(defclass cinnamon () ())
pie
のクラス優先順位リストは、 (pie apple cinnamon standard-object t)
です。
pastry
のクラス優先順位リストは、 (pastry cinnamon apple standard-object t)
です。
pie
のスーパークラスの順序で apple
がcinnamon
に先行することは問題ありませんし、 同様にpastry
の順序で apple
がcinnamon
に先行することは問題ありません。 しかし、pie
とpastry
の両方をスーパークラスとする 新しいクラスを作ることはできません。