ホーム » スタッフ » 斉藤徹 » 継承を説明

2010年5月
« 4月   6月 »
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

最近の投稿(電子情報)

アーカイブ

カテゴリー

継承を説明

データを拡張してプログラムを作成することを通して、継承の概念を説明する。

C言語での限界

struct Person {
char name[ 10 ] ;
int   age ;
} ;
void print( struct Person* p ) {
printf( "%s %d\n" , p->name , p->age ) ;
}
struct Jyoshi {
struct Person person ;
int size ;  // 部下の人数
struct Person* table[ 10 ] ; // 部下へのポインタ
} ;
void print_jyoshi( struct Jyoshi* p ) {
print( &p->person ) ;
for( int i = 0 ; i < size ; i++ ) // 本人と部下のデータを表示
print( p->table[ i ] ) ;
}
void main() {
struct Person saitoh ; // 初期化も適度に行うとする
struct Jyoshi  ashida ;
print( &saitoh ) ;
// print( &ashida ) ;  // saitohと同じ様にprintしたいけど、できない
print( &ashida.person ) ;
print_jyoshi( &ashida ) ;
// 部下の表示が不要だとしたら
// わざわざJyoshiバージョンを作るのが面倒。
}

unionを使えば…

union PERSON { // 初期化の処理は省略
struct Person person ;
struct Jyoshi jyoshi ;
} ;

こういう方法を使えば、jyoshi の先頭部分はpersonであり、 共用体によって、同じ部分に person が配置されている。 こういった共用体を使って、拡張部分のあるデータを同じように扱うテクニックは、 unix のグラフィックシステム X11 に見られる。 例年は、共用体を使うテクニックまでは解説しないけど、 今年度は受講者が電子情報出身者だけになったので、解説を行った。

派生と継承

データを拡張しても同じように扱うテクニックとして、派生があることを説明。 前の例みたいなことは、C++であれば以下のように行う。

class Person { // データの共通部で元になるものを
private:       // 基底クラスと呼ぶ。
char name[ 10 ] ;
int  age ;
public:
Person( char s[] , int a ) { strcpy( name,s ) ; age = a ; }
void print() { printf( "%s %d\n" , name , age ) ; }
} ;
class Jyoshi : public Person { // 派生クラス
private:
int size ;
Person* table[ 10 ] ;
public:
Jyoshi( char s[] , int a )
: Person( s , a )  // 基底クラスの初期化
{ size = 0 ; }
void buka( Person* p ) { table[ size++ ] = p ; }
} ;
void main() {
Person saitoh( "saitoh" , 45 ) ;
Jyoshi ashida( "ashida" , 60 ) ;
ashida.buka( &saitoh ) ;
saitoh.print() ;
ashida.print() ; // ここがミソ:基底クラスのメソッドを流用
}

最後のJyoshiのデータ ashida において、print メソッドは存在しないが、 基底クラスのprintメソッドを流用してくれる。これを継承と呼ぶ。

void Jyoshi::print() {
Person::print() ;
for( int i = 0 ; i < size ; i++ )
table[ i ]->print() ;
}

上記のような、Jyoshi専用のprintを定義してもいい。