inheritance
「inheritance」とは、「継承」や「相続」「相続権」など人が死亡した時に持っている財産のことや特定の人が遺産を受け継ぐことを意味する英語表現である。
「inheritance」とは・「inheritance」の意味
「inheritance」とは、「継承」「相続」「遺産」などを意味する英語表現である。また、「相続権」「分与権」「生得権」「相続財産」「相続物件」など、「相続をすること」や「相続をしている事実」をはじめ、「受け継ぐ権利」や「受け継いだもの」のことにも幅広く用いられる。そのほかにも、「遺伝」や「遺伝的形質」のことを指して使う場合もある。「inheritance」は、意味するものによって「可算名詞」と「不可算名詞」の両方の要素を持つ。「可算名詞」として使われる場合には複数形の「inheritances」に変化させる必要がある。また、「inheritance」には名詞以外の意味はないので、動詞として用いる場合には「inherit(相続する・引き継ぐ)」に置き換える。
「inheritance」の発音・読み方
「inheritance」の発音記号は、「inhérətəns」である。一般的に「inheritance」のカタカナ語読みは「インヘリタンス」であるが、実際には「 インヘェラァタァンス」の方が正確な発音に近い。最初の「イ」は、日本語の「イ」と「エ」を同時に言うような感じで発音する。また、2回の「ン」は舌先を前歯の裏に付けてから息が漏れないようにして、鼻から出すように発するのがよい。最後の「ス」は、舌先を前歯の裏に近付けてから、息を出しながら発音するがコツである。「inheritance」の語源・由来
「inheritance」は、「inherit」から派生した言葉である。「in(中に)」+「heri(相続人)」が組み合わさった意味合いが、「相続」や「遺産」などの意味の由来になったとされている。また、「inherit」のもともとの語源は、ラテン語の「 inheredito(相続する)」だとする説もある。「inheritance」の覚え方
「inheritance」は、動詞の「inherit」とセットで覚えるのがよい。ただし、どうしても記憶しづらい時には、カタカナ語読みの「インヘリタンス」から想像できる語呂合わせを使って覚える方法もある。例えば、残された遺産の管理をする委員が減ってしまって管理を継続することが難しくなった状況をイメージしながら、「委員減り箪笥(インヘリタンス)預金を使った遺産の管理が難しくなる」と覚えると、スペルと意味がつながりやすくなる。「inheritance」と「heritage」の違い
「inheritance」と「heritage」は、いずれも「遺産」という意味を持つ英単語である。ただし、「inheritance」は「相続などで手にした財産や不動産などの遺産」を意味するのに対して、「heritage」は「伝統的に後世に受け継がれていく遺産」を指す言葉である。「heritage」が表す遺産には、建造物や文化などの歴史的価値のあるものが含まれ、ユネスコによって登録される「世界遺産」も「World Heritage」と表現する。「inheritance」を含む英熟語・英語表現
「genetic inheritance」とは
「genetic inheritance」とは、「inheritance」と「遺伝学の」「遺伝上の」などの意味がある「genetic」を組み合わせた英熟語で、「genetic inheritance」全体では「遺伝」という意味になる。「inheritance」のみでも「遺伝」を表すことがあるが、「inheritance」が付くことでよりはっきりと「遺伝」を表現することができる。
「inheritance tax」とは
「inheritance tax」とは、「inheritance」に「税金」の意味を持つ「tax」を加えた英熟語である。「inheritance tax」全体では「相続税」「遺産税」のことを意味し、亡くなった人から財産を受け継いだ場合にかかる税金のことを表す言葉である。
「inheritance」の使い方・例文
He has a large inheritance from his uncle.(彼には叔父から相続した多額の相続財産がある)She acquired land through inheritance.(彼女は相続によって土地を手に入れた)
My mother left us a large inheritance.(母は私たちに莫大な遺産を残した)
Mary doesn’t get her inheritance until she is thirty.(メアリーは30歳になるまで遺産を受け取ることができない)
The shape of one's ears depends on genetic inheritance.(人間の耳の形は遺伝に左右される)
「inheritance」の英語での説明
「inheritance」を英語で説明する場合には、「相続」「遺産」の意味については「money, property etc that you receive from someone who has died」「money, land, or possessions received from someone after the person has died」などになる。また、「遺伝」の意味においては「physical or mental qualities that you inherit from your family」となる。継承 (プログラミング)
(インヘリタンス から転送)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2023/10/17 00:49 UTC 版)
コンピュータプログラミングにおける継承(けいしょう、英: inheritance)とは、任意のオブジェクトの特性を、他のオブジェクトの特性の基礎にするためのメカニズムと定義されている。
基礎にされる継承元は親、その継承先は子と呼ばれて、状態と機能と定数と注釈などが引き継がれるが、コンストラクタとデストラクタは対象外になる。その親と子の関係を、クラスベースOOPはスーパークラスとサブクラスの関係で、プロトタイプベースOOPはプロトタイプとクローンの関係で導入している[1]。
概要

継承は、他のオブジェクトの特性(データ・手続き・関数・定数・アノテーションなど)を引き継ぐという概念であり、引き継いだオブジェクトがどのような性質を持ち、どのように振る舞うのかは全くの任意になる。引き継ぎかたは、リクエストされた特性をそのオブジェクトが持たない場合は、自動的に上位オブジェクトの方でサーチするという方式が一般的であり、これは暗黙の委譲(delegation)ベースとも呼ばれる。他には、インスタンス化時にその型の継承チェーンを走査してその全要素を集めて同名重複要素を解決して1つの実体を生成するという方式もあり、これは連結(concatenation)ベースとも呼ばれる。
他オブジェクトの特性を引き継ぐという概念は、それに新しい特性群を付け足しての手軽なオブジェクトの機能拡張と、引き継がれる共通の特性群を上位ノードにしたオブジェクトの分類体系化をもたらしている。これは差分プログラミングとも呼ばれ、プログラムの再利用性と保守性を高めるとされている。
継承(inheritance)とサブタイピング(subtyping)は混同されやすい。ここでのサブタイピングは、親オブジェクトに対する子オブジェクトの安全な代替/代入(substitute)を保証する継承という意味で使われている。それに対してのただの継承は、親オブジェクトの特性をただ引き継ぐことに専念しており、安全な代替/代入には無関心である。たとえ話としては、親の白黒映画をカラー映画化するのが代替可能なサブタイピングであり、親の白黒映画をメディアミックス的グッズ販売につなげるのが代替不可な継承になる。継承に代入可能性(substitutability)を順守させてサブタイピングにすることを提唱しているのが、リスコフの置換原則である。
継承と対比される概念にコンポジション (合成)がある。継承のサブタイピング用法の上位概念と下位概念(Is-a)に対して、合成は(Has-a)であるが、継承の非サブタイピング用法では、スーパークラスとサブクラスの関係が(Is-aでもHas-aでもない)の関係になることがしばしばあるので、それと合成との使い分けが重視されるようになっている。
継承の目的
差分プログラミング
差分プログラミング(difference coding)とは、クラス間の共通構成を、各クラスの特有構成に引き継がせるようにして、重複構成の削減と、分類体系化をもたらすことを目的にした継承の用法である。これは、クラスに新機能を付け足しての手軽なクラス拡張目的と、クラスの共通部分を括りだして体系化するクラス分類目的の双方に使われた。
差分プログラミングは、継承の元々の用法であり、プログラムの再利用性と保守性を高めると見なされていたが、後年になると階層分散配置されたデータとメソッドの把握のしづらさによる弊害の方が目立つようになって、この用法を否定する傾向が強くなった。同時にその代替としての合成が重視されるようになっている。
サブタイピング
サブタイピング(subtyping)とは、スーパークラスのインスタンスを、サブクラスのインスタンスで安全に代替できることを指針にした継承の用法である。基底クラスの変数への、派生クラスのインスタンスの安全な代入可能性(substitutability)を保証している。これはIs-a関係とも言われる。サブタイピングでは、派生側でのフィールドの追加は抑制され、基底側からのメソッド実装の引き継ぎも抑制されており、基底側からのメソッド定義(メソッドシグネチャ)の引き継ぎが重視されている。派生インスタンスが代入された基底変数のメソッド名から派生メソッド内容が呼び出される言語機能は、メソッドオーバーライドと呼ばれ、その機能概念は動的ディスパッチと呼ばれる。サブタイピングは動的ディスパッチに焦点を当てた継承と解釈できる。
具象メソッド(定義+実装)の引き継ぎは実装継承(implementation inheritance)またはコード継承(code inheritance)と呼ばれており、抽象メソッド(定義だけ)の引き継ぎは界面継承(interface inheritance)と呼ばれている。
Is-a関係サブタイピング主体の継承関係は、UMLクラス図では汎化/特化の関係に投影されている。抽象メソッドだけで構成される純粋抽象クラスは、インターフェースと呼ばれており、それとの継承関係はUMLクラス図では実現/実装の関係に投影されている。
サブタイピングのコーディング例はこうなる。
#include <iostream>
#include <string>
#include <typeinfo>
class Base {
public:
virtual ~Base() {}
virtual std::string greet() const = 0;
};
class Derived : public Base {
virtual ~Derived() { std::cout << "Destructor of Derived is called." << std::endl; }
virtual std::string greet() const { return "Hello!"; }
};
int main() {
Base* b = new Derived(); // OK
std::cout << "Message: " << b->greet() << std::endl;
std::cout << "Is instance of Derived? " << std::boolalpha << (typeid(*b) == typeid(Derived)) << std::endl;
delete b;
return 0;
}
多重継承
クラスに複数のスーパークラスを持たせることを多重継承という。単一継承と異なり、多重継承では、スーパークラス上のメンバサーチが複数方向に分かれるので、どのメンバが参照されるのかの把握が困難になるという欠点がある。特にフィールドの多重継承・分散配置は、早期に原則禁止が一般化している。メソッドの方はやむなく許容されたので、メソッド決定順序(MRO)問題が取り沙汰された。MRO問題を解決するために導入されたのが、インターフェースの実装やトレイトのインクルードであり、双方はデータ主体クラスを単一継承にしてメソッド主体クラスを多重継承にするというハイブリッド継承の担い手になった。
また、多重継承上のスーパークラスの重複による菱形継承問題も問題視されるようになっている。菱形継承問題の解決策としては、C++/Eiffel発の仮想継承、Eiffel発のリネーミング、Python発のC3線形化などがある。
多重継承と仮想継承のコーディング例を以下に示す。同一のクラスから継承している複数の派生クラスを多重継承して1つのクラスを作る場合に始めの基底クラスの存在をどうするかによって仮想継承と通常の多重継承の2つに分かれる。
class Base {
public:
int n;
};
// 非仮想継承。
class DerivedNV1 : public Base { /* ... */ };
class DerivedNV2 : public Base { /* ... */ };
// 仮想継承。
class DerivedV1 : public virtual Base { /* ... */ };
class DerivedV2 : public virtual Base { /* ... */ };
class DerivedNV : public DerivedNV1, public DerivedNV2 { /* ... */ };
class DerivedV : public DerivedV1, public DerivedV2 { /* ... */ };
int main() {
DerivedNV nv;
//nv.n = 0; // 曖昧さが解決できないためコンパイルエラー。
nv.DerivedNV1::n = 0;
nv.DerivedNV2::n = 0;
DerivedV v;
v.n = 0; // コンパイルエラーにはならない。
return 0;
}
この例のような状態は特に菱形継承(ダイアモンド継承)と呼ばれる。
仮想継承でない場合、DerivedNV
のインスタンスにはDerivedNV1
の基底のBase::n
とDerivedNV2
の基底のBase::n
という2つのn
が別に存在することになる(メンバ関数も同様)。一方、仮想継承した場合、DerivedV
のインスタンスにはBaseの部分はただ1つしか存在しない。DerivedV1
の基底とDerivedV2
の基底が共有されている状態である。
先発OOP言語のC++やEiffelでは実装の多重継承ができたが、後発言語のJavaやC#では実装は単一継承限定にされ、代わりにインターフェースの多重継承(界面の多重継承)が導入されている。なぜなら実装の多重継承はメリットよりもデメリットのほうが多いとみなされたためである。
- 継承関係が複雑になるため全体の把握が困難になる。
- 名前の衝突。同じ名前を複数の基底クラスがそれぞれ別の意味で用いていた場合、その両方を派生クラスでオーバーライドするのが困難。
- 処理系の実装が複雑になってしまう。
- 仮想継承にしていない場合に同一の基底クラスが複数存在してしまう(これが望ましい場面もあるが)。これの何が問題かというと、最初は仮想継承していなかったものを、後から仮想継承にしたくなったときに、変更点を洗い出すのが大変になるからである。つまり仮想継承を使用するには設計をきちんと行う必要があるということである。
しかしながら多重継承を使う方が直感的になる場合もあるとの主張もあり、どちらが正しいとは言えない状況である。
カプセル化の可視性と継承の可視性
カプセル化の可視性(public/protected/package/private)によって、各スーパークラスメンバの受け継ぎが取捨選択されることは、派生型に対する継承の大きな特徴である。privateメンバはサブクラスに受け継がれない。packageメンバは外部パッケージのサブクラスには受け継がれない。
継承の可視性は、スーパークラスメンバ(フィールド/メソッド)の可視性に更に制約をかける機能である。三段階ある。
- public継承 - そのままの継承。
- protected継承 - スーパークラスのpublicメンバを、protectedメンバに引き下げて継承する。
- private継承 - スーパークラスのpublic/protectedメンバを、privateメンバに引き下げて継承する。
これはC++で導入されていたが、後継OOP言語ではほとんど採用されていない。
ミックスイン
ミックスイン(Mix-in)は、多重継承問題の解決策を発端にしたもう1つの継承方法論である。メソッドの集合体を継承することで、その機能をクラスに注入することを目的にしており、メソッド集合体とクラスの間には汎化/特化の関係がないままで、多重継承を前提にしている。そのメソッド集合体はトレイトとされることが多く、他にモジュール、プロトコル、ロールといった形態もある。トレイトの継承はインクルードと呼ぶのが好まれ多重継承前提である。ミックスインはそれらをひっくるめた方法論としての用語になっている。
界面継承のインターフェース(抽象メソッドをまとめたクラス)と、Mix-in継承のトレイト(独立メソッドをまとめたモジュール)は双方とも多重継承前提なのでよく対比されて説明される。双方の違いを列挙すると以下のようになる。
- 界面継承は抽象メソッドをクラスに相続させるのに対して、Mix-in継承は独立メソッドをクラスに贈与する。
- 界面継承はインターフェースの継承先クラスに実装メソッドを記述するが、Mix-in継承はトレイトに実装メソッドを記述する。
- 界面継承は同名アルゴリズムを個々のクラスのメソッドに分散記述するが、Mix-in継承は1つのメソッドに個々のクラスのアルゴリズムを一括記述する。
- インターフェースはデータメンバを持つことを想定されていないが、トレイトはデータメンバを持つ。すなわち界面継承は派生メソッドたち専用の共有データを持てないが、Mix-in継承はそれが可能である。
- 界面継承はthis参照を暗黙使用できるが、Mix-in継承は不可なのでThis参照の明示的な引数渡しや関連型の機能が必要になる。
- インターフェースは記名的型付けであるのに対して、トレイトは構造的型付けで識別されることが多い。
UMLにおける継承
統一モデリング言語 (UML) のクラス図では、サブクラスから見たスーパークラスは汎化 (generalization) 、スーパークラスから見たサブクラスは特化 (specialization) と呼ばれる。
純粋抽象クラスはインターフェースと定義されており、クラスから見たインターフェースは実現(realization)[要検証 ]、クラスがインターフェースを継承することは実装(implementation)と呼ばれる。
サブタイピング用法の投影は汎化/特化の関係であり、インターフェース用法の投影は実現/実装の関係である。ミックスイン用法はUMLクラス図で扱われていない関係であり、差分プログラミング用法も同様である。
脚注
- ^ MDN contributors (2022年9月17日). "継承とプロトタイプチェーン - JavaScript". developer.mozilla.org. 2022年9月18日閲覧。
関連項目
- インヘリタンスのページへのリンク