Microsoft PowerPoint - 09-object

Similar documents
Microsoft PowerPoint - HITobject.ppt

Microsoft PowerPoint - object.ppt

Microsoft PowerPoint - object.ppt [互換モード]

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

PowerPoint プレゼンテーション

プログラミング基礎I(再)

Microsoft PowerPoint - prog03.ppt

Microsoft PowerPoint - chap10_OOP.ppt

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

Javaの作成の前に

メディプロ1 Javaプログラミング補足資料.ppt

た場合クラスを用いて 以下のように書くことが出来る ( 教科書 p.270) プログラム例 2( ソースファイル名 :Chap08/AccountTester.java) // 銀行口座クラスとそれをテストするクラス第 1 版 // 銀行口座クラス class Account String name

GEC-Java

プログラミング実習I

JavaプログラミングⅠ

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

11 ソフトウェア工学 Software Engineering デザインパターン DESIGN PATTERNS デザインパターンとは? デザインパターン 過去のソフトウェア設計者が生み出したオブジェクト指向設計に関して, ノウハウを蓄積し 名前をつけ 再利用しやすいようにカタログ化したもの 各デ

プログラミング入門1

Javaプログラムの実行手順

レコードとオブジェクト

PowerPoint プレゼンテーション

Prog2_12th

メソッドのまとめ

Microsoft PowerPoint - prog04.ppt

PowerPoint プレゼンテーション

プログラミング入門1

基本情報STEP UP演習Java対策

JavaプログラミングⅠ

Java言語 第1回

ガイダンス

Microsoft PowerPoint ppt

できるプログラマーを本気で育てる Java 超 Webプログラマーへの第 歩 第 2 回オブジェクト指向 テクノロジックアート 瀬 嘉秀

ガイダンス

ガイダンス

プログラミング入門1

JavaプログラミングⅠ

C#の基本

Prog2_9th

書式に示すように表示したい文字列をダブルクォーテーション (") の間に書けば良い ダブルクォーテーションで囲まれた文字列は 文字列リテラル と呼ばれる プログラム中では以下のように用いる プログラム例 1 printf(" 情報処理基礎 "); printf("c 言語の練習 "); printf

PowerPoint プレゼンテーション

ガイダンス

Javaセキュアコーディングセミナー2013東京第1回 演習の解説

コンピュータ工学講義プリント (7 月 17 日 ) 今回の講義では フローチャートについて学ぶ フローチャートとはフローチャートは コンピュータプログラムの処理の流れを視覚的に表し 処理の全体像を把握しやすくするために書く図である 日本語では流れ図という 図 1 は ユーザーに 0 以上の整数 n

Microsoft Word - no11.docx

JavaプログラミングⅠ

PowerPoint プレゼンテーション

Microsoft PowerPoint pptx

Prog1_6th

Microsoft PowerPoint - 09.pptx

2

V8.1新規機能紹介記事

JAVA入門

JavaプログラミングⅠ

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

第2回講義

Prog1_15th

コンピュータ中級B ~Javaプログラミング~ 第3回 コンピュータと情報をやりとりするには?

ガイダンス

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

Microsoft PowerPoint - lec06 [互換モード]

02: 変数と標準入出力

レコード class Point attr_accessor("x", "y") インスタンス変数の宣言 point.rb

メソッドのまとめ

プログラミング基礎

ガイダンス

レコードとオブジェクト

Microsoft PowerPoint - prog09.ppt

HCI プログラミング 10 回目テキストフィールドとキーイベント 今日の講義で学ぶ内容 テキストフィールドの利用 キーイベントの処理 テキストフィールドの利用 1 テキストフィールドを配置してみましょう テキストフィールドを用いることにより 数値や文字列などのデータ入力が可能になります ソースファ

Java講座

Java 基礎問題ドリル ~ メソッドを理解する ~ 次のプログラムコードに 各設問の条件にあうメソッドを追加しなさい その後 そのメソッドが正しく動作することを検証するためのプログラムコードを main メソッドの中に追加しなさい public class Practice { // ここに各設問

Microsoft PowerPoint - handout07.ppt [互換モード]

PowerPoint Presentation

ただし 無作為にスレッドを複数実行すると 結果不正やデッドロックが起きる可能性がある 複数のスレッド ( マルチスレッド ) を安全に実行する ( スレッドセーフにする ) ためには 同期処理を用いるこ とが必要になる 同期処理は 予約語 synchronized で行うことができる ここでは sy

Microsoft PowerPoint - prog09.ppt

02: 変数と標準入出力

memo

PowerPoint プレゼンテーション

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

Sort-of-List-Map(A)

教材ドットコムオリジナル教材 0から始めるiアプリ (4) 0 から始める i アプリ (4) i アプリをプログラミングする際に必要なのは Java というプログラミング言語の基礎知識です 独自の命令や駆使してプログラミングをするわけですが Java というベースになっている言語を知らないでプログ

memo

HCI プログラミング 8 回目ボタン チェックボックス ラジオボタン 今日の講義で学ぶ内容 ボタンとアクションイベント ボタンのカスタマイズ チェックボックスとラジオボタン ボタンとアクションイベント 1 ボタンを配置してみましょう ボタンは ラベルと同じようにフォントやその色 画像の貼り付けなど

Microsoft Word - VBA基礎(6).docx

C#の基本2 ~プログラムの制御構造~

Microsoft PowerPoint - prog07.ppt

PowerPoint プレゼンテーション

人工知能入門

JavaプログラミングⅠ

プログラミングA

kantan_C_1_iro3.indd

Microsoft PowerPoint - OOP.pptx

Week 1 理解度確認クイズ解答 解説 問題 1 (4 2 点 =8 点 ) 以下の各問いに答えよ 問題 bit 版の Windows8.1 に Java をインストールする時 必要なパッケージはどれか 但し Java のコンパイルができる環境をインストールするものとする 1. jdk

GEC-Java

Microsoft Word - 3new.doc

ウィンドウの構成ウィンドウはタイトルバーとウィンドウ枠からなります タイトルバーには最小化 / 最大化ボタンや閉じるボタンがあります また ウィンドウはクライアント領域をもちます クライアント領域にはボタンなど GUI 部品が配置されます GUI 部品配置 ( レイアウト ) ウィンドウ ( ステー

Microsoft PowerPoint - ●SWIM_ _INET掲載用.pptx

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

JavaプログラミングⅠ

Prog1_10th

Transcription:

9 ソフトウェア工学 Software Engineering オブジェクト指向プログラミング OBJECT-ORIENTED PROGRAMMING オブジェクト指向プログラミングの考え方とその 3 大特徴および Java 言語によるプログラムの記述例を学ぶ.Java はインターネットなどと連携した現代的なプログラムを記述するのに適した実用的なプログラミング言語である. ただし, この講義は Java を修得してもらうことを目的としているわけではないので,Java の細部は理解できなくてもかまわない. オブジェクト指向の概念と 3 つの特徴を理解してほしい. 1

構成 Part1 オブジェクト指向の基本概念 Part2 オブジェクト指向の 3 大特徴 1 カプセル化 2 継承 ( インヘリタンス ) 3 ポリモーフィズム ( 多相性 ) 今回の授業では, オブジェクト指向プログラミングの最も特徴的な考え方を学ぶ. 具体的なプログラミングは Java を用いるが,Java の詳細を学ぶことが目的ではない. Part1 でオブジェクト指向の基本概念を説明した後,Part2 でオブジェクト指向の 3 大特徴を学ぶ. 2

Part1 オブジェクト指向の基本概念 3

オブジェクトとは? データと操作をカプセル化した もの オブジェクト カプセル化 X 軸方向のみに進むロボット 位置速度燃料どこ? 変速 データ ( フィールド ) メンバ 操作 ( メソッド ) オブジェクト (object) とは何か? その答えを短く言うと, データと操作をカプセル化したもの となる. とはいえ, それで内容が理解できるとは思えないので, 順を追って内容を見ていく. この授業では, このスライドに表示されているようなロボットを動かすプログラムを考える. このロボットが オブジェクト のつもりである. このロボットは x 軸上を進むものである. ロボットの状態は, 現在の 位置, 現在の 速度, 現在の 燃料 の 3 つのデータで表すことができる. それらのデータはロボットの胸のあたりにあるメモリーに内蔵されている. また, このロボットはリモコンの 3 つの操作を受け付ける. 1 つめの操作は, どこ? というボタンを押すことで, 現在位置 (x 座標の値 ) を返してくれる.( それは, たとえば, リモコンの表示画面に表示される.) 2 つめの操作は, 変速 というボタンを押して, 速度を設定できる. 実際には, このボタンを押すほかに, さらに設定すべき新しい速度の値を補助情報として入力する必要がある. 3 つめの操作は, ボタンで, これを押すと,1 秒間だけ, 現在の設定速度でロボットが前進する. リモコンからのこれらの指示を実行するためのプログラムがロボットの足のあたりに内蔵されている. オブジェクト指向プログラミングの用語では, いま述べた データ のことを フィールド (field), 操作 のことを メソッド (method) という. フィールド と メソッド を総称して メンバ (member) ということもある. 一般的なプログラミング用語で言えば, フィールドは変数, メソッドは関数のようなもので, いずれもデジタルなデータあるいは機械語コードで表現できる. それらが, このロボットという オブジェクト の中にまとめて閉じこめられている様子を カプセル化 (encapsulation) というのだが, もっと正確な説明は後にわかってくる. 重要なのは, オブジェクト というのは単なる概念ではなく, これらのデジタルなデータまたはコードからなり, コンピュータのメモリの一定領域を占める具体的な 実体 だということである. この 実体 あるいは もの が英語の object という単語の意味である. 4

メモリ内にオブジェクトがうようよできる 位置 5 8-4 速度 +1-1 2 燃料 10 8 0 どこ? どこ? どこ? 変速 変速 変速 オブジェクト は一定の実メモリ領域を占める もの であるが, ふつう, オブジェクト指向でプログラムを書くと, そのようなオブジェクトがたくさん生成される. それぞれのオブジェクトごとにメモリ領域が占められる. ロボットの場合には, このスライドのように, 状態 ( 各フィールド 位置, 速度, 燃料 のそれぞれの値 ) の異なるロボットが生成されるわけである. ただし, 操作 ( メソッド ) を表すプログラムコードはこれらのオブジェクトに共通である. 5

いろんな種類 ( クラス ) のオブジェクトが共存する 8 1 6 7 2 4 ロボットクラス 2 3 1 船クラス オブジェクトにはいろいろな種類のものがあってよい. たとえば, オブジェクト指向で書かれたあるコンピュータゲームの中では, ロボットのほかに船が出てきて, ロボットが船に乗って, いろいろな島に渡って冒険をするのかもしれない. この場合, ロボット と 船 は異なる種類のオブジェクトである. オブジェクトの種類のことを クラス (class) という. この例の場合, ロボットクラス, 船クラスという 2 つのクラスのオブジェクトが存在することになる. 6

オブジェクトはクラス ( ひな形 ) から生成されるインスタンス ( 実例 ) クラス 6 2 位置 速度 燃料 9 2 3 4 インスタンス 操作 ( メソッド ) は クラスで共通 どこ? 変速 データ ( フィールド ) は インスタンス毎 2 5 4 オブジェクト指向プログラミングで初心者が最初につまづく点は, クラス と インスタンス の区別である. クラス (class) とは, オブジェクトを作るための ひな形 あるいは 設計図 のようなものである. ロボットの例の場合, 位置, 速度, 燃料 というフィールドがあることがこの設計図に書かれている. しかし, 当然だが, その 現在の値 というのはない. 一方, インスタンス (instance) とは, この設計図から作られた 実例 のことであり, 各フィールドには 現在の値 が記録されている. このスライドでは,1 つのクラスから異なる 3 つのインスタンスが生成されている. これまで出てきた オブジェクト という言葉は, この インスタンス と同じ意味である. メソッドの具体的なコードもクラスに記述されている. このクラスからインスタンスを生成すると, 各インスタンスにはこれらのメソッドがそのままコピーされる.( ただし, これは概念上の話で, 実際には,1 台のコンピュータ内に同じものをたくさんコピーしておくのは無駄が多いので, ポインタなどを用いて効率的に実装されている.) 以上の結果, 操作 ( メソッド ) はクラスで共通に使用され, データ ( フィールド ) はインスタンス毎に異なるものとして使われることになる. 7

整数型 戻り値のデータ型 値を戻す 戻り値なし Java ではクラスを記述する ( ロボットになったつもりで書く ) class ロボット int 位置 ; int 速度 ; int 燃料 ; メソッド名 int どこ?() { return( 位置 ); void 変速 (int 新速度 ) { 速度 = 新速度 ; 続くクラス名 フィールド名 種々の名前には日本語を使える このスライドのプログラムが, これまで設計したロボットを Java で記述したものである. Java で記述するものは, 実際にはクラスである. ここではクラス名を ロボット としている. フィールドは, 他のプログラミング言語 ( たとえば,C 言語 ) における変数宣言のような形で宣言される. メソッドは,(C 言語における ) 関数定義のような形で定義される. ロボットメソッドのプログラムを書くときのコツは, 自分自身がロボットになったつもりで書くことである. どこ? メソッドは, 自分が どこ? と質問されたつもりで考えて, 戻り値として, 現在位置の値を返すことにする. 変速 メソッドは, 指定された 新速度 の値に変えよと命令されたつもりになって, 自分自身の状態変数である 速度 に, 外部から指定された 新速度 の値を保存する. 8

Java ではクラスを記述する ( 続き ) class ロボット { int 位置 ; int 速度 ; int 燃料 ; //---------------------- int () { if ( 燃料 > 0) { 位置 = 位置 + 速度 ; 燃料 = 燃料 - 1; return 0; else { return (-1); 再掲続く メソッドは, 自分が と命令されたらどうするかを考えて書く. ここでは, 現在設定されている速度で 1 単位時間だけ前進し, 燃料が 1 単位消費される. その結果, 位置 と 燃料 の値が更新される. この場合, 正常終了したので, エラーコードとして戻り値 0 を返すような設計としてある. 燃料が 0 なら, 進むことはできず, エラーコードとして -1 を返すことにした. 9

クラス定義の終わり コンストラクタも記述する class ロボット { int 位置 ; int 速度 ; 再掲 int 燃料 ; //---------------------- ロボット (int p, int v, int f) { 位置 = p; 速度 = v; 燃料 = f; インスタンス生成時フィールドを初期化 Constructor ロボットのインスタンスが生成されたときに, そのフィールドを初期化するなどのために, コンストラクタ (constructor) という特別なメソッドを定義しておく. Java では, コンストラクタの名前はクラス名と同じにするという約束になっている. したがって, このスライドでは, ロボット というコンストラクタを定義している. この定義の内容は, ロボットのインスタンス生成時にプログラマから引数として渡される p, v, f という 3 つの整数値を, それぞれ, 位置, 速度, 燃料 の 3 つのフィールドの現在値 ( 初期値 ) として記録 ( 代入 ) することを表している.(p, v, f は,position, velocity, fuel の頭文字.) これが典型的なコンストラクタの定義である. すなわち, 引数で与えられたデータをフィールド ( 状態 ) の初期値として記録するのである. 10

ロボットを生成し, 使用する ( ロボットのコントローラを持ったつもりで書く ) public class ロボットのテスト { public static void main(string args[]) { ロボット robocop = new ロボット (0,1,10); ローカル変数宣言 robocop. (); ロボット生成 robocop. 変速 (2); ( コンストラクタ呼出し ) while(robocop. どこ?() < 10) { robocop. (); ロボットを使う ( メソッド呼出し ) これはロボットを使う簡単なプログラムである. ロボットを使うプログラムを書くときのコツは, 自分がロボットのコントローラを持ったつもりで, いろいろなボタンを押しまくるように書く. ここで比喩的に言っている ボタンを押す とは, すでに定義した 3 つの メソッドを呼び出す ことである. オブジェクト ( インスタンス ) は,new というキーワードの後にコンストラクタを呼び出す形式で生成する. この例では,new ロボット (...) によって, ロボットのインスタンスを生成し, コンストラクタの記述にしたがって, 位置 =0, 速度 =1, 燃料 =10に設定している. そのロボットを robocop と名付ける. これは robocop という変数を ロボット型 と宣言し, その変数の初期値として, いま生成されたロボット ( への参照 ( ポインタ )) を代入することである. Java では, オブジェクト. メソッド名 ( 引数,..., 引数 ) の形の式を書くことによって, オブジェクトのメソッドを引数を指定して呼び出す ( 実行する ) ことができる. このプログラムでは,Robocop. () によって 1 秒だけロボットを進ませ, つぎに Robocop. 変速 (2) によって速度を 2 に変える. つぎに while ループの中で,rococo. どこ?( ) によって現在位置を取得し, それが 10 未満である間, ループの中でボタンを連打する. 現在位置が 10 以上になった時点でプログラムは停止する. このようにして, ロボットクラスで定義された 3 つのメソッド, 変速, どこ? を ( コントローラーのボタンを押しているかのように ) 適切に呼び出しながらロボットを動かすプログラムである. プログラミングの際には, ロボットを作る メーカー と, ロボットを買って動かす ユーザ - との区別が大事である. メーカーは, ロボットを動かす汎用的なソフトウェア部品をクラスとして制作する. そのプログラムは自分がロボットになったつもりで書く. それに対してユーザーは, 自分の応用目的に応じて, アプリケーションを制作する. そのプログラムは自分がロボットのコントローラーを持ったつもりで書く. 11

Part2 オブジェクト指向の 3 大特徴 1 カプセル化 2 継承 ( インヘリタンス ) 3 ポリモーフィズム ( 多相性 ) オブジェクト指向プログラミングにはさまざまな特徴があるが, このスライドに示したものが, もっとも大きな 3 つの特徴と考えられている. それぞれを見ていこう. 12

特徴 1: カプセル化 (encapsulation) 1 カプセル化 2 継承 ( インヘリタンス ) 3 ポリモーフィズム ( 多相性 ) 13

用可ロボットクラス使いろんなクラスが出てきたら... 制作者 B 船クラス 船のフィールドの宣言 船のメソッドの宣言 アクセス不可カプセル化制作者 A ロボットのフィールドの宣言ロボットのメソッドの宣言 カプセル ( 殻 ) の硬さも重要 制作者 A がロボットクラスをプログラムし, 制作者 B が船クラスをプログラムしているとしよう. これらのプログラムは最終的に 1 つの計算機の同一メモリ内で実行されるので,2 人の制作者は連絡を密にして注意深くプログラムを作らないと思わぬミスを生むことがある. たとえば, 制作者 B が, 船のメソッドの中でロボットのフィールドの値を勝手に変更するプログラムを書くと, ロボットが制作者 A の思わぬ状態変化をして, 大変都合が悪い. そのため, オブジェクト指向の考え方では, 基本的に,1 つのクラスの中のプログラムが, 他のクラスのフィールドの値を直接読み書きすることを禁じている. そのかわり, メソッドの呼び出しを通して, フィールドにアクセスできるようにする.( 読み書き をまとめて アクセス という.) これにより, 意図しないプログラムの動作を防止して, バグ ( 誤り ) の生成を抑制し, セキュリティを高めている. つまり, 各クラスはある種の殻によって, 内部へのアクセス方法を制限している. あるいは, 内部のフィールドを保護している. この機能を カプセル化 と呼ぶ. このスライドの太いピンク色の部分が殻 ( あるいはカプセル ) のつもりである. カプセルの殻の中にフィールドとメソッドが閉じ込められている. この殻の固さは, ほかのクラスのプログラムが内部のフィールド に直接アクセスすることを防御できる程度に固い. しかし, ほかのクラスのプログラムが自分のメソッドを呼び出すことを許す程度に柔らかい. カプセルという言葉で, 薬が思い浮ぶ. 子供などが粉薬 ( こなぐすり ) を飲みやすくするために, オブラートでできているカプセルに入れることがある. カプセルを飲み込むと, カプセルは胃の中で解け, 中の薬が胃の中に出てきて吸収される. このカプセルの固さにも注意が必要である. 飲むときに破れて口の中に薬がこぼれてしまわない程度に固い必要がある. しかし, 胃の中で溶ける程度には柔らかくなければならない. このように, カプセル化は, オブジェクトの内部情報へのアクセスを, 適切なレベル ( 殻の硬さ ) で保護している. 14

カプセル化メソッドを通してのみ, フィールドにアクセス メソッド フィールド アクセス メソッド フィールドフィールド メソッド. メソッド名 ( 引数,..., 引数 ) メソッド オブジェクトとは, データと操作をカプセル化した もの オブジェクトのフィールドには, メソッドを通してのみアクセスできる という概念を図にすると, このスライドのような感じとなる. ちょうど, フィールドがたまごの黄身で, メソッドがその白身であるかのように, フィールドはメソッドによって周囲を囲まれ, 守られている. そのため, フィールドの中味にオブジェクトの外部から直接アクセスすることができない. フィールドにアクセスするには, オブジェクト. メソッド名 ( 引数,..., 引数 ) の形のプログラムコードを書いて, オブジェクト内のメソッドを起動するしかない. このスライドの図は, このプログラムコードの文法に似せて描いてある. 15

ゲッター, セッター, コンストラクタは超基本メソッド class Robot int position; int getposition() { return(position); void setposition(int p) { position = p; Robot(int p) { position = p; Getter 値を取得 Setter 値を設定 ローカル変数寿命が短い Constructor 値を初期化 最も基本的なメソッドは, ゲッター (getter), セッター (setter), コンストラクタ (constructor) である. ゲッターは, 値を読み取る ( ゲットする ) ためのメソッドである. サッカーなどのスポーツでたくさん点を取る人を point getter というが, それと同じ単語である. ゲッターには, 慣習的に,get の後ろにフィールド名を付加した名前を付けることが多い. このスライドのプログラム例の場合,position というフィールドのゲッターは getposition と命名されている. セッターは, 値を書き込む ( セットする, 設定する ) ためのメソッドである. バレーボールでも, トスを上げてアタックする準備を設定する選手を setter という. セッターには, 慣習的に,set の後ろにフィールド名を付加した名前を付けることが多い. この例の場合, position というフィールドのセッターは setposition と命名されている. この例では, setposition の引数で与えられた整数をローカル変数 p で受け取り, セッターのプログラム本体で, それをフィールド position に代入している. ローカル変数 p は, メソッドの実行が終了したら消えてしまうような, 寿命が短い変数である. それに対して, フィールド position は, オブジェクトが存在している限り共に存在するような長い寿命を持っている. セッターを用いて, 暫定的なデータをフィールドに保存することによって, オブジェクトの状態が変更されることになる. コンストラクタは, すでに見たように, インスタンス生成時の初期設定を定義している. コンストラクタの名前はクラス名と同じでなければならない. オブジェクトを新規に生成して, コンストラクタを呼び出してフィールドを初期化するには, new コンストラクタ ( 引数,, 引数 ) という形式を用いる. 16

ゲッター, セッターを通してフィールドにアクセス メソッド getposition( ) Position setposition( p ) アクセス.setPosition(10) Robot( p ) この例では,Position の値を 10 にセットするために,setPosition というセッターを使用している. 17

クラス図 (API: Application Programmer's Interface) クラス名 フィールド メソッド Robot int position Robot(int p) int getposition() void setposition(int p) メンバ いつもクラスを定義した Java のソースコードを見るのは大変なので, 設計内容の概略をこのようなクラス図として図式化することが多い. 長方形を 3 段に分け, 最上段にはクラス名を, 中段にはフィールド名 ( とそのデータ型名 ) を, 最下段にはメソッド名 ( と引数及び戻り値のデータ型名 ) を記入する. このような情報は, クラスを利用して応用プログラムを作成しようとするプログラマーに対して, 利用法の インタフェース ( ソフトウェア部品の使い方 ) を提供しているので, API (Application Programmer's Interface) と呼ばれることがある. 18

ロボットのクラス図 ロボット int 位置 int 速度 int 燃料 ロボット (int p, int v, int f ) int どこ?( ) void 変速 (int 新速度 ) int ( ) コンストラクタ ゲッター セッター オペレータ ( 一般のメソッド ) これはこれまで作ってきた ロボット クラスのクラス図である. どこ? メソッドはゲッター, 変速 メソッドはセッターになっている. メソッドはゲッター, セッターのような基本的なメソッドではなく, このロボット特有の応用的なメソッドである. 19

特徴 2: 継承 ( インヘリタンス ) (inheritance) 1 カプセル化 2 継承 ( インヘリタンス ) 3 ポリモーフィズム ( 多相性 ) 20

親子 再利用可能ロボット 位置 速度 燃料 容量 どこ? 変速 補給 新( インヘリタンス ) データ継承 親を再利用して子を作る 使い捨てのロボット 位置 速度 燃料 どこ? 変速 親 スーパークラス サブクラス 子 新操作オブジェクト指向の特徴は, すでに作ったコードを再利用して機能拡張をしていく仕組みが整っていることである. それが継承 ( インヘリタンス ) という機能である. この例では, これまで作成した ( 使い捨ての ) ロボットを拡張して, 再利用可能なロボットを作ろうとしている. つまり, 燃料が切れたら, 燃料補給できる機能を追加する. 新しいフィールドとして, 燃料タンクの 容量 を追加する. 新しいメソッドとして, 補給 メソッドを追加する. このようなクラス間の関係を, 図のように, 親 / 子と呼んだり, スーパークラス / サブクラスと呼んだりする. ものつくり の観点から言えば, スーパークラス ( 親クラス ) は部品であり, ソフトウェア部品メーカーが供給することもある. それを目的に合わせてユーザ側のプログラマーがカスタマイズしたり機能拡張するなど, 有効に再利用して作るものがサブクラス ( 子クラス ) である. 21

新データ操作スーパークラスの指定新新コンストラクタサブクラスの定義 新属性, 新機能, 新コンストラクタのみ記述 class 再利用可能ロボット extends ロボット int 容量 ; void 補給 () { 燃料 = 容量 ; 再利用可能ロボット (int p, int v, int f, int c) { super(p, v, f); 容量 = c; スーパークラスを書き直したり再コンパイルする必要はない Java ではこの図のように extends 親クラス名 と書くことによって, 親クラスを再利用して子クラスを定義できる. この例では, すでに作成した ロボット クラスを親クラスとし, その子クラスとして 再利用可能ロボット クラスを定義している. 子クラスには, 新しく追加するフィールドやメソッドだけを記述する. すでに親クラスで定義してあるフィールドやメソッドは, 書かなくても, あたかも書いてあるかのように, 子クラスに引き継がれる. また, この子クラスをコンパイルする際には, スーパークラスを書き直したり, 再コンパイルする必要はない. さらに重要なのは, スーパークラスのソースコード ( ソースファイル ) は無くてよく, そのコンパイルされたコード ( クラスファイル ) さえあれば OK である. これは特にスーパークラスが商用で, 価格のある商品の場合に重要である. スーパークラスを作成したソフトウェアメーカーは, それを販売するにあたって, ふつうはソースコードを公開したくない. 公開すれば他社等に設計情報を知られるからである.Java の場合, スーパークラスを購入したユーザーは,API だけを知っていれば, ソースファイルがなくても, クラスファイルさえあれば, 購入したスーパークラスを部品として利用し, 子クラスを自分で定義できるのである. 22

継承のクラス図 ロボット int 位置 int 速度 int 燃料 スーパークラス int どこ?( ) void 変速 (int 速度 ) int ( ) 再利用可能ロボット int 容量 void 補給 ( ) クラス図を書くときには, 子クラスから親クラスに矢印を付けておく. 23

継承の使用例 public class 再利用可能ロボットのテスト public static void main(string args[]) { 再利用可能ロボット robo2 = new 再利用可能ロボット (0,1,10,10); for (int i=0; i<100; i=i+1) { if(robo2. ()< 0) { robo2. 補給 (); robo2. (); 継承されたメソッドの使用 ( ) は, 正常にたら 0, 燃料切れだったら -1 を返す. 新しいメソッドの使用 再利用可能ロボットを使ってみよう. この例では, 再利用可能ロボット robo2 を生成し, for ループを使って ボタンを 100 回連打する. ただし, 途中で燃料切れになったときは, メソッドは負のエラーコードを返すので, 燃料を補給して, ボタンを 1 回押し直している. 24

特徴 3: ポリモーフィズム ( 多相性 ) (polymorphism) 1 カプセル化 2 継承 ( インヘリタンス ) 3 ポリモーフィズム ( 多相性 ) 25

ポリモーフィズム ( 多相性 ) 同じメッセージでもクラスによって処理が異なる ロボットクラス. ( ) メッセージ船クラス 先生クラス. ( ) 授業をる. ( ) このスライドに図示してある 3 つのクラス ( ロボット, 船, 先生 ) に, いずれも メソッドがあるとしよう.3 つのメソッドの内容 ( プログラムコード ) は全く異なるものである. ロボットが 進む とは, 足を動かすプログラムコードを実行することだし, 船が 進む とは, スクリューを回転させるコードを実行することである. 先生が 進む とは, 脱線していた授業を進ませることである. したがって, 本来なら異なるメソッド名を付けるのがスジである. しかし, 人間にとって という言葉が適切なら, その言葉を共通に使えるようにした方が便利である. 言葉の数の節約になり, 人間にとって心理的に覚えやすい. プログラミングの世界でその考え方を採り入れたのが ポリモーフィズム という機能である.( このスライドでは 多相性 という和訳を採用したが, 多態性, 多様性 などと呼ばれるときもある. カタカナ書きでも, ポリモフィズム, ポリモルフィズム などの表記が使われることがある.) オブジェクト指向の言葉で述べると, 同じメッセージ ( メソッド ) でも, 受け手のオブジェクトのクラスによって, 処理 ( 意味 ) が異なる という機能である. ここで 同じメソッド と言っているのは, 一般には, メソッドの名前が同じであることに加えて, そのインタフェース ( すなわち, 引数の数と型, およびメソッドからの戻り値の型 ) までも同じであることを指している. 26

型の階層 ( 包含 ) るもの型 ロボット型船型先生型 ロボット クラスのオブジェクトは ロボット 型というデータ型である. 同様に, 船 クラスは 船 型, 先生 クラスは 先生 型である. これらのクラス ( データ型 ) は, 共通に という同一の名前をもつメソッドをもっている. そのような共通性を認識して, これらの複数のデータ型をまとめて,1 つのデータ型として総称的に定義することができる. このスライドの例ではそれを るもの という名前のデータ型としている. 27

るもの のインタフェース interface るもの { int (); 抽象メソッド Java でこの考え方を実現する方法の 1 つが, インタフェース という機能である. その書き方はクラスの書き方と似ているが,class のかわりに interface というキーワードを用いる点が異なる. 最も重要な違いは, メソッドの本体 ({ と で囲まれて記述されるプログラムコード ) を書くことが許されない点である. そのようなメソッドを抽象メソッドという. この Java コードの例は, るもの は, int (); というメソッドを共通に持っていることを宣言している. Java で良く使われるインタフェースとして,Runnable インタフェースというのがある. これは,run メソッドを持つクラスを総称するためのもので, 実際にはつぎのように定義されている. interface Runnable { void run( ); 28

るもの の実装 ここを追加する class ロボット implements るもの int 位置 ; int 速度 ; int 燃料 ; int どこ?() { return( 位置 ); void 変速 (int 新速度 ) { 速度 = 新速度 ; int () { if ( 燃料 > 0) { 位置 = 位置 + 速度 ; 燃料 = 燃料 - 1; return 0; else { return (-1); ロボット型が, るもの型に含まれることを,implements というキーワードを用いてこのスライドのように記述する. このような場合, ロボット クラスは るもの インタフェースを 実装している という.Java の約束によって, インタフェースを実装するクラスの中では, そのインタフェース内で記述された抽象メソッドの本体を具体的に記述する必要がある. この例の場合, るもの インタフェースには,int ( ) という抽象メソッドが記述されていたことを思い出そう. したがって, るもの インタフェースを実装する ロボット クラスの中で, int ( ) メソッドの本体が具体的に記述されている. 29

実装のクラス図 interface るもの int ( ) ロボット int 位置 int 速度 int 燃料 int どこ?( ) void 変速 (int 速度 ) int ( ) 実装 ロボットが るもの を実装していることを, 破線の矢印を使って, このようなクラス図で表す. 30

ポリモーフィズムの使用例いろいろな るもの を統一的に進ませる るもの [] A = new るもの [3]; A[0] = new ロボット (0,1,10); A[1] = new 船 (" 横浜 "); A[2] = new 先生 (" 数学 "," 舞黒素太 "); 配列0 1 2 ポリモーフィズムが便利と感じるようなプログラムの例を紹介しておこう. それは同じインタフェースが実装されたいろいろなクラスのオブジェクトを一次元配列に記憶しておき, それらに対して同じメッセージを送る ( 同じ名前のメソッドを実行する ) ことにより, 各オブジェクト特有の適切な動作を統一的なコーディングによって起こさせる例である. Java で整数 (int) の一次元配列を作るには, つぎの例のようにする. int [ ] a = new int[n]; または int a[ ] = new int[n]; これは,n 個の要素 a[0],a[1],...,a[n-1] をもつ int 型の配列を生成し,a という名前の変数に代入している例である.int 型以外の配列を作るときには, 型の名前を int でない適切なものに変えればよい. このスライドのプログラムでは, るもの 型のオブジェクトを 3 つまで記憶できる配列を用意して,A という名前の変数に代入している. プログラムの第 2~4 行目では,A の 3 つの要素に, それぞれ, ロボット, 船, 先生のインスタンスを記憶させている. そもそもポリモーフィズムがなければ, こういうことはできない. なぜなら, 配列というものは, 同じデータ型のデータを複数個記憶するためのデータ構造だからである. たとえば, 整数型や実数型や文字列型のデータを混在させて記憶することはできない. しかし, ポリモーフィズムがあればそれができる. この例では, ロボット, 船, 先生は異なるデータ型で, ふつうは同じ配列に混在させることはできないのだが, それらの 3 つのデータ型を包含する るもの 型の配列を導入することにより, すべてを記憶できるようになる. なぜなら, ロボットも船も先生も るもの 型という同じデータ型に属するからである. 31

ポリモーフィズムの使用例 ( 続き ) いろいろな るもの を統一的に進ませる るもの A[] = new るもの [3]; A[0] = new ロボット (0,1,10); A[1] = new 船 (" 横浜 "); A[2] = new 先生 (" 数学 "," 舞黒素太 "); for(i=0; i<3; i++) A[i]. (); 配列0 1 2 さて, つぎに進もう. ここが山場である. 前のコードに続いて, このスライドでは for 文が書かれている.for ループの中で,i を 0,1,2 というふうに変化させながら, ループの本体 A[i]. ( ); が 3 回実行されるのだが, そこでは という同じ名前のメソッドによって, 異なる意味と異なるメカニズムのもとで A[ i ] に記憶されているオブジェクトが 進む こととなる. すなわち, ループの第 1 周目 (i=0) ではロボットが足を動かしながら進み, 第 2 周目では船がスクリューを回転させて進み, 第 3 周目では先生が授業をるというバラエティに富んだ処理が行われる. 要するに, 全員に一斉に という指示を与えたときに, 各自がそれぞれの の意味に従って行動する様子が表現できているのである. このような処理を簡潔な 1 行で記述できるのは大変便利である. ポリモーフィズムがなければ, オブジェクトがどのクラスのインスタンスなのかの判別に instanceof という Java の機能を用いて,if 文を使って, for( i=0; i<3; i++) if (A[i] instanceof ロボット ) A[i]. ロボット ( ) else if (A[i] instanceof 船 ) A[i]. 船 ( ) else if (A[i] instanceof 先生 ) A[i]. 先生 ( ); のように, インスタンスのクラスが何であるかに応じて, ロボット, 船, 先生 という, 名前の異なるメソッドを実行させることになる. その程度のことはたいした面倒なことではないのだが, プログラムのバージョンアップのときに を実行できる第 4, 第 5 のクラスが導入されてくるとその違いが明確になる. ポリモーフィズムがあるときは, 第 4, 第 5 のクラスをこれまでのように定義すればそれで済み, このスライドの for ループのプログラムを書き直す必要はない. しかし,if 文を使うプログラムでは,if 文の条件判定を新クラス向けに追加しなければならないので, この for 文を書き直し, 再コンパイルする必要が生ずるのである. ましてや, メーカーがソースコードを公開していない場合, 末端のユーザー ( アプリケーションプログラマ ) には, このバージョンアップの作成は不可能になってしまう. このようなプログラミングテクニックは Java のプログラムコードでたくさん見かけるものなので, ぜひ覚えておこう. 良く知られているものは,Runnable インタフェースである.Java では, アニメーションを動かすと同時に,GUI のクリックも受け付ける などのように, 複数のプログラムを同時に動かすときには, スレッド (Thread) と呼ばれるオブジェクトを使う. その場合, プログラマは, 応用に合わせて, オブジェクトに void run( ) というメソッドを記述しておく必要がある. この run ( ) メソッドは Java が事前に用意している Runnable というインタフェースの中で記述された抽象メソッドである. プログラマは,Runnable インタフェースを実装するようなクラスを自分で定義し, その中で run ( ) メソッドの中身を具体的に記述できる. つまり, 先ほどの説明と比較すると, メソッドが run, るもの インタフェースが Runnable に対応している. 32

オブジェクト指向のまとめ 基本用語 オブジェクト, フィールド, メソッド, メンバ クラス, インスタンス ゲッター, セッター, コンストラクタ スーパークラス, サブクラス, クラス図 インタフェース, 抽象メソッド, 実装特徴 1 カプセル化 2 継承 ( インヘリタンス ) 3 ポリモーフィズム ( 多相性 ) このスライドでまとめた用語のおよそのイメージが, それぞれ数秒で想起されるように復習してね. 33

演習問題 9 オブジェクト指向プログラミングのもつ 3 つの大きな特徴について説明しなさい. 字数は全体で 400 字程度とする. 34