オブジェクト指向プログラミングと設計を含む知識表現とオントロジー構成要素において、is-a ( is_aまたはis aとも表記される)は抽象化(例えば、型、クラス)間の包含的[a]関係であり、あるクラスAは別のクラスB のサブクラスである(したがって、BはA のスーパークラスである)。言い換えれば、型Aの仕様が型Bの仕様を暗示する場合、型Aは型Bのサブタイプである。つまり、Aの仕様を満たすオブジェクト(またはクラス)は、Bの仕様の方が弱いため、Bの仕様も満たす。[1]
たとえば、猫は動物ですが、その逆は当てはまりません。すべての猫は動物ですが、すべての動物が猫であるわけではありません。すべての動物に関連する動作は動物クラスで定義されますが、猫にのみ関連する動作は猫クラスで定義されます。猫クラスを動物クラスを「拡張」するものとして定義することで、すべての猫は動物に定義された動作を「継承」し、猫の動作を明示的にコード化する必要がなくなります。
関連概念
is -a関係は、型 (クラス) 間のhas-a ( has_aまたはhas a ) 関係と対比されます。has -a関係とis-a関係を混同することは、オブジェクトとその従属関係の現実世界の関係のモデル (たとえば、コンピュータ プログラム) を設計するときによくある間違いです。is -a関係は、オブジェクト (インスタンス) と型 (クラス) 間のinstance-of関係と対比されることもあります。型とトークンの区別を参照してください。
関係をまとめると次のようになります。
- 上位語-下位語(上位型/上位クラス - 下位型/下位クラス) 分類階層を定義する型 (クラス) 間の関係。
- 包含関係の場合: 下位語 (サブタイプ、サブクラス) は、その上位語 (スーパータイプ、スーパークラス) とtype-of ( is-a ) 関係を持ちます。
- ホロニム-メロニム(全体/実体/容器–部分/構成要素/メンバー)所有階層を定義する型(クラス)間の関係。
- 型(クラス)とオブジェクト(インスタンス)間の概念-オブジェクト(型-トークン)関係。
- トークン (オブジェクト) は、その型 (クラス) とインスタンスの関係を持ちます。
サブタイプの例
サブタイピングにより、特定の型を別の型または抽象化に置き換えることができます。サブタイピングは、言語サポートに応じて、暗黙的または明示的に、サブタイプと既存の抽象化の間にis-a関係を確立すると言われています。サブタイピング メカニズムとして継承をサポートする言語では、この関係は継承を介して明示的に表現できます。
C++
次の C++ コードは、クラスBとAの間に明示的な継承関係を確立します。ここで、B はAのサブクラスとサブタイプの両方であり、Bが指定されている場所であればどこでもAとして使用できます(参照、ポインター、またはオブジェクト自体を介して)。
クラスA { public : void DoSomethingALike () const {} };
クラスB : public A { public : void DoSomethingBLike () const {} };
void UseAnA ( A const & some_A ) { some_A . DoSomethingALike (); }
void SomeFunc () { B b ; UseAnA ( b ); // b は A の代わりに使用できます。 }
[3]
パイソン
次の Python コードは、クラスBとAの間に明示的な継承関係を確立します。ここで、BはAのサブクラスとサブタイプの両方であり、Bが必要な場所ではどこでもAとして使用できます。
クラス A :
def do_something_a_like ( self ):
渡す
クラス B ( A ):
def do_something_b_like ( self ):
パス
use_an_aを定義します( some_a ):
some_a . do_something_a_like ()
def some_func ():
b = B ()
use_an_a ( b ) # b は A の代わりに使用できます。
次の例では、type(a) は「通常の」型であり、type(type(a))はメタタイプです。分散型ではすべての型が同じメタタイプ ( PyType_Type 、これも独自のメタタイプ) を持ちますが、これは必須ではありません。types.ClassTypeと呼ばれる古典的なクラスの型も、異なるメタタイプと見なすことができます。[4]
>>> a = 0
>>> type ( a )
<type 'int'>
>>> type ( type ( a ))
<type 'type'>
>>> type ( type ( type ( a )))
< type ' type'>
>>> type ( type ( type ( a )))) <type 'type'>
ジャワ
Java では、あるクラスまたはインターフェースの型パラメータと別のクラスまたはインターフェースの型パラメータ間のis-a関係は、extends 句とimplements句によって決定されます。
クラスを使用するとCollections、ArrayList<E>は を実装しList<E>、 をList<E>拡張しますCollection<E>。 はArrayList<String>のサブタイプでありList<String>、 は のサブタイプです。 サブタイプ関係は、型間で自動的に保持されます。ジェネリック型Pのオプションの値を各要素に関連付けるCollection<String>インターフェイス を定義する場合、その宣言は次のようになります。
PayloadList
インターフェース PayloadList < E , P >はList < E >を拡張します{ void setPayload ( int index , P val ); ... }
PayloadList の次のパラメータ化は のサブタイプですList<String>:
PayloadList <文字列、文字列> PayloadList <文字列、整数> PayloadList <文字列、例外>
リスコフの置換原理
リスコフの置換原理は、「型Sの各オブジェクトo1に対して型Tのオブジェクトo2が存在し、Tに関して定義されたすべてのプログラムPについて、o1がo2に置き換えられてもPの動作が変化しない場合、SはTのサブタイプである」という性質を説明します。[5]次の例は、LSPの違反を示しています。
LSP 違反の例としては次のようなものがあります。
クラスRectangle { public : void SetWidth ( double w ) { itsWidth = w ; } void SetHeight ( double h ) { itsHeight = h ; } double GetHeight () const { return itsHeight ; } double GetWidth () const { return itsWidth ; } double GetArea () const { return GetHeight () * GetWidth (); } private : double itsWidth ; double itsHeight ; };
プログラミングの観点から見ると、Square クラスは Rectangle クラスを継承することによって実装できます。
パブリッククラスSquare : Rectangle {パブリック:仮想void SetWidth ( double w );仮想void SetHeight ( double h ); }; void Square::SetWidth ( double w ) { Rectangle :: SetWidth ( w ); Rectangle :: SetHeight ( w ); } void Square::SetHeight ( double h ) { Rectangle :: SetHeight ( h ); Rectangle :: SetWidth ( h ); }
しかし、RectangleとSquareの間には is-a関係が成立しているにもかかわらず、これはLSPに違反している。
次の例を考えてみましょう。ここでは、Square が渡された場合、関数 g は機能しないため、オープンクローズ原則に違反していると考えられます。
void g ( Rectangle & r ) { r . SetWidth ( 5 ); r . SetHeight ( 4 ); assert ( r . GetArea ()) == 20 ); // アサーションは失敗します}
逆に、図形の種類はその寸法の関係に対する制約のみであるべきと考える場合、SetHeight は高さと面積を変更するが幅は変更しないという g() の仮定は無効であり、これは真の正方形だけでなく、高さが変わっても面積やアスペクト比を維持するようにコード化される可能性のある他の長方形に対しても無効になります。
[6]
参照
注記
- ^ リスコフの置換原理を参照。
- ^ 「サブタイプとサブクラス」(PDF) . MIT OCW . 2012年10月2日閲覧。
- ^ Containment (コンピュータプログラミング)も参照。
- ^ ミッチェル、ジョン(2002)。「10 オブジェクト指向言語の概念」 「プログラミング言語の概念」ケンブリッジ、イギリス:ケンブリッジ大学出版局。p. 287。ISBN 0-521-78098-5。
- ^ Guido van Rossum. 「組み込み型のサブタイプ化」 。2012年10 月 2 日閲覧。
- ^ Liskov, Barbara (1988年5月). データ抽象化と階層(PDF) . SIGPLAN通知. 2020年6月21日時点のオリジナルよりアーカイブ。
{{cite book}}: CS1 maint: unfit URL (link) - ^ 「リスコフの置換原理」(PDF) 。ロバート・C・マーティン、1996年。 2015年9月5日時点のオリジナル(PDF)からアーカイブ。 2012年10月2日閲覧。
参考文献
- ロナルド・J・ブラクマン、「IS-A とは何か、そうでないものとは何か。セマンティック ネットワークにおける分類リンクの分析」IEEE Computer、16 (10)、1983 年 10 月
- Jean-Luc Hainaut、Jean-Marc Hick、Vincent Englebert、Jean Henrard、Didier Roland: IS-A 関係の実装について。 ER 1996: 42-57
