オブジェクト指向概論 第 2 講 クラスとカプセル化 立命館大学 情報理工学部 黄宏軒 1
オブジェクト指向の重要な概念 n クラス q 同じようなオブジェクトを まとめて 考える n 継承 ( インヘリタンス ) q 複数のクラスの 共通部分をまとめる n ポリモーフィズム ( 多態性 ) q 呼び出す側を 共通化 する n 複雑なものを簡単に 2
2.1 クラスとは何か n 類似のオブジェクトを まとめて 考える q 個々のオブジェクトが持つ共通の特性を表わす コンピューターの共通特性 CPU:Pentium/Athlon/ 入力装置 : キーボード, マウス, 出力装置 : 画面記憶デバイス :HDD,DVD... A さんのパソコン ( デスクトップ ) B さんのパソコン (WS) H さんのパソコン ( ノート ) 3
プログラムの世界のクラス n プログラムの世界では, クラスはオブジェクトのひな型 ( 原型 ) q q オブジェクトを作るための設計図 Java ではすべてのプログラムがクラスで記述される パソコン の設計図 CPU: 入力装置 : 出力装置 : 記憶デバイス : OS: 所有者 : ログインする A さんのパソコン オブジェクト CPU:Pentium 3.2G 入力装置 : キーホ ート, 出力装置 :17 インチ液晶記憶デバイス :512MB OS:Windows XP 所有者 :A さんログインする 4
クラスとインスタンス n クラスという設計図を元に作られたオブジェクトを インスタンス という パソコンクラス CPU: 入力装置 : 出力装置 : 記憶デバイス : OS: 所有者 : ログインする CPU:Pentium 3.2G 入力装置 : キーホ ート, 出力装置 :17 インチ液晶記憶デバイス :512MB OS:Windows XP 所有者 :A さんログインする CPU:Athlon 4G CPU:Pentium M 1.2G 入力装置 : キーホ ート, 出力装置 :12 インチ液晶記憶デバイス :1GB OS:Windows XP 所有者 :H さんログインする インスタンス (A さんのパソコン ) インスタンス (B さんのパソコン ) 入力装置 : キーホ ート, 出力装置 :19 インチ液晶記憶デバイス :2GB OS:Windows XP 所有者 :B さんログインする インスタンス (H さんのパソコン ) 5
Java で記述したテレビクラス // テレビクラス public class Television { クラス名 //**** 属性 ****// private String manufacturer; private String name; private int channel; private int volume; private int size; private int weight; //**** 振舞い ****// // チャンネル変更 public void chagechannel (int channel) { this.channel = channel; // ボリューム変更 public void changevolume (int volume) { this.volume = volume; 6
インスタンスを指定して実行 // Television クラスから 2 つのインスタンスを作る tv1 = new Television(); tv2 = new Television(); // インスタンスを指定してチャネルを変更 tv1.changechannel (10); // tv1のチャンネルを10に変更 tv2.changechanel (4); // tv2のチャンネルを4に変更 インスタンスを管理するための変数などを用意する必要はない 7
クラスの作成者と利用者 n クラスという設計図をいろいろな人が使えるのがオブジェクト指向のメリットの一つ クラスの作成 ( クラスの提供者 ) オブジェクトの作成 ( クラスの利用者 ) 8
2.2 OOP の実行の仕組み n コンパイラ方式 ソースコード Int b = 1; Int C = 2; If (b > c) { a = b + c; コンパイルリンク 機械語 010001 111010 100110 001110 実行 n インタプリタ方式 ソースコード Int b = 1; Int C = 2; If (b > c) { a = b + c; 解釈 インタプリタ 実行 9
Java の実行方式 ( 中間コード方式 ) ソースコード Int b = 1; Int C = 2; If (b > c) { a = b + c; コンパイル コンパイルリンク 中間コード (bytecode) Iconst_0 Istore_0 Iload_0 Iconst_1 解釈 インタプリタ (JVM) 実行 実行効率はほどほど どのマシン /OS でも動く 10
オブジェクトの実体 n 実行時にはメモリ空間にオブジェクトの実体が作られる テレビ メーカ名製品名大きさ重さチャンネルボリューム チャンネルを変えるボリュームを変える コンパイル テレビクラス ( 実行形式 ) テレビインスタンス 1 テレビインスタンス 2 メモリ空間 ( スタティック域 ) メモリ空間 ( ヒープ域 ) テレビクラス ( ソース ) テレビインスタンス 3 11
インスタンスの詳細 n クラスで定義されたプロパティの 型 によってメモリ領域が確保される メモリ領域 テレビ メーカ名製品名大きさ重さチャンネルボリューム チャンネルを変えるボリュームを変える テレビクラス テレビインスタンスメーカ名格納場所製品名格納場所大きさ格納場所重さ格納場所チャンネル格納場所ホ リューム格納場所チャンネルを変えるメソッド * ボリュームを変えるメソッド * * メソッドはスタティック域に確保される 12
オブジェクトの作成 n オブジェクトを作成するには, オブジェクト自身のメソッドを利用する n このメソッドを コンストラクタ という n コンストラクタの役割 q q q オブジェクトの作成 属性の初期化 オブジェクトの作成に関連する初期処理 n ファイルを開くなど 13
// テレビオブジェクトを利用するクラス Television t; // インスタンス変数 Television メーカ名製品名大きさ重さチャンネルボリューム 3 インスタンス // テレビオブジェクトの作成 t = new Television(); 1 コンストラクタ呼び出し テレビオブジェクト メーカ名格納場所製品名格納場所 メモリ領域 チャンネルを変えるボリュームを変える Television( ) channel = 0; volume = 0; テレビクラス 2 変数の初期化 大きさ格納場所重さ格納場所チャンネル (0に初期化) ホ リューム (0に初期化) チャンネルを変えるメソッドボリュームを変えるメソッドコンストラクタ 14
パラメータを使ったオブジェクトの作成 // テレビクラス public class Television { // テレビクラスのコンストラクタ public Television (int size, int weight) { volume = 0; channel = 0; this.size = size; this.weight = weight; 15
パラメータを使ったオブジェクトの作成 ( 続き ) // テレビオブジェクトを使うプログラム 14 インチ, 3kg のテレビ Television t1; Television t2; Television t3; // インスタンス変数 // インスタンス変数 // インスタンス変数 // 14 インチテレビオブジェクトの作成 t1 = new Television (14, 3 ); // 17 インチテレビオブジェクトの作成 t2 = new Television (17,5 ); // 20 インチテレビオブジェクトの作成 t3 = new Television (20, 8 ); 17 インチ, 5kg のテレビ 20 インチ, 8kg のテレビ 16
オブジェクトの破棄 n オブジェクトを破棄するメソッドをデストラクタという n 破棄しなければ, メモリリークが起きる n Java などでは, プログラムで使わなくなったオブジェクトを自動的に破棄する機能を持っている. この仕組みを ガーベジコレクション という 17
インスタンスを指定して実行 // Television クラスから 2 つのインスタンスを作る tv1 = new Television(); tv2 = new Television(); // インスタンスを指定してチャネルを変更 tv1.changechannel (10); // tv1のチャンネルを10に変更 tv2.changechanel (4); // tv2のチャンネルを4に変更 インスタンスを管理するための変数などを用意する必要はない 18
メソッドのオーバーロード n 機能は同じだが呼び出し方の異なるメソッドを ( 同じ名前で ) 複数作ることができる n 実行時に適切なメソッドが選択される. これをメソッドのオーバーロードという // 顧客クラス public class Customer { // パラメータ custno で顧客情報を検索 public void getcustomer (int custno) { // パラメータ custname で顧客情報を検索 public void getcustomer (String custnname) { 19
2.3 カプセル化とは何か n オブジェクトの操作に必要な部分だけを外から見えるようにして, それ以外の部分を隠す n 余計なものを見えないようにしてわかりやすくする n 利用の仕方を制限して単純化する. 不用意のデータ操作を防ぐ n プログラムを変更するときの影響を小さくする 20
カプセル化の概念 ハンドルを操作する タイヤの向きが変わる 中がどうなっているかわからない ( 知る必要は無い ) 21
カプセル化の概念 ( 続き ) n DVD ドライブの例 22
アクセス制御 n プログラムの世界では, オブジェクトの外から ( 利用する側から ) 利用できないよう隠すもの 隠蔽 利用できるように見せるもの 公開 n 隠蔽と公開を制御 ( アクセス制御 ) するために アクセス修飾子 がある q 隠蔽 :private( 同じクラスの中からだけ利用可 ) q 公開 :public( どのクラスからも利用可 ) q 制限 :protected( 同じパッケージなら利用可 ) 23
// テレビクラス public class Television { //**** 属性 ****// private String manufacturer; private String name; private int channel; private int volume; private int size; private int weight; //**** 振舞い ****// // チャンネル変更 public void changechannel (int channel) { this.channel = channel; // ボリューム変更 public void changevolume (int volume) { this.volume = volume; private 修飾子がついているので, オブジェクトの外からは認識できない public 修飾子がついているので, オブジェクトの利用側から認識, 利用できる 24
隠蔽と公開の基準は? n プロパティ 原則隠蔽 公開してしまうと, いつどこで参照されているかを特定するのは困難 n メソッド 原則公開 もともと外部から操作するためのもの. 呼び出し方 ( パラメータ ) を変更することはまれ 25
アクセサメソッド n 外部からプロパティにアクセスするためのメソッド n ゲッター : 属性を参照するためのメソッド get+ 属性名 n セッター : 属性を変更するためのメソッド set+ 属性名 26
アクセサメソッドの例 // テレビクラス public class Television { //**** 属性 ****// private String manufacturer; private String name; private int channel; //**** 振舞い ****// // メーカ名のアクセサメソッド ( 属性を参照 ) public String getmanufacturer ( ) { return manufacturer; // 製品名のアクセサメソッド ( 属性を参照 ) public String getname ( ) { return name; // チャンネルのアクセサメソッド ( 属性を変更 ) public void setchannel (int channel) throws Exception { if ( (channel > 0) && (channel < 13) ) this.channel = channel; 入力値のチェックなどを行うこともできる else throw new Exception ( 指定されたチャネルは無効です ); 27
複雑なアクセサメソッド // 顧客クラス public class Customer { private int custno; private String name; private String address; // 顧客番号 // 顧客名 // 住所 // 顧客番号のセッター ( 属性の変更 ) public void setcustno (int custno ) { this.custno = custno; // 顧客番号のセット1 顧客番号をセット // 顧客データベースの参照 getcustomerinfo (custno) ; // 顧客データベースの参照 private void getcustomerinfo (custno) { // 他のアクセサ public String getname ( ) { return name; public String getaddress ( ) { return address; 3 顧客情報をセットしておく 2 ついでに顧客 DB にアクセスして 顧客データベース 28
複雑なアクセサメソッド ( 続き ) // 顧客管理クラス public class CustomerManager { private Customer cust; private String name; private String address; // 顧客オブジェクトの作成 cust = new Customer ( ); // 顧客番号のセット cust.setcustno (100) ; // 顧客情報の参照 name = cust.getname() ; address = cust.getaddress() ; // 顧客オブジェクト // 顧客名 // 住所 顧客番号のセットと同時に顧客 DB へのアクセスが行われる 顧客情報を参照することができる 29
まとめ n 複数のオブジェクトが持つ共通の特性 ( 属性, 振舞い ) を取り出してまとめたものを クラス という n プログラムの世界では, クラスはオブジェクトのひな型 ( 原型 ) n クラスという設計図を元に作られたオブジェクトを インスタンス という n プログラムの実行時には, メモリ空間にオブジェクト ( インスタンス ) の実体が作られる n オブジェクトを作成するには, オブジェクト自身のメソッド ( コンストラクタ ) を利用する 30
まとめ ( 続き ) n 自動的に不要になったオブジェクトを破棄してくれる仕組みを ガーベジコレクション という n オブジェクトの操作に必要な部分だけを外から見えるようにして, それ以外の部分を隠すことを カプセル化 という n 隠蔽と公開を制御するにはアクセス制御子 (private と public と protected) を用いる n 属性 ( 原則隠蔽 ) にアクセスするには アクセサメソッド を用いる. アクセサメソッドでは初期化などの処理を行うこともできる 31