inheritance c
例を挙げたC ++での継承の重要性:
継承は、オブジェクト指向プログラミングの最も重要な機能の1つです。
継承は、あるクラスが他のクラスのプロパティとメソッドを取得する手法です。このようにして、すでに作成および検証されたコードを再利用できます。別のクラスのプロパティを取得するクラスは、サブクラスまたは派生クラスまたは子クラスと呼ばれます。
プロパティが取得されるクラスは、基本クラスまたは親クラスまたはスーパークラスと呼ばれます。あるクラスが別のクラスを取得または継承すると、基本クラスのすべてのプロパティとメソッドが派生クラスで使用できるため、このコードを再利用できます。
=> ゼロからC ++を学ぶには、ここにアクセスしてください。
スタックc ++を使用するdfs
学習内容:
なぜ継承が必要なのですか?
車、バス、ジープなどの車両のグループについて考えてみます。これらの各車両には、次の図に示すようなプロパティとメソッドがあります。
上記の車両に個別のクラスを実装する必要がある場合、3つのクラスすべてで、3つのタイプの車両すべてがほぼ同じプロパティを示すため、同じコードを記述する必要があることがわかります。これにより、重複するコードが多数存在するため、プログラムが非効率的で面倒になります。
上記のように重複したコードを作成する代わりに、継承機能を実装してコードの重複を防ぎ、1つのコードを作成して、3つのクラスすべてで使用することもできます。これは、以下のように図で表されます。
上の図では、基本クラス「Vehicles」を定義し、このクラスからクラスCar、Bus、およびJeepを派生させています。共通のメソッドとプロパティは現在、Vehiclesクラスの一部です。他のクラスはVehiclesクラスから派生しているため、すべてのクラスがこれらのメソッドとプロパティを取得します。
したがって、共通コードを1回だけ記述し、3つのクラスすべてを記述する必要があります。車、バス、ジープが取得します。
したがって、既存のクラスを継承したり、継承メカニズムを設計したりすることで得られる主な利点は、コードの再利用性です。
さらに読む= >> Java継承チュートリアル
クラスを継承するための一般的な形式は次のとおりです。
class derived_classname: access_specifier base_classname { };
ここに ' 派生クラス名 」は派生クラスの名前です。「 access_specifier 」はアクセスモードです。つまり、派生クラスが基本クラスを継承する必要があるパブリック、プロテクト、またはプライベートであり、「 派生クラス名 」は、派生クラスが継承する基本クラスの名前です。
遺伝形式
上記の継承宣言に示されている「access_specifier」は、以下に示すような値を持つことができます。
クラスを継承するときに指定されたaccess_specifierに応じて、以下に示すさまざまな継承モードがあります。
公的継承
一般的な構文
class sub_class : public parent_class
パブリックアクセス指定子を指定すると、基本クラスのパブリックメンバーはパブリックとして継承され、保護されたメンバーは保護されます。プライベートメンバーはプライベートのままです。これは最も人気のある遺伝形式です。
プライベート継承
一般的な構文
class sub_class : parent_class
プライベート継承は何も継承しません。プライベートアクセス指定子を使用すると、基本クラスのパブリックメンバーと保護されたメンバーもプライベートになります。
保護された継承
一般的な構文
class sub_class:protected parent_class
保護されたアクセス指定子が使用される場合、基本クラスのパブリックおよび保護されたメンバーは、派生クラスの保護されたメンバーになります。
基本クラスにプライベートアクセス指定子を使用する場合、基本クラスのメンバーはいずれも継承されないことに注意してください。それらはすべて、派生クラスでプライベートになります。
以下に示すのは、すべてのアクセスモードの表形式の表現と、継承のためのそれらの解釈です。
派生クラス-> 基本クラス | 民間 | 公衆 | 保護されています |
---|---|---|---|
民間 | 継承されません | 継承されません | 継承されません |
公衆 | 民間 | 公衆 | 保護されています |
保護されています | 民間 | 保護されています | 保護されています |
継承するコンストラクタ/デストラクタの順序
クラスが継承されると、コンストラクターはクラスが継承されるのと同じ順序で呼び出されます。基本クラスと、この基本クラスを継承する1つの派生クラスがある場合、基本クラスコンストラクター(デフォルトまたはパラメーター化されているかどうか)が最初に呼び出され、次に派生クラスコンストラクターが呼び出されます。
次のプログラムは、継承におけるコンストラクターの順序を示しています。デフォルトのコンストラクターとパラメーター化されたコンストラクターを持つBaseクラス「Base」があります。これから「Derived」と呼ばれるクラスを派生させます。このクラスには、1つのデフォルトと別のパラメーター化されたコンストラクターもあります。
このプログラムの出力は、コンストラクターが呼び出される順序を示しています。
#include using namespace std; //order of execution of constructors in inheritance class Base { int x; public: // default constructor Base() { cout 出力:
基本クラスのデフォルトコンストラクタ
基本クラスのデフォルトコンストラクタ
派生クラスのデフォルトコンストラクタ
基本クラスのパラメーター化されたコンストラクター
派生クラスのパラメーター化されたコンストラクター
基本クラスオブジェクトを作成した後、デフォルトのコンストラクターを使用して派生クラスオブジェクトを作成していることがわかります。このオブジェクトが作成されると、最初に基本クラスのデフォルトコンストラクターが呼び出され、次に派生クラスコンストラクターが実行されます。
同様に、派生クラスオブジェクトがパラメーター化コンストラクターを使用して作成される場合、基本クラスのパラメーター化コンストラクターが最初に呼び出され、次に派生クラスコンストラクターが呼び出されます。
基本クラスにパラメーター化されたコンストラクターがない場合は、パラメーター化された派生クラスオブジェクトを構築する場合でも、デフォルトのコンストラクターが呼び出されることに注意してください。
しかし、派生クラスオブジェクトの構築中に基本クラスコンストラクターが呼び出される理由については疑問が残ります。
コンストラクターは、クラスのオブジェクトを作成し、クラスのメンバーを初期化するために使用されることを知っています。派生クラスオブジェクトが作成されると、そのコンストラクターは派生クラスメンバーのみを制御できます。
ただし、派生クラスは基本クラスのメンバーも継承します。派生クラスのコンストラクターのみが呼び出された場合、派生クラスによって継承された基本クラスのメンバーは正しく初期化されません。
その結果、オブジェクト全体が効率的に作成されません。これが、派生クラスオブジェクトが作成されるときにすべての基本クラスコンストラクターが最初に呼び出される理由です。
継承の種類
クラスの派生方法またはクラスが継承する基本クラスの数に応じて、次の図に示すように、次のタイプの継承があります。

これらの各タイプについては、次の「継承のタイプ」に関するチュートリアルで説明します。
テンプレートの継承
実装にテンプレートが含まれる場合、テンプレートクラスを継承または派生させる必要があり、そこでテンプレートの継承を利用します。
テンプレートを使用した継承をよりよく理解するために、プログラミングの例に直接ジャンプしてみましょう。
#include using namespace std; //template inhertance templateclass basecls_Template { public: T value; basecls_Template(T value) { this->value = value; } void displayVal() { cout << value << endl; } }; //derived class inherits basecls_Template class derivedcls_Child : public basecls_Template { public: derivedcls_Child(/* no parameters */): basecls_Template( 0 ){ // default char is NULL; } derivedcls_Child(char c): basecls_Template( c ) { ; } void displayVal_drvd() { displayVal(); } }; int main() { basecls_Template obj( 100 ); derivedcls_Child obj1( 'A' ); cout<<'basecls_Template obj = '; obj.displayVal(); // should print '100' cout< 出力:
j2eeインタビューの質問と回答pdf
basecls_Template obj = 100
派生したcls_Childobj1(basecls_Template = Aから継承
上記のプログラムには、基本クラスのクラステンプレートを定義するbasecls_Templateという名前のテンプレートがあります。次に、テンプレートクラスから派生させたいクラスderivedcls_Childを定義します。
ただし、basecls_Templateクラスは単なる型であり、クラスではないことに注意してください。したがって、このテンプレートからクラスderivedcls_Childを派生させることはできません。
したがって、子クラスを次のように宣言すると、次のようになります。
class derivedcls_Child : public basecls_Template
これにより、エラーが発生します。 basecls_Templateである理由は、クラスではなくデータ型です。したがって、basecls_Templateのメンバーを継承するには、派生する前に最初にインスタンス化する必要があります。
したがって、上記のステートメントは、 クラスderivatedcls_Child:public basecls_Template 正常に動作します。
このステートメントでは、テンプレートbasecls_Templateを文字クラステンプレートにインスタンス化しました。このインスタンス化されたテンプレートクラスを使用すると、オブジェクトの作成や使用など、それに続く他のことは、通常の継承作業と一致します。
組成
これまで、継承関係についてすべて見てきました。継承は基本的に、関係が部分を示すような関係を表します。 例えば、 ヘビは爬虫類の一種です。爬虫類は動物のクラスの一部であるとも言えます。
結論として、継承は 「IS-A」 派生クラスは基本クラスの一部であると言えるような関係です。
関係全体を表すこともできます。 例えば、 給与クラスが従業員クラスの一部であると言う場合、それを適切に表現していません。従業員には給料があることを私たちは知っています。したがって、「従業員には給料がある」と言う方が便利です。
同様に、Vehiclesクラスを例にとると、Vehicleにはエンジンがある、またはVehicleにはシャーシがあると言えます。したがって、これらすべての関係は 'があります' 別のクラスに含まれるオブジェクト全体を表す関係。これは次のように定義されます 組成 。
構成によって表される関係は、互いに依存しています。 例えば、 シャーシは車両なしでは存在できません。同様に、給与は従業員なしでは存在できません。
以下に示すように、構成を図式的に表すことができます。

構成は封じ込めとも呼ばれます。上記の表現では、親クラスを示しています。継承とは対照的に、親クラス内に子クラスオブジェクトを含めます。これは封じ込めまたは構成です。
偽のメールアドレスを取得する方法
これを理解するためにプログラミングの例を見てみましょう。
#include using namespace std; //Composition example //Child class - address class Address { public: string houseNo, building, street, city, state; //Initialise the address object Address(string houseNo,string building,string street, string city, string state) { this->houseNo = houseNo; this->building = building; this->street = street; this->city = city; this->state = state; } }; //Parent class - Employee class Employee { private: Address* address; //composition->Employee has an address public: int empId; string empName; Employee(int empId, string empName, Address* address) { this->empId = empId; this->empName = empName; this->address = address; } void display() { cout< 出力:
10001 Ved
A-101シルバースプリングスアウンドプネマハラシュトラ
この例では、親クラスEmployeeと子クラスAddressがあります。親クラスEmployee内で、Addressクラスへのポインターを宣言し、Employeeコンストラクターでこのオブジェクトを初期化しました。したがって、従業員が構成であるアドレスを持っているという関係を示します。
構成と継承をどのように決定する必要がありますか?
構成と継承はどちらもクラス間の関係を表しています。継承は「IS-A」関係を表しますが、構成は「HAS-A」関係を表します。
ここで問題となるのは、いつ継承を使用し、いつ合成を使用する必要があるのかということです。実際、どちらを使うべきかという正確な状況を決めることはできません。これは、それぞれに長所と短所があるためです。
どちらもコードの再利用を促進します。継承により、ソリューションが複雑になるためコードが大きくなる可能性がありますが、同時に、既存のコードを拡張することもできます。したがって、新しいクラス内の別のクラスのプロパティとメソッドを変更して使用する必要がある場合は、継承を使用する必要があります。
つまり、プロパティを追加して既存のクラスを拡張する場合です。一方、別のクラスのプロパティや動作を変更せずに、単にクラス内で使用する場合は、構成に進みます。
したがって、構成を使用するか継承を使用するかについての最良の決定は、特定の状況に対する両方の手法の長所と短所を比較検討することによって行われます。
結論
これで、継承に関するトピックは終わりです。私たちはさまざまな遺伝形式を見てきました。また、継承のタイプについても見てきました。これについては、次のチュートリアルで説明します。継承の場合に実行されるコンストラクターの順序について学びました。
また、テンプレートと継承についても学習しました。テンプレート自体はデータ型であり、データ型から継承できないため、継承で使用する前にテンプレートをインスタンス化する必要があります。
構成は別のタイプのクラス関係であり、最初に正確な状況を知る必要があります。次に、構成と継承のどちらを使用するかを決定できるのは私たちだけです。
次のチュートリアルでは、継承の種類について詳しく説明します。
=> ここで簡単なC ++トレーニングシリーズに注意してください。
推奨読書