210 likes | 373 Views
オブジェクト指向言語 オブジェクト指向言語演習. 第 25 回 C++ 言語 クラスの継承. スケジュール (C++ 言語 ). オブジェクト指向技術 (2004/12/13) C++ 言語 コンソール入出力とクラス (2004/12/20) C++ 言語 クラスの継承 (2004/12/20) C++ 言語 クラスの詳細 (2005/01/17) C++ 言語 オーバーロード (2005/01/17) C++ 言語 クラスの継承 (2005/01/24) C++ 言語 マニピュレータ , ファイル入出力 (2005/01/24)
E N D
オブジェクト指向言語オブジェクト指向言語演習オブジェクト指向言語オブジェクト指向言語演習 第25回 C++言語 クラスの継承
スケジュール(C++言語) • オブジェクト指向技術 (2004/12/13) • C++言語 コンソール入出力とクラス (2004/12/20) • C++言語 クラスの継承 (2004/12/20) • C++言語 クラスの詳細 (2005/01/17) • C++言語 オーバーロード (2005/01/17) • C++言語 クラスの継承 (2005/01/24) • C++言語 マニピュレータ, ファイル入出力 (2005/01/24) • C++言語 テンプレート (2005/01/31) • C++言語 試験 (2005/02/01) 最終試験は期末試験は 2月1日(火) 7,8 時限 に実施します。 教室はいつもと同じ場所(新四号館211と411)です。 Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
C++言語 クラスの継承 C++ Language Inheritance
乗り物 自動車 継承(復習) • 継承(Inheritance) • あるクラスが、他のクラスの性質をそのまま受け継ぐ仕組み • 継承されるクラス • スーパークラス (Super Class) • 基本クラス (Base Class) • 継承したクラス • サブクラス (Sub Class) • 派生クラス (Derived Class) 基本クラス • 例)自動車クラスでは、乗り物クラスの持つ • すべての性質を受け継ぐことになる 派生クラス Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
継承の表現(復習) 教科書: P57 • 継承したクラス(派生クラス)の宣言は、以下のように表現する • 「基本クラス名で示されたクラスを継承して、派生クラス名で示されたクラスを定義する」ことを表す • アクセス制御は基本クラスの public 要素をどのように継承するかを表す • アクセス制御には public, private, protected がある • はじめは public を主に利用する (注意) classは小文字 (Class ではない) class 派生クラス名: アクセス制御 基本クラス名{ : : }; Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
B D - i : int - j : int + set_i ( n : int ) : void + get_i ( ) : int + set_j ( n : int ) : void + mul ( ) : int 継承の例(B/D)(復習) 教科書: P55 • DクラスはBクラスの性質をすべて引き継ぐ • Dクラスは、Bクラスで宣言している • int 型の i • 戻り値のない set_i 関数 • int 型の戻り値を持つ get_i 関数 をも自動的に宣言したことになる class B { int i; public: void set_i(int n); int get_i(); }; class D : public B { int j; public: void set_j(int n); int mul(); }; 「 : アクセス制御 基本クラス名 」 で「クラスを継承する」ということを表す Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
基本クラスのアクセス制御(1) • クラスが別のクラスを継承するときに基本クラス(上位概念のクラス)においてpublicとなっているメンバに対して、それらをprivate/public/protectedにするのかを指定することができる(アクセス指定子と呼ぶ)。 class D :private B { //クラスBを継承、クラスBのpublicをprivateとする }; アクセス指定子を省略した場合 *structの場合 public *classの場合 private class D :public B { //クラスBを継承、クラスBのpublicをpublicとする }; class D :protected B { //クラスBを継承、クラスBのpublicをprotectedとする }; Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
基本クラスのアクセス制御(2) #include <iostream> using namespace std; class base { int x; public: void setx(int n) { x = n; } void showx() {cout << x << '\n';} }; // publicとして継承する class derived : public base { int y; public: void sety(int n) {y = n;} void showy() {cout << y << '\n';} }; • 基本クラスのprivateにはアクセスできない。つまり上記の例ではderivedクラスでは x にアクセスできない。 • アクセス指定子がprivateでも、基本クラスでpublic/protectedのものは派生クラス内で利用可能。 int main() { derived ob; ob.setx(10); // 基本クラスのメンバにアクセス ob.sety(20); // 派生クラスのメンバにアクセス ob.showx(); // 基本クラスのメンバにアクセス ob.showy(); // 派生クラスのメンバにアクセス return 0; } ●リスト7.1:例【1】 baseの派生クラスであるderivedがpublicになっているので、derivedクラスのオブジェクトobでsetxやshowxがメインで利用可能である。 Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
被保護メンバの使用(1) • 派生クラスから基本クラスのprivateメンバにはアクセスできない。派生クラスからアクセスするためには、基本クラスでpublicにしておく必要があるが、それでは不都合な場合もある。 • このような場合はprotectedを使用する。 • このprotectedは派生クラス以外にはprivateと同じ動作をする。 #include <iostream> using namespace std; class samp { // デフォルトにより非公開 int a; protected: // samp以外には非公開 int b; public: int c; samp(int n, int m) {a=n; b=m;} int geta() { return a; } int getb() { return b; } }; int main() { samp ob(10, 20); // ob.b = 99;エラー! bは被保護。したがって非公開 ob.c = 30; // OK。cは公開 cout << ob.geta() << ' '; cout << ob.getb() << ' ' << ob.c << '\n'; return 0; } Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
被保護メンバの使用(2) #include <iostream> using namespace std; class base { protected: // 基本クラス以外には非公開ながら int a, b; // 派生クラスからはアクセスできる public: void setab(int n, int m) {a=n; b=m;} }; class derived : public base { int c; public: void setc(int n) { c = n; } void showabc() { cout << a <<' '<< b <<' '<< c << '\n'; // この関数は基本クラスのaとbにアクセスできる } }; ●リスト7.2:例【2】 int main() { derived ob; // aとbは、ここではアクセスできない。 // 基本クラスとその派生クラス以外には非公開 // 従って、ob.aやob.bは使えない。 // baseでpublic,derivedでpublicなので // setabは利用可能である。 ob.setab(1, 2); ob.setc(3); ob.showabc(); return 0; } Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
class B class A class C コンストラクタ、デストラクタ、継承(1) • 派生クラスのオブジェクトが生成/破棄されたときコンストラクタ/デストラクタはどのように働くか? • class C のオブジェクトobjectが生成された時、 • C object; • コンストラクタは、A→B→Cの順番で起動される。 • 基本クラスは派生クラスの情報を知らない。 • 派生クラスは基本クラスの情報を参照していることが多いので、基本クラスを先に初期化する必要がある。 • デストラクタは、C→B→Aの順番で起動される。 Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
コンストラクタ、デストラクタ、継承(2) #include <iostream> using namespace std; class base { public: base() { cout << "baseクラスのコンストラクタ呼び出し\n"; } ~base() { cout << "baseクラスのデストラクタ呼び出し\n"; } }; class derived : public base { public: derived() { cout << "derivedクラスのコンストラクタ呼び出し\n"; } ~derived() { cout << "derivedクラスのデストラクタ呼び出し\n"; } }; int main() { derived o; //mainが呼ばれたときにコンストラクタ起動 return 0; //終了時にデストラクタが起動する } 実行結果 baseクラスのコンストラクタ呼び出し derivedクラスのコンストラクタ呼び出し derivedクラスのデストラクタ呼び出し baseクラスのデストラクタ呼び出し Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
コンストラクタ、デストラクタ、継承(3) • 派生クラスから基本クラスへの引数の受け渡し • 基本クラスのコンストラクタに引数を渡さなくてはいけない場合、派生クラスのコンストラクタから渡してやる必要がある。 派生クラスコンストラクタ(arg-list): 基本クラスコンストラクタ(arg-list){ 派生クラスのコンストラクタ本体 } class base { int i; public: base(int n) { cout<<"baseクラスのコンストラクタ\n"; i = n; } ~base(){ cout <<“baseクラスのデストラクタ\n"; } void showi() { cout << i << '\n'; } }; class derived : public base { int j; public: derived(int n) : base(n) { // 引数を基本クラスに渡す cout <<"derivedクラスのコンストラクタ\n"; j = n; } ~derived() {cout << “derivedクラスの デストラクタ\n"; } void showj() { cout << j << '\n'; } }; Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
SuperClass1 SubClass SuperClass2 SuperClass3 多重継承 • 多重継承(Multipule Inheritance) • 複数のクラスを継承すること • 複数のクラスの属性と操作をそのまま引き継ぐこと class SubClass : public SuperClass1, public SuperClass2, public SuperClass3 { メンバ定義; }; Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
A B C ABC 多重継承の例 • 基本クラスA,B,Cを継承した派生クラスABCの作成 class A { : }; class B { : }; class C { : }; class ABC : public A, public B, public C { : }; Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
Ball -x: int -y: int -r: int +Ball( ) +Ball(rr: int) +Ball(xx: int, yy: int) +Ball(xx: int, yy: int, rr: int) +~Ball( ) +setX(xx: int = 0): void +setY(yy: int = 0): void +setR(rr: int = 100): void +getX( ): int +getY( ): int +getR( ): int Ball3D - z: int + Ball3D( ) + ~Ball3D( ) + setZ(int zz = 0): void + getZ( ): int + show( ): void 課題1 • 以下のクラス図を表すプログラムを、例を参考にして作成しなさい。Ballクラスは前回課題にx,yを設定する関数を付加。 • なお、新しい関数の内容は例のとおり。 • また、main 部分は次ページのものをそのまま利用しなさい。 Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
課題1(2) int main(int argc, char **argv) { int x, y, z, r; cout << "x ? “ ; cin >> x; cout << "y ? “ ; cin >> y; cout << "z ? “ ; cin >> z; cout << "radius ? "; cin >> r; Ball3D bb; bb.show(); bb.setX(x); bb.setY(y); bb.setZ(z); bb.setR(r); bb.show(); return (0); } Ball3D クラスは Ball クラスを継承しているため、Ball3D クラスでは定義していない関数が利用できる 実行結果 x ? 12 y ? 15 z ? 12 radius ? 50 x = 10, y = 10, z = 10, radius = 10 x = 12, y = 15, z = 12, radius = 50 Volume = Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
Color ColoredBall3D - color: string + Color( ) + Color(ccolor:string) + ~Color( ) + setColor(ccolor:string) + getColor( ): string + ColoredBall3D( ) + ColoredBall3D(ccolor: string) + ColoredBall3D(xx:int,yy:int,zz:int,rr:int, ,ccolor:string) + ~ColoredBall3D( ) 課題2(1) • 下記のクラス図で示すプログラムを作成せよ。 • ただし、それぞれの内容は次のページに示すとおり。 • Main部分では以下のオブジェクトを作成し、それぞれのオブジェクの半径、位置、速度、色を表示させなさい。 • ColoredBall3D b1; • ColoredBall3D b2(“black”); • ColoredBall3D b3(3,5,7,10,“red”); Ball Ball3D Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
Color - color: string + Color( ) + Color(ccolor: string) + ~Color( ) + setColor(ccolor: string) + getColor( ): string 課題2(2) • Color Class • メンバ変数 • 色: color (string) • 色を文字列として保存しておく変数 • white, black, red, blue, green, yellow, … • メンバ関数 • Color( ) –コンストラクタ • 初期値は color = “white” • Color( string ccolor ) –コンストラクタ • 色の指定 color = ccolor とするコンストラクタ • ~Color( ) –デストラクタ • 何もしない • setColor( string ccolor ) • 色の設定 color = ccolor を行う関数 • getColor( ) • オブジェクトの持つ色を返す関数 • 戻り値は string 型 Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
ColoredBall3D + ColoredBall3D( ) + ColoredBall3D(ccolor: string) + ColoredBall3D(xx:int, yy:int, zz:int, rr: int, ccolor: string) + ~ColoredBall3D( ) 課題2(3) • ColoredBall3D Class • メンバ変数 • なし • メンバ関数 • ColoredBall3D( ) –コンストラクタ • ColoredBall3D( string ccolor ) –コンストラクタ • ColoredBall3D( int xx, int yy, int zz, int rr, string ccolor ) –コンストラクタ • ~ColoredBall3D( ) –デストラクタ • 何もしない Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp
コンパイルと実行 • まずはじめに • 作業ディレクトリの作成 $ mkdir ~/wrk/ $ mkdir ~/wrk/oo/ • 次に • 作業ディレクトリへの移動 $ cd ~/wrk/oo • プログラミング $ vi oo20-1.cc • コンパイル・リンク $ g++ -o oo20-1 oo20-1.cc • 実行 $ ./oo20-1 * C++言語プログラムのファイル名は、.ccでなければならない 一度実行すればよい 注意 • * プログラムが終了しなくなったら • Ctrl キーを押しながら c • を押して強制終了すること Object Oriented Language - Y.Nagasaka: nagasaka@cc.it-hiroshima.ac.jp