オブジェクト指向基礎学習Ⅱ 平成19年6月20日 森田 彦 学習内容 I. オブジェクト指向の考え方 II. オブジェクト指向の実装(Java言語の場合) III. JBuilderプログラミング総復習 Ⅰ.オブジェクト指向の考え方 オブジェクト指向の考えのエッセンスを学習し、それをプログ ラム開発に応用した場合にどのようなメリットがあるかを理 解する。 <内容> 1 オブジェクトとは何か? 2 オブジェクトの基本概念 3 オブジェクトの拡張 1.オブジェクトとは何か? オブジェクトの例 カプセル化(プロパティとメソッド) オブジェクト指向的考え オブジェクトの例 人、車、黒板、机などのモノのこと。 オブジェクト指向の世界での定義→(自身の)状 態に関する情報と、(自身に対する)操作を有す るモノ。 例) 車 状態:型式、色、排気量、マニュアルかATか、 等々。 操作:走る、停止する、等々。 (プロパティとメソッドの)カプセル化 オブジェクト→自身の状態を表すデータ+(自身 に対する)操作を有するモノ データと操作の(オブジェクトへの)カプセル化 1セットにするという意味 車オブジェクト 色 走る 停止する 排気量 データ ・・・ 操作 ・・・ プロパティ メソッド 補足 カプセル化の意味 関連のあるメソッドとプロパティを組み合わせて1セット にする。 そのオブジェクトの(メソッドの)使い方以外は、情報を見 せない→情報の隠蔽(データの保護という意味もある) 利用者は、オブジェクトの内部の詳細を知ることなく、オブ ジェクトに備わった機能(メソッド)を利用できる。 情報の隠蔽の積極的意味 オブジェクト指向的考え ある用途のためのオブジェクトがあれば・・・ そのオブジェクトのメソッドを操作することで、処理を実現 例) ゼミでコンパを企画する。 オブジェクト→コンパ係 メソッド→企画 オブジェクト指向的記述→コンパ係.企画 (ドット記法) (意味:コンパ係に企画を依頼する。→コンパ係オブジェクトに 企画せよというメッセージを送る。) プロパティとメソッドがカプセル化されたオブジェクト を用いれば、手続き型(指向)プログラミングよりも 効率が上がる!? 操作(メソッド)の詳細を知る必要がない。 2.オブジェクトの基本概念 長方形オブジェクト クラスとインスタンス メソッドの継承 スーパクラスとサブクラス 長方形オブジェクト 長方形:高さと幅をプロパティとして持っている。 (ここでは)面積を求めるメソッド(操作)考える。 長方形オブジェクト 長方形A 高さ:7 面積は? プロパティ(幅、高さ)の値によって、 様々なオブジェクトがある。 幅:10 幅と高さというプロパティは共通 高さ×幅 一まとめに定義した方が便利 クラスの概念の登場 クラスとインスタンス クラス→共通の性質を持ったものの集まり 長方形 高さ: 長方形クラス 幅: 抽象化 (プロパティとメソッドの定義を持つ) 面積は? 高さ×幅 長方形A 長方形B 高さ:7 幅:10 高さ:9 幅:5 長方形オブジェクト 実例 (インスタンス) ( 個々に異なるプロパティの 値(のみ)を持つ ) メソッドはクラスから引き継ぐ メソッドの継承 インスタンス(オブジェクト)がメッセージを受け 取った時→自分が属するクラスのメソッドを起動 する→メソッドの継承 長方形オブジェクト (インスタンス) 長方形クラス 長方形A メッセージ 面積は? 70 高さ:7 幅:10 面積は? 高さ×幅 長方形 高さ: 面積は? 高さ×幅 幅: スーパクラスとサブクラス(クラスの継 承) 長方形と正方形の関係 正方形は長方形の一部→「高さ=幅」が成り立 つ特別な長方形 長方形:広い範囲のインスタンスをカバーするク ラス→スーパクラス 正方形:スーパクラスの一部のインスタンスのみ をカバーするクラス→サブクラス サブクラスを利用した正方形の定義 長方形 高さ: 幅: 面積は? 高さ×幅 長方形クラス スーパクラス 継承 OMT(Object Modeling Technique)の記法 正方形 高さ=幅 正方形A 幅:10 正方形クラス サブクラス 正方形オブジェクト (インスタンス) クラスの階層図(図形クラスの例) 図形 四角形 長方形 正方形 三角形 台形 スーパクラスとサブクラスと いう概念は相対的なもの サブクラス(下位のクラス)はスーパクラス(上 位のクラス)の性質を全て引き継ぐ。 + 新たなプロパティあるいはメソッドを持つ。 3.オブジェクトの拡張性 単純なクラスに機能を付加→複雑なクラスを定 義可能 既存のクラスに機能を付加→目的に応じたクラ スを容易に定義できる ソフトウェアの生産性向上 オブジェクト指向プログラミングはソフトウェア危機の 救世主!? 三角形クラスの定義 (多態性) 長方形.面積は? 図形 高さ: 長方形 面積は? 高さ×幅 三角形.面積は? 幅: 三角形 面積は? 高さ×幅/2 長方形クラスと三角形クラス、それぞれ に異なる「面積は?」メソッドを定義 同じ「面積は?」メッセージを受 け取っても、長方形と三角形オ ブジェクト(インスタンス)では、 振る舞いが違う。 ポリモフィズム (polymorphism:多態性) プログラムの拡張が 容易に! デフォルトメソッドと上書き (定義の改良) 図形 高さ: デフォルトメソッド 幅: 多くの(しかし全てではない)イン スタンスに適用できるメソッド 面積は? 高さ×幅 メソッドの上書き 長方形 三角形 面積は? 高さ×幅/2 <三角形クラスの異なる定義> サブクラスでメソッドを定義し 直すこと プログラムの拡張が効率的に! スーパ疑似変数と差分プログラム 「高さ×幅」の重複をなくす。 図形 高さ: 幅: super:スーパ擬似変数 面積は? 高さ×幅 一つ上のクラスを表す。 拡張時にプログラムの重複 を排除する上で有効 長方形 三角形 面積は? super.面積は?/2 スーパクラスに何かを追加することでサブクラスのメソッドを定義する。 継承を利用した差分プログラム プログラムの拡張が効率的に! 再利用性の向上! 理解度チェック 以下の設問に答えて下さい。 1. クラスとインスタンスの実例を挙げて下さい。 2. プログラムの再利用性を高める差分プログラムを 可能にするのは、オブジェクト指向のどのような機 能ですか? クラスとインスタンス -プログラミング の場合 クラス→ 型に対応 インスタンス(オブジェクト)→ 変数に対応 <通常の変数の場合> int a,b ; double x,y; <オブジェクト(インスタンス)の場合> コンストラクタ JButton jButton1 = new JButton(); JButtonクラス JButtonクラスのインスタンス Ⅱ.オブジェクト指向の実装(Java言語の場合) オブジェクト指向の機能が、Java言語でどのように実装(実 現)されているのかを理解(確認)する。 <内容> 1. 2. 3. 4. フレームクラスの定義 人間クラスの定義 インスタンス(オブジェクト)の生成・利用 Java言語のメリット・デメリット 1.フレームクラスの定義(復習) <空っぽのフレームの場合> <Frame1クラスの定義> プロパティの定義 ・・・ コンストラクタの定義 } } ・・・ メソッドの定義 フレームの生成 <Application1.javaファイル> フレームを生成する役割 frameの生成 Frame1クラスのイ ンスタンス インスタンスの生成(Java言語) コンストラクタ クラス名 Frame1 frame = new Frame1(); インスタンス名 クラスがあれば、インスタンス(オブジェクト)の生成 は容易! JBuilderによるJavaアプリケーションの構成 (補足) パッケージ(samplejava) <クラス> Frame1.java フレームクラスの定義 <クラス> Application1.java フレームを生成 役割分担の明確化! オブジェクト指向プログ ラミングの特徴 2.人間クラスの定義 サンプルプログラム 人間 動け:左右に動く 話せ:あいさつ 日本人 話せ:こんにちは アメリカ人 話せ:Hello イタリア人 話せ:Buon Giorno ① プログラム起動時 ② 日本人を選択し[登場]ボタン をクリック ⑤ [退場]ボタンをクリック ③ [→]ボタンをクリックし、右へ移動 ④ [話す]ボタンをクリック プログラムの構成 パッケージ humanmain クラスApplication1: フレームの生成 クラスFrame1: フレームの定義 クラスhuman: 人間クラスの定義 人間クラスの定義 ボタンクラス(JButton) をスーパークラスに Moveメソッドの定義 Speakメソッドの定義 サブクラスを指す 人間クラスの定義(詳細) class Human extends JButton { public void Move(int Dist) { Rectangle Rect; Rect=this.getBounds(); 現在位置を取得 Rect.x=Rect.x+Dist; 水平位置をずらす this.setBounds(Rect); ずらした位置に表示(移動) } thisはHumanクラスを public void Speak() { 指す。 this.setText("あいさつ"); } } 日本人クラスの定義(継承) Humanクラス定義部の下に以下を追加 Humanクラスを継承 class Japanese extends Human { public void Speak() { this.setText("こんにちは"); } } メソッドの上書き Americanクラス、Italianクラスの定義も同様 3.インスタンスの生成・利用 ① インスタンス(オブジェクト)名の宣言(Frame1クラス内) public class Frame1 extends JFrame { private Japanese Taro; private American John; private Italian Mario; ・・・ ② コンストラクタによるインスタンス生成 Taro= new Japanese(); アメリカ人およびイタリア人オブジェクト(インスタンス)の 生成も同様 「登場」ボタン void jButtonCreate_actionPerformed(ActionEvent e) { if(jRadioButtonJapan.isSelected()) { Taro=new Japanese(); 日本人インスタンス(Taro)を生成 contentPane.add(Taro); Taro.setBounds(new x , y , w , h ボタンの大きさを設定 Rectangle(110,10,110,30)); Taro.setBackground(Color.white); 白色に設定 Taro.setText(“Taro"); Taroと表示 } else if(jRadioButtonAmerica.isSelected()) { ・・・ アメリカ人インスタンス(John)の処理 } else if(jRadioButtonItaly.isSelected()) { ・・・ イタリア人インスタンス(Mario)の処理 } } 移動「→」ボタン void jButtonMoveRight_actionPerformed(ActionEvent e) { if(jRadioButtonJapan.isSelected()) { Taro.Move(5); 5歩右へ移動 } else if(jRadioButtonAmerica.isSelected()) { John.Move(5); } else if(jRadioButtonItaly.isSelected()) { Mario.Move(5); } } 「話す」ボタン void jButtonSpeak_actionPerformed(ActionEvent e) { if(jRadioButtonJapan.isSelected()) { Taro.Speak(); } else if(jRadioButtonAmerica.isSelected()) { John.Speak(); } else if(jRadioButtonItaly.isSelected()) { Mario.Speak(); } } 多態性の実現 多態性のメリット(この例の場合) 日本人、アメリカ人そしてイタリア人それぞれにとって、 “あいさつをする”という概念は共通。 ただ、個別的なあいさつの言葉が異なるだけ。 そこで、それら、個別の違いを気にせず、全て、Speak() というメソッドで(あいさつの表示を)実現できたら、プロ グラムの見通しが良く(読みやすく)、拡張も容易(ドイツ 人、スペイン人クラスのインスタンスに対しても同様にプ ログラムできる)。 この様に、概念上同様の処理を、共通のメソッド名で表 現し、処理内容の詳細がオブジェクト(インスタンス)に 応じて異なっている様を多態性という。 「退場」ボタン void jButtonDelete_actionPerformed(ActionEvent e) { if(jRadioButtonJapan.isSelected()) { Taro.setVisible(false); } else if(jRadioButtonAmerica.isSelected()) { John.setVisible(false); } else if(jRadioButtonItaly.isSelected()) { Mario.setVisible(false); } } サンプルプログラム 4.Java言語のメリット・デメリット (オブジェクト指向の観点から) メリット デメリット オブジェクト指向プログラミ オブジェクト指向の独特の記 ングの記述が容易にできる。 述が初心者には理解困難。 豊富なクラスライブラリが存 クラスライブラリの全体像を把 在する。→色々な用途のア 握する事が困難。 プリケーション開発が可能に。 課題 1. 解説で採りあげた、Java言語による人間クラスの プログラムを実際に作成して下さい。 補足) オブジェクト指向の難しさ ’90年代初頭の技術者は皆頭を悩ませた。 オブジェクト指向の機能は便利。しかし、その活用方法 のノウハウは当初は手探りだった・・・。 プログラマによってクラスの設計や継承の仕方(考え 方)が異なるので、共有しにくい。 行き当たりばったりの継承が流行→スパゲッティ継承!? 現在は開発手法が整備されてきた。→クラスの設計や 継承に関するルールが共有されるようになった。 きちんと教育を受ければ一定のレベルに到達するように なった。 Ⅲ.JBuilderプログラミング総復習 JBuilderを用いて行ってきたフレームの生成やイベント処 理などを、(JBuilderに頼らず)最初から記述してみる。 その過程を通じてJBuilderの機能のメリットを理解する。 <内容> 1. 2. 3. 4. 5. 6. mainクラスの定義 フレームの生成 mainクラスとフレームクラスの役割分担 ボタンとテキストフィールドの貼り付け イベント処理の実装① イベント処理の実装② 1.mainクラスの定義 class FrameApplication { コンストラクタ public FrameApplication() { 省略可 } public static void main(String[] args) { System.out.println("実行成功!"); } } mainメソッドの定義:一つの処理に対し必ず一つ定義する。 FrameApplication.javaとして保存 以下、作成したファイルやフォルダが、javac.exeやjava.exeなどのJava翻 訳システムがあるフォルダにあるものとして話を進める。 mainクラスの翻訳・実行 ① バイトコードへの変換(翻訳) ② バイトコードの実行 実行結果! 2.フレームの生成 import javax.swing.*; フレームクラスはjavax.swing パッケージにある class FrameApplication { public static void main(String[] args) { JFrame frame=new JFrame(); フレームオブジェクトの生成 w h フレームの幅wと高さhを設定 frame.setSize(300,200); } } frame.setTitle("自作のフレーム"); x y frame.setLocation(100,50); 表示位置(x,y)の設定 frame.setVisible(true); フレームを表示させる フレームの生成→実行 50 100 200 300 ※ ×をクリックしても、ウィンドウは閉じるがプログラムの実行は終了しない。 プログラムの終了処理を記述しなければならない。 3.mainクラスとフレームクラスの役割分担 <準備> 1. 適当なフォルダ、例えばframesampleというフォルダを作る。 2. その中にFrameApplication.javaを移動する。 3. 同フォルダ内に、フレームを定義するFrame1.javaを作る。 framesample パッケージ FrameApplication.java Frame1.java フレームを生成・表示 フレームを定義 ここで新たに定義 Frame1.java package framesample; import javax.swing.*; import java.awt.event.*; パッケージの指定 ウィンドウ(フレーム)の終了処理 のために必要 class Frame1 extends JFrame { public Frame1() { ・・・ } JFrameを継承 コンストラクタ フレームの初期処理 //ウィンドウが閉じられたときに終了するようにオーバーライド protected void processWindowEvent(WindowEvent e) { ・・・ } } FrameApplication.java package framesample; class FrameApplication { public static void main(String[] args) { Frame1 frame=new Frame1(); フレームオブジェクト frame.setLocation(100,50); の生成 frame.setVisible(true); } } 役割分担の徹底 これで、FrameApplication.javaは(フレーム設計を変えても) いじる(変更する)必要がなくなる。 JBuilderで皆が意識しなかった理由 4.ボタンとテキストフィールドの貼り付け <Frame1.java> class Frame1 extends JFrame { private JPanel contentPane; private JTextField TField1 = new JTextField(); private JButton Btn1= new JButton(); public Frame1() { contentPane = (JPanel) this.getContentPane(); contentPane.setLayout(null); TField1.setBounds(20,10,200,25); テキストフィールドの 貼り付け contentPane.add(TField1); Btn1.setBounds(20,60,120,25); Btn1.setText("自作ボタン"); ボタンの貼り付け contentPane.add(Btn1); this.setSize(300,200); this.setTitle("自作のフレーム"); } 5.イベント処理の実装① ボタンをクリックした時に、テキストフィールドに「イベント処理 成功!」という文字を表示させるには・・・ 以下の部分を加える。 イベントリスナの登録 public Frame1() { ・・・ this.setTitle("自作のフレーム"); リスナインタフェース Btn1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { TField1.setText("イベント処理成功!"); } }); } メソッドの上書き(定義) 6.イベント処理の実装② public Frame1() { ・・・ this.setTitle("自作のフレーム"); Btn1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Btn1_actionperformed(); TField1.setText("イベント処理成功!"); } }); } メソッドに置き換える public void Btn1_actionperformed() { TField1.setText("イベント処理成功!"); } 皆がいつも記述していた部分 JBuilderを用いると・・・ パッケージ Application1.java プログラマは・・・ Frame1.java Frame1.javaに於いて フレームの設計(ボタンやテキストフィールドなどの 貼り付け等)とイベント処理プログラム(ボタンクリッ ク時のプログラム等)の記述に専念できる。 フレームを生成するApplication1.javaというプログ ラムはいじる(変更する)必要がない。 クラス間の役割分担の徹底により、効率よくプログラ ムを作成できる様になっている。 課題 1. 本日は、オブジェクト指向の基礎概念とJava言語 におけるオブジェクトプログラミングを学習しました。 この学習内容の感想を、良く理解できた点と理解 が困難だった点を含めて述べて下さい。 Java言語におけるクラスの定義 class クラス名 { プロパティ(フィールド)の定義 コンストラクタの定義(初期化処理) メソッドの定義 } クラスの継承 サブクラス スーパークラス public class Frame1 extends JFrame { プロパティの定義 コンストラクタの定義 メソッドの定義 } 全クラスから参照可能 コンポーネントはオブジェクト 復習)デフォルトメソッドと上書き (定義の改良) 図形 高さ: デフォルトメソッド 幅: 多くの(しかし全てではない)イン スタンスに適用できるメソッド 面積は? 高さ×幅 メソッドの上書き 長方形 三角形 面積は? 高さ×幅/2 <三角形クラスの異なる定義> サブクラスでメソッドを定義し 直すこと プログラムの拡張が効率的に! 人間クラスの継承図 スーパークラス 人間 Move:左右に動く Speak:あいさつ サブクラス 日本人 Speak:こんにちは Taro アメリカ人 Speak:Hello John インスタンス イタリア人 Speak:Buon Giorno Mario 復習) 多態性(図形クラスの定義より) 長方形.面積は? 図形 高さ: 長方形 面積は? 高さ×幅 三角形.面積は? 幅: 三角形 面積は? 高さ×幅/2 同じ「面積は?」メッセージを受 け取っても、長方形と三角形オ ブジェクト(インスタンス)では、 振る舞いが違う。 ポリモフィズム 長方形クラスと三角形クラス、それぞれ (polymorphism:多態性) に異なる「面積は?」メソッドを定義 プログラムの拡張が 容易に! 参考:言語の制約の度合い print “Hello!” BASIC 行が基本 main( ) { printf(“Hello!\n"); C } 関数が基本 制約大 public class Hello { public static void main(String args[ ]) { System.out.println(“Hello!”); } } Java クラスが基本 一般に・・・ 一般に、オブジェクト指向言語は最も記述に手 間がかかる。 ただ、プログラムの再利用性と見通しの良さは 最も良い。 オブジェクト指向言語が威力を発揮するのは、大き なプログラムを共同で開発する時。 コンストラクタの記述 class Frame1 extends JFrame { public Frame1() { this.setSize(300,200); this.setTitle("自作のフレーム"); } ・・・ } これにより、フレームが生成されるときに、その大きさとフ レームタイトルが設定される。 コンストラクタはインスタンス(オブジェクト)が生成さ れる時に呼び出される特別なメソッド フレームの終了処理 //ウィンドウが閉じられたときに終了するようにオーバーライド protected void processWindowEvent(WindowEvent e) { if (e.getID() == WindowEvent.WINDOW_CLOSING) { System.exit(0); } ×を選択した場合 } プログラムを終了させる。 メソッドの上書き→終了処理を加える。
© Copyright 2024 ExpyDoc