プログラミング言語論
第十二回
理工学部
情報システム工学科
新田直也
多態性(最も単純な例)
class A {
void m() { System.out.println(“this is class A”); }
}
class A1 extends A {
void m() { System.out.println(“this is class A1”); }
}
class A2 extends A {
void m() { System.out.println(“this is class A2”); }
}
class Test {
派生
main () {
A a = new A1();
A1
a.m();
// “this is class A1”と表示
a = new A2();
a.m();
// “this is class A2”と表示
}
}
A
派生
A2
多態性の考え方

メッセージを送る人は送り先の具体的なクラス
(具象クラス)を知らなくてもよい.

実際に呼ぶメソッドは実行時に決まる(遅延束縛).
Aa
Test
m()
m()
Aa
Aa
A
A1
A2
多態性の使い方1

異なる種類のオブジェクトに一括して処理を行う場合
クラス
選択
移動
図形
三角
四角
円
→図形はすべて移動することができる.
→移動の処理は図形ごとに異なる.
→実行時までどのクラスのオブジェクトが選択されるか不明.
多態性の使い方2

クラス定義:
class Shape {
void move(int x, int y) {
:
}
}
// 図形クラス
// 移動メソッド
class Trianle extends Shape {
void move(int x, int y) {
:
}
}
// 三角形クラス
// 移動メソッドをオーバーライド
class Rectangle extends Shape {
void move(int x, int y) {
:
// 四角形クラス
// 移動メソッドをオーバーライド
多態性の使い方3

選択図形の移動:
// 選択図形の配列を取得(図形の具象クラスは不明)
Shape [] sel_obj = GetSelectedObjects();
// 配列中の各要素を移動する
Shape クラス for (int n = 0; n < sel_obj.length; n++) {
sel_obj[n].move(x, y);
の参照変数の
}
配列
Shape sel_obj[n]
多態性により Shape
クラスまたは子クラス
のmoveメソッドが呼
ばれる
多態性を用いた図形の描画

クラス定義:
class Shape {
void view(Graphics g) {
:
}
}
class Trianle extends Shape {
void view(Graphics g) {
:
}
}
class Rectangle extends Shape {
void view(Graphics g) {
:
}
}
// 図形クラス
// 表示メソッド
// 三角形クラス
// 表示メソッドをオーバーライド
// 四角形クラス
// 表示メソッドをオーバーライド
図形の一括描画

多態性を用いると,図形の種類に関係なく描画できる.
class GraphicWindow extends Frame {
// Windowのクラス
:
void paint(Graphics g) {
// Windowを描画する度に呼ばれる
Shape[] objList = new Shape[3];
objList[0] = new Circle(120,120,50);
objList[1] = new Triangle(20,100,50,50,80,100);
objList[2] = new Rectangle(200,50,250,100);
}
for (int i = 0; i < objList.length; i++) {
objList[i].view(g);
}
配列のサイズを取得できる
}
多態性により実際のクラスの view() が呼ばれる
多態性を使うメリット

もし多態性がなければ…
for (int i = 0; i < objList.length; i++) {
switch (objList[i].type()) {
case CIRCLE:
CircleView(objList[i], g);
break;
case TRIANGLE:
TriangleView(objList[i], g);
break;
case RECTANGLE:
RectangleView(objList[i], g);
break;
新しい図形が増える毎に
}
caseを追加する必要
}
抽象クラス,抽象メソッド


抽象メソッド:
実体を持たないメソッド.abstract 修飾子を付ける.
メソッドの実装は派生クラスに任せる.
抽象クラス:
抽象メソッドを1つ以上持つクラス.抽象クラスはインスタンス化
できない.(継承しなければ使えない.)
abstract class Shape {
// 抽象図形クラス
abstract void view(Graphics g); // 抽象表示メソッド
}
→ Shape クラスはインスタンス化できない.
アクセスレベル


各メソッドやメンバ変数に対して外部からのアクセスを
許可/不許可できる.
アクセス修飾子:




public: 無制限に公開.
protected: ほぼ無制限に公開.
private: 同じクラス内からしかアクセスできない.
使用法:

基本的にメソッドは,publicで宣言する.
public void view(Graphic g) {…

基本的にメンバ変数は,privateで宣言する.
private int x;

基本的にメンバ変数へのアクセスはメソッドを通じて間接的に行う.
public void setX(int px) { x = px; }
public int getX() { return x; }
クラス変数,クラスメソッド

クラス変数:
クラスが持つ変数.全インスタンスで値を共有できる.

クラスメソッド:

インスタンスを指定せずに呼び出せるメソッド.内部ではクラ
ス変数にしかアクセスできない.
使用例:
class A {
static int MAX_NUM = 1000;
static int getMaxNum() {
return MAX_NUM;
}
n = A.getMaxNum();
修飾子のまとめ

よりオブジェクト指向らしいプログラムのために…

修飾子:

抽象メソッド,抽象クラス
abstract

アクセスレベル
public,protected,private

クラス変数,クラスメソッド
static
ダウンロード

プログラミング言語論12