プログラミング言語論0615

Download Report

Transcript プログラミング言語論0615

プログラミング言語論
第十回
理工学部
情報システム工学科
新田直也
オブジェクト指向の歴史

実は起源は明らかではない.



チューリング賞:



Simula67: クリステン・ニガード, オルヨハン・ダール
SmallTalk72: アラン・ケイ
2001年 クリステン・ニガード, オルヨハン・ダール
2003年 アラン・ケイ
現在の主流


C++: ビャーネ・ストロヴストルップ (1979年)
Java: ジェームズ・ゴスリング, SUN (1991年)
オブジェクト指向の主要概念

オブジェクト指向を特徴付ける3つの概念:

カプセル化(クラス):
データとそれに関連する手続きを一体化し,他の部分から
分離(隠蔽)すること.分離した部分をクラスと呼ぶ.クラス
は言語中では型としての役割を持つ(抽象データ型).

継承:
あらかじめ基本となる機能を(親クラスとして)定義し,その
機能を引き継ぐ形で拡張機能(子クラス)を定義すること.

多態性(ポリモルフィズム):
オブジェクトの種類(クラス)を知ることなくその機能を使える
ようにする仕組み.(遅延束縛,動的結合)
モジュールプログラミング

カプセル化はC言語でも実現されている.

モジュールプログラミング:
プログラムを機能毎に複数のモジュール(ファイル)
に分けて開発する手法.C言語では分割コンパイル
でサポートされている.

情報隠蔽,関心事の分離,カプセル化.
モジュールの例

リストモジュール(list.c)
《list.c》
#include “list.h”
int list[LIST_MAX];
int num = 0;
void init_list(void) {
num = 0;
}
int get_list_num(void) {
return num;
}
:
《list.h》
#define LIST_MAX 1000
void init_list(void);
int get_list_num(void);
int read_list(int k);
void write_list(int k, int v);
void insert_list(int k, int v);
void delete_list(int k);
モジュールの構成

モジュールには大域変数と関数定義が含まれる
《list.c》
#include “list.h”
int list[LIST_MAX];
int num = 0;
void init_list(void) {
num = 0;
}
int get_list_num(void) {
return num;
}
:
大域変数
関数定義
(他のモジュールから呼ばれる)
モジュールによる情報隠蔽

大域変数と関数定義はカプセル化され隠蔽される.
《list.c》
#include “list.h”
int list[LIST_MAX];
int num = 0;
void init_list(void) {
num = 0;
}
int get_list_num(void) {
return num;
}
:
カ
プ
セ
ル
化
他のファイル
から見えない
→情報隠蔽
モジュールの利用方法

モジュールはヘッダ(list.h)を通じて利用.
《list.c》
#include “list.h”
int list[LIST_MAX];
int num = 0;
void init_list(void) {
num = 0;
}
int get_list_num(void) {
return num;
}
:
#include “list.h”
:
init_list();
:
list.h が橋渡しの役割
ヘッダの内容

ヘッダはインタフェースの役目をする.
《list.c》
#include “list.h”
int list[LIST_MAX];
int num = 0;
void init_list(void) {
num = 0;
}
int get_list_num(void) {
return num;
}
:
《list.h》
#define LIST_MAX 1000
void init_list(void);
int get_list_num(void);
int read_list(int k);
void write_list(int k, int v);
void insert_list(int k, int v);
void delete_list(int k);
利用者はインタフェースのみ知って
いれば使える.
実装の変更の影響を受けない.
モジュールプログラミングのまとめ

モジュールプログラミング:

モジュール中の大域変数と関数定義はカプセル化され,
他のモジュールから隠蔽される.

モジュールのインタフェースは公開される.

利用者はインタフェースのみ知ってれば利用できる.

利用者は実装の変更の影響を受けない.
抽象データ型(1)

任意個のリストを扱いたい場合どうするか?


list.c の大域変数は1組しか用意されていない.
List構造体を定義しよう!
《list.c》
#include “list.h”
int list[LIST_MAX];
int num = 0;
void init_list(void) {
num = 0;
}
:
struct List {
int list[LIST_MAX];
int num = 0;
};
変数をモジュールの代わりに
構造体の中に隠蔽する
抽象データ型(2)

関数定義はどうする?
《list.c》
#include “list.h”
int list[LIST_MAX];
int num = 0;
void init_list(void) {
num = 0;
}
int get_list_num(void) {
return num;
}
:
《list.h》
struct List {
int list[LIST_MAX];
int num = 0;
};
《list.c》
void init_list(struct List *l) {
l->num = 0;
}
int get_list_num(struct List *l) {
return l->num;
}
→関数はモジュールに残される
抽象データ型(3)

利用者(呼出し側)は?
#include “list.h”
:
struct List l1, l2;
init_list(&l1);
init_list(&l2);
:
利用者側でList構造体の変数を宣言.
任意の場所で任意個宣言できる.
クラス

抽象データ型を直接表現したもの.
関数を構造体の中に入れたものと考えてもよい.
struct List {
int list[LIST_MAX];
int num = 0;
};
void init_list(struct List *l) {
l->num = 0;
}
int get_list_num(struct List *l) {
return l->num;
}
:
class List {
int list[LIST_MAX];
int num = 0;
void init_list(void) {
num = 0;
}
int get_list_num(void) {
return num;
}
:
}
クラスの定義

クラスは,メンバ変数(フィールド)とメンバ関数
(メソッド)によって構成される.
class List {
int list[LIST_MAX];
int num = 0;
}
void init_list(void) {
num = 0;
}
int get_list_num(void) {
return num;
}
:
メンバ変数
メソッド
クラスの利用



オブジェクト指向ではあるクラスを型とみなしたときの変数を
インスタンス(オブジェクト)と呼ぶ.
インスタンスは利用者側が生成する.
インスタンスのメンバへは”.”でアクセスする.
#include “list.h”
:
struct List l1, l2;
init_list(&l1);
init_list(&l2);
:
class List l1 = new class List();
class List l2 = new class List();
l1.init_list();
l2.init_list();
:
利用者側でListクラスのインスタンスを生成.
カプセル化のまとめ

クラス:
データとその操作をカプセル化したもの.
(モジュール×構造体?)

オブジェクト:
クラスを実体化したもの.クラスを型とみなしたときの変数に
相当.

メンバ変数: クラスが持つ変数.

メソッド: クラスが持つ関数.