クラスとカプセル化

オブジェクト指向概論
第2講
クラスとカプセル化
立命館大学
情報理工学部
黄 宏軒
1
オブジェクト指向の重要な概念
n 
クラス
q 
n 
継承(インヘリタンス)
q 
n 
複数のクラスの「共通部分をまとめる」
ポリモーフィズム(多態性)
q 
n 
同じようなオブジェクトを「まとめて」考える
呼び出す側を「共通化」する
複雑なものを簡単に
2
2.1 クラスとは何か
n 
類似のオブジェクトを「まとめて」考える
q 
個々のオブジェクトが持つ共通の特性を表わす
パソコンの共通特性
CPU:Pentium/Athlon/…
入力装置:キーボード,マウス,
出力装置:画面
記憶デバイス:HDD,DVD
...
Bさんのパソコン
Aさんのパソコン
Hさんのパソコン
3
プログラムの世界のクラス
n 
プログラムの世界では,クラスはオブジェクトの
ひな型(原型)
q 
q 
オブジェクトを作るための設計図
Javaではすべてのプログラムがクラスで記述される
「パソコン」の設計図
CPU:
入力装置:
出力装置:
記憶デバイス:
OS:
所有者:
ログインする
・・・
「Aさんのパソコン」オブジェクト
CPU:Pentium 3.2G
入力装置:キーボード,…
出力装置:17インチ液晶
記憶デバイス:512MB
OS:Windows XP
所有者:Aさん
ログインする
・・・
4
クラスとインスタンス
クラスという設計図を元に作られたオブジェクトを
インスタンス
CPU:Pentium 3.2G
「インスタンス」という
入力装置:キーボード,… (Aさんのパソコン)
n 
パソコンクラス
CPU:
入力装置:
出力装置:
記憶デバイス:
OS:
所有者:
ログインする
・・・
出力装置:17インチ液晶
記憶デバイス:512MB
OS:Windows XP
所有者:Aさん
ログインする
・・・
CPU:Pentium M 1.2G
入力装置:キーボード,…
出力装置:12インチ液晶
記憶デバイス:1GB
OS:Windows XP
所有者:Hさん
ログインする
・・・
インスタンス
(Bさんのパソコン)
CPU:Athlon 4G
入力装置:キーボード,…
出力装置:19インチ液晶
記憶デバイス:2GB
OS:Windows XP
所有者:Bさん
ログインする
・・・
インスタンス
(Hさんのパソコン)
5
Javaで記述したテレビクラス
// テレビクラス
クラス名
public class Television {
//**** 属性 ****//
private String maker;
private String name;
private int channel;
private int volume;
private int size;
private int weight;
//**** 振舞い ****//
// チャンネル変更
public void channelChange (int channel) {
this.channel = channel;
}
// ボリューム変更
public void volumeChange (int volume) {
this.volume = volume;
}
…
}
6
インスタンスを指定して実行
// Televisionクラスから2つのインスタンスを作る
tv1 = new Television();
tv2 = new Television();
// インスタンスを指定してチャネルを変更
tv1.channelChange(10); // tv1のチャンネルを10に変更
tv2.chanelChange(4); // tv2のチャンネルを4に変更 ⇒インスタンスを管理するための変数などを用意する必要はない
7
クラスの作成者と利用者
n 
クラスという設計図をいろいろな人が使えるのが
オブジェクト指向のメリットの一つ
クラスの作成
(クラスの提供者)
オブジェクトの作成
(クラスの利用者)
8
2.2 OOPの実行の仕組み
n 
コンパイラ方式
ソースコード
Int b = 1;
Int C = 2;
If (b > c) {
a = b + c;
}
n 
機械語
コンパイル
リンク
010001
111010
100110
001110
実行
インタプリタ方式
ソースコード
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; //インスタンス変数
③インスタンス // テレビオブジェクトの作成
t = new Television();
Television
メーカ名
①コンストラクタ呼び出し
製品名
メモリ領域
大きさ
重さ
テレビオブジェクト
チャンネル
ボリューム
メーカ名格納場所 製品名格納場所
大きさ格納場所
重さ格納場所
チャンネルを変える
ボリュームを変える
チャンネル(0に初期化)ボリューム(0に初期化)
Television( )
チャンネルを変えるメソッド
channel = 0; volume = 0;
②変数の
ボリュームを変えるメソッド
初期化
コンストラクタ
テレビクラス
14
パラメータを使ったオブジェクトの作成
// テレビクラス
public class Television {
・・・
// テレビクラスのコンストラクタ
public Television (int size, int weight) {
volume = 0;
channel = 0;
・・・
this.size = size;
this.weight = weight;
}
・・・
}
15
パラメータを使ったオブジェクトの作成
(続き)
// テレビオブジェクトを使うプログラム
Television t1; // インスタンス変数
Television t2; // インスタンス変数
Television t3; // インスタンス変数
// 14インチテレビオブジェクトの作成
t1 = new Television (14, 3 );
// 17インチテレビオブジェクトの作成
t2 = new Television (17,5 );
// 20インチテレビオブジェクトの作成
t3 = new Television (20, 8 );
14インチ,
3kgの
テレビ
17インチ,
5kgの
テレビ
20インチ,
8kgの
テレビ
16
オブジェクトの破棄
オブジェクトを破棄するメソッドをデストラクタ
という
n  破棄しなければ,メモリリークが起きる
n  Javaなどでは,プログラムで使わなくなった
オブジェクトを自動的に破棄する機能を持っ
ている.この仕組みを「ガーベジコレクション」
という
n 
17
インスタンスを指定して実行
// Televisionクラスから2つのインスタンスを作る
tv1 = new Television();
tv2 = new Television();
// インスタンスを指定してチャネルを変更
tv1.channelChange(10); // tv1のチャンネルを10に変更
tv2.chanelChange(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  隠蔽と公開を制御(アクセス制御)するために
「アクセス修飾子」がある
q  隠蔽:private(同じクラスの中からだけ利用可)
q  公開:public(どのクラスからも利用可)
q  制限:protected(同じパッケージなら利用可)
n 
23
// テレビクラス
public class Television {
//**** 属性 ****//
private String maker;
private String name;
private int channel;
private int volume;
private int size;
private int weight;
//**** 振舞い ****//
// チャンネル変更
public void channelChange (int channel) {
this.channel = channel;
}
// ボリューム変更
public void volumeChange (int volume) {
this.volume = volume;
}
…
}
private修飾子が
ついているので,
オブジェクトの外か
らは認識できない
public修飾子がつ
いているので,
オブジェクトの利用
側から認識,利用
できる
24
隠蔽と公開の基準は?
n 
プロパティ
⇒原則隠蔽
公開してしまうと,どこで参照されているかを
特定するのは困難
n 
メソッド ⇒原則公開
もともと外部から操作するためのもの.呼び出し方
(パラメータ)を変更することはまれ
25
アクセサメソッド
n 
外部からプロパティにアクセスするための
メソッド
ゲッター:属性を参照するためのメソッド
get+属性名
n  セッター:属性を変更するためのメソッド
set+属性名
n 
26
アクセサメソッドの例
// テレビクラス
public class Television {
//**** 属性 ****//
private String maker;
入力値のチェックなどを
private String name;
行うこともできる
private int channel;
//**** 振舞い ****//
// メーカ名のアクセサメソッド(属性を参照)
public String getMaker ( ) { return maker; }
// 製品名のアクセサメソッド(属性を参照)
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; // 顧客番号のセット①顧客番号をセット
// 顧客データベースの参照
顧客
getCustomerInfo (custNo) ;
データベース
}
②ついでに
// 顧客データベースの参照
顧客DBに
private void getCustomerInfo (custNo) {
アクセスして
・・・
}
// 他のアクセサ
public String getName ( ) { return name; }
public String getAddress ( ) { return address; }
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
第2講のまとめ
n 
n 
n 
n 
n 
複数のオブジェクトが持つ共通の特性(属性,
振舞い)を取り出してまとめたものを「クラス」という
プログラムの世界では,クラスはオブジェクトの
ひな型(原型)
クラスという設計図を元に作られたオブジェクトを
「インスタンス」という
プログラムの実行時には,メモリ空間にオブジェクト
(インスタンス)の実体が作られる
オブジェクトを作成するには,オブジェクト自身の
メソッド(コンストラクタ)を利用する
30
第2講のまとめ(続き)
n 
n 
n 
n 
自動的に不要になったオブジェクトを破棄してくれる
仕組みを「ガーベジコレクション」という
オブジェクトの操作に必要な部分だけを外から
見えるようにして,それ以外の部分を隠すことを
「カプセル化」という
隠蔽と公開を制御するにはアクセス制御子(private
とpublicとprotected)を用いる
属性(原則隠蔽)にアクセスするには「アクセサ
メソッド」を用いる.アクセサメソッドでは初期化など
の処理を行うこともできる
31