継承
クラスの拡張
継承(インヘリタンス : Inheritance)は、オブジェクト指向の基礎概念の一つです
継承は、あるクラスを別のクラスに「継承」しその機能を受け継ぎます
継承するクラスを基本クラス、または基底クラスと呼び
基本クラスを継承したクラスを派生クラスと呼びます
派生クラスを作成するには、クラスの宣言時に次ぎの構文を使用します
class derived_name : [access_type] base_name {
member;
};
derived_name には、派生クラスのクラス名を指定します
その後、コロン : を付加し、access_type にアクセス指定子
base_name に基本クラス名を指定します
access_type にはアクセス指定子を指定します。省略可能です
とりあえずこの場は public を指定するものとします
public は基本クラスの public メンバを派生クラスでも public とするという意味になります(詳しくは次章)
今は継承の基本的な機能と意味を知ることに集中してください
次のプログラムに注目してください、Di_Gi_Gharat クラスは Kitty クラスを継承しています
#include<iostream>
using namespace std;
class Kitty {
public:
void nyan() { cout << "Kitty on your lap\n"; }
} ;
class Di_Gi_Gharat : public Kitty {
public:
void nyo() { cout << "Di Gi Gharat\n"; }
} obj ;
int main() {
obj.nyo();
obj.nyan();
return 0;
}
Kitty クラスの派生クラスとなる Di_Gi_Gharat クラスのオブジェクト obj が
main() 関数内で obj.nyo() メンバ関数を呼び出しています。これは今までどおりですね
注目して欲しいのは、Di_Gi_Gharat クラスのオブジェクトである obj が
Kitty クラスのメンバ関数 nyan() を呼び出していることです
この動作は正しく、意図どおりの結果になります
ずばり、これが「継承」なのです
派生クラス Di_Gi_Gharat には、基本クラス Kitty の機能が「継承」されるのです
メンバ名の衝突
クラスを継承すると、場合によっては派生クラスと基本クラスの
メンバ名が同じになるという問題が発生するでしょう
この場合は、グローバル変数とローカル変数の問題に似ています
派生クラスと基本クラスで同じ名前のメンバが存在する場合
派生クラスは常に派生クラス(自分)のメンバを優先します
派生クラスのオブジェクトから、基本クラスの同名のメンバを呼び出す場合
やはりスコープ解決演算子を用いてクラスを明示します
#include<iostream>
using namespace std;
class Kitty {
public:
void nyan() { cout << "Kitty on your lap\n"; }
} ;
class Di_Gi_Gharat : public Kitty {
public:
void nyan() { cout << "Di Gi Gharat\n"; }
} obj ;
int main() {
obj.Kitty::nyan();
obj.nyan();
return 0;
}
Di_Gi_Gharat クラスは Kitty クラスを継承しています
しかし、両方のクラスでメンバ関数 nyao() が定義されていますね
この時、何も指定せずに obj.nyao() の場合は
自分のクラスのメンバを優先して呼び出します
基本クラスのメンバを呼び出す場合は、スコープ演算子で明示してください