プログラミング言語論 第12回 オブジェクト指向 情報工学科 篠埜 功.

Slides:



Advertisements
Similar presentations
オブジェクト指向 言語 論 第八回 知能情報学部 新田直也. 多相性(最も単純な例) class A { void m() { System.out.println( “ this is class A ” ); } } class A1 extends A { void m() { System.out.println(
Advertisements

ソフトウェア工学 理工学部 情報システム工学科 新田直也. 演習問題 1 の解答例  入庫処理の DFD 酒屋の在庫問題の DFD( 入庫処理 ) 更新情報 在庫ファイル 更新処理 倉庫係 在庫不足リスト 在庫ファイル 出庫指示書 新規出庫 判定 出庫指示書 作成処理 出庫依頼 積荷票.
ソフトウェア工学 知能情報学部 新田直也. オブジェクト指向パラダイムと は  オブジェクト指向言語の発展に伴って形成され てきたソフトウェア開発上の概念.オブジェク ト指向分析,オブジェクト指向設計など,プロ グラミング以外の工程でも用いられる.  ソフトウェアを処理や関数ではなくオブジェク.
Generic programming と STL
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
5.データ構造入門 5-1.連結リスト(Linked List) 5-2.スタック(Stack) 5-3.キュー(Queue)
プログラミング基礎I(再) 山元進.
Javaのための暗黙的に型定義される構造体
プログラミングパラダイム さまざまな計算のモデルにもとづく、 プログラミングの方法論 手続き型 関数型 オブジェクト指向 代数 幾何.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
アルゴリズムとデータ構造1 2007年6月12日
プログラミング言語論 第6回 型 情報工学科 篠埜 功.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
情報工学概論 (アルゴリズムとデータ構造)
アルゴリズムとデータ構造 2011年6月13日
構造体.
プログラミング言語論 第10回 オブジェクト指向 情報工学科 篠埜 功.
プログラミング演習II 2004年12月 21日(第8回) 理学部数学科・木村巌.
データ構造とアルゴリズム 第13回 スタックとキュー
社会人学習講座 「Javaプログラミング概論」
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
ソフトウェア工学 知能情報学部 新田直也.
プログラミング言語入門 手続き型言語としてのJava
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
暗黙的に型付けされる構造体の Java言語への導入
プログラミング 4 記憶の割り付け.
プログラミング言語入門.
データ構造と アルゴリズム第4回 知能情報学メジャー 和田俊和.
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
プログラミング言語論 第13回 オブジェクト指向 情報工学科 篠埜 功.
アルゴリズムとデータ構造1 2005年7月1日
Java8について 2014/03/07.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
オブジェクト指向言語論 第八回 知能情報学部 新田直也.
一時的な型 長谷川啓
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング言語論 第十三回 理工学部 情報システム工学科 新田直也.
ソフトウェア工学 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
C#プログラミング実習 第3回.
計算機プログラミングI 木曜日 1時限・5時限 担当: 増原英彦 第1回 2002年10月10日(木)
アルゴリズムとデータ構造 2012年6月11日
アルゴリズムとデータ構造1 2009年6月15日
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
cp-2. 属性,アクセサ (C++ オブジェクト指向プログラミング入門)
オブジェクト指向言語論 第二回 知能情報学部 新田直也.
アルゴリズムとデータ構造 2010年6月17日
ソフトウェア工学 知能情報学部 新田直也.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
情報処理Ⅱ 2005年11月25日(金).
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
オブジェクト指向言語論 第十回 知能情報学部 新田直也.
C言語講座第5回 2017 構造体.
Presentation transcript:

プログラミング言語論 第12回 オブジェクト指向 情報工学科 篠埜 功

プログラムの分割 大きなプログラムは、分割して開発するのがよい。 手続きは分割の最も基本的なものである。 Module(モジュール)は、関連する変数、手続き、型を一つにまとめるものである。 手続きが処理するデータの型を一つのモジュール内に入れ、データ型の実装を隠す。

(参考)Opaque type Modula-2では、モジュールから型をexportするとき、 type stack; これをopaque exportといい、exportされた型をopaque typeという。 Importした側では、stack型の変数を var s, t: stack のように宣言できる。 Modula-2はopaque型について、代入、等しさのチェックをサポートする。ただし、opaque型はポインタに限られ、等しさの判定はポインタの等しさで判定される。

C++におけるクラス C++におけるクラスは、レコード(Cでは構造体と呼ばれる)を一般化したもの。 クラスを宣言した後はクラス名を型名として使用でき、その型の変数を宣言したり、オブジェクトを生成したりできる。 class Stack { public: int top; char elements [101]; char pop(); void push (char); Stack(); }; (例) struct Stack { int top; char elements [101]; char pop(); void push (char); Stack(); }; (参考)Simula 67のクラスをCに移植して設計されたのがC++。

C++でのクラス宣言 struct X { <declarations> }; は、 class X { public : <declarations> } と同じであり、 class X { <declarations> }; struct X { private : <declarations> }; と同じである。

クラス宣言の例 class Stack { int top; int size; char *elements; public: Stack (int n) {size=n; elements = new char[size]; top=0;} ~Stack() { delete elements; } void push (char a) {top++; elements[top] = a; char pop() {top--; return elements[top+1]; };

オブジェクトの生成、破棄 C++ではオブジェクトはnewで生成し、deleteで破棄する。任意の型Tについて、 new T delete p によって、pが指しているオブジェクトが破棄される。 (例) 前ページの例の、elements = new char [size] によって、char型を要素とする長さsizeの配列が生成される。elements[0], elements[1], …, elements[size-1]によって配列の各要素が得られる。また、delete elementsによって配列オブジェクトが破棄される。

例: 後ろからも要素を追加可能なリスト class List { Cell * rear; public: void put (int); void push (int); int pop(); int empty() { return rear == rear->next; } List() { rear = new Cell (0); } ~List() { while(!empty()) pop(); } }; class Cell { int info; Cell * next; Cell (int i) { info = i; next = this; } Cell (int i, Cell *n) {info = i; next = n; } friend class List; }; List中の関数はCellのprivateなメンバーにアクセスできる。

例(続き) void List::push (int x) { rear->next = new Cell (x, rear->next); } void List::put (int x) { rear->info = x; rear = rear->next = new Cell (0, rear->next); int List::pop() { if (empty()) return 0; Cell * front = rear->next; rear->next = front->next; int x = front->info; delete front; return x;

テンプレート(例) template <class T> class Stack { int top; int size; T * elements; public: Stack (int n) {size=n; elements = new T[size]; top=0;} ~Stack() { delete elements; } void push (T a) { top++; elements[top]=a; } T pop() { top--; return elements[top+1]; } }; Stack型の変数を宣言したりオブジェクトを生成したりするとき、Stack<int> s(99); のように型を<>内に引数として与える。

CとC++ C++は1983年、Bjarne Stroustrupによって設計、開発された。Cの拡張として設計されており、ほとんどのC言語のプログラムはC++のプログラムであり、意味も同じである。ただし、CとC++で意味が違うプログラムがある。 コメントは、Cでは /* … */だが、C++では // … (C99では// もコメントとして使えるが) (例) int f (int a, int b) { return a //* */ b ; } returnの右に書かれている式は、C89ではa/b, C++およびC99ではaとなる。

CとC++(続き) C++では、構造体型を名前付きで宣言する構文で宣言した場合、その名前のみで構造体型を表せる。 (例1) struct test {int a;} test x; のように書いてよい。Cでは、struct test x;と書く必要がある。(C++でstruct test x; と書いてもよいが。) (例2) int x[99]; void f() { struct x {int a;}; sizeof (x); } sizeof(x)は、Cでは配列xのサイズ、C++では構造体xのサイズ。Cでは、構造体xのサイズはsizeof(struct x) と書かなければならない。

CとC++(続き) Cでは、sizeof(‘a’)はsizeof(int)と同じである。 C++では、sizeof(‘a’)はsizeof(char)と同じである。 Cでは、列挙型のサイズはsizeof(int)である。 C++では、列挙型のサイズは、処理系依存である。 (列挙型の例) enum color {RED, BLUE, YELLOW}; のように列挙型colorを宣言すると、Cではsizeof(enum color)はsizeof(int)と同じ、C++では処理系依存。

オブジェクト指向 オブジェクト指向はシミュレーションを記述することを意図して考え出された。シミュレーションの中の要素がオブジェクトである。 (例) Simula(Simulation language, 1967) Ole-Johan Dahl, Kristen Nygaardが開発 最初のオブジェクト指向言語(オブジェクト指向という言葉はまだなかったが、オブジェクト指向における種々の概念が含まれていた) ALGOLの拡張として設計された 空港のシステムの記述が重要な例となっていた

オブジェクト指向 [オブジェクトの例] 乗客、航空会社のカウンター、行列、チケット、… (外側からの見た場合) [オブジェクトの例] 乗客、航空会社のカウンター、行列、チケット、… (外側からの見た場合) オブジェクト間でメッセージをやりとりすることにより計算が進んでいく。 (内側から見た場合) メッセージを受け取ったら、それに対応する手続きを実行する。この手続きのことを、メソッド(method)あるいはメンバ関数(member function)という。

クラスの階層構造 Shape Box Ellipse Line Text Circle Shape Box Ellipse Line

継承(inheritance) 子クラスは親クラスのメソッド、変数を継承する(親クラスのメソッド、変数が子クラスのメソッド、変数になる)。 子クラスでは、追加でメソッドや変数を定義できる。同じ名前の場合には上書き(override)される。 (注意)overloadはoverrideとは全く別の概念。Overloadは、引数の数や型が違うメソッドに同じ名前をつけること。

C++の例 C++では、継承は以下のように記述する。 class Box : public Shape { … } すべてのメンバーをvisibilityを保って継承する。 class Box : private Shape { … } 継承されたメンバーはdefaultでprivateメンバーになる。 C++では親クラスを基底クラス(base class)、子クラスを派生クラス(derived class)という。

仮想関数(virtual function) class D : public B { public: char f () { return ‘D’; } char g() { return ‘D’; } }; #include <iostream> int main (void) { D d; std::cout << d.testF() << d.testG() << "\n"; return 0; } class B { public: virtual char f () { return ‘B’; } char g() { return ‘B’; } char testF() {return f(); } char testG() { return g(); } }; d.testF()は’D’を返し、d.testG()は’B’を返す。

補足 メソッドは、(C++コンパイラ内で)引数を1つ追加した関数へコンパイルすればよい。 char testF() { return f(); } char testF (B * this) { return this->f(); } d.testF()をtestF(d)にコンパイルすれば、(クラスBにおいてfはvirtualなので)testFの本体でdに対してメッセージfが送られることになり、’D’が返される。

C++の特徴 Cとのbackward compatibilityをできる限り保ちつつオブジェクト指向をサポートするように設計された。 オブジェクトをCの構造体の拡張とした。つまり、オブジェクトは関数のactivation recordやlocal block内にallocateされ得る。(もちろんヒープにもallocateできるが。) オブジェクト指向ではないプログラミング(命令型のプログラミング)もできる。(プログラミングのスタイルをプログラマに強要しない。) Multiple inheritanceをサポートする。(授業範囲外とする)

オブジェクト指向言語のまとめ オブジェクト指向言語(object-oriented language)は、オブジェクトを持ち、以下の4つの特徴を持つ。 Dynamic lookup(メッセージを受け取ったときに実行されるメソッドは実行時に決まる) Abstraction(public関数がインターフェースとなり、データや実装は他の部分から見えない) Subtyping(派生クラス型の式は基底クラス型の式と置き換えてもよい(publicで継承している場合)) Inheritance(継承。コード量が削減され、コードを修正しやすくなる。)

注意 Subtypingとinheritanceは異なる概念である。 (例) Queue --- first-in, first-out Stack --- last-in, first-out Dequeue --- 両端から出し入れ可能なqueue Dequeueの派生クラスとしてQueueクラスとStackクラスを実装することができる(privateな継承を使って必要なメソッドのみpublicにすれば)。 しかし、Queue, StackはDequeueのsubtypeではない。

(参考)Data invariant 制御がオブジェクト内にないときに常に成り立つ性質 (例) bounded buffer(長さ制限付きqueue) put(x), get()の2つのメソッドからなる。 配列に要素を格納し、frontとrearで範囲を示す。配列の最後の要素の次は最初の要素とする。 バッファーはfrontとrearが等しいとき空 Rearの次の要素がfrontのときバッファーは一杯 Frontとrearの間に、入力された順に要素が並んでいる。 オブジェクトは、data invariantを考慮しつつ設計する