オブジェクト指向言語論7

オブジェクト指向言語論
第七回
知能情報学部
新田直也
継承

継承:
基本となるクラスを拡張して,新しいクラスを定義すること.

親クラス:
元となるクラス.スーパークラスとも言う.

子クラス:
親クラスを拡張したクラス.拡張した部分だけ定義する.
基底クラス
クラスA
派生
クラスC
派生
クラスB
派生
クラスD
Javaによるオブジェクト指向
(継承)

extends キーワードを使って継承する.


拡張するインスタンス変数,メソッドのみ定義する.
例:
class Vector3D extends Vector {
拡張するメンバ変数
double z;
Vector add(Vector a) {
x += a.x; y += a.y; z += a.z;
置き換える
return this;
メソッド
}
double inner_product(Vector a) {
拡張する
return x * a.x + y * a.y + z * a.z;
メソッド
}
Vector3D outer_product(Vector3D a) {
return new Vector3D(y*a.z - z*a.y, z*a.x - x*a.z,
x*a.y - y*a.x);
}
}
Javaによるオブジェクト指向
(オーバーライド)

オーバーライド: 継承によるメソッドの置き換え.

Vector3Dでは,addと inner_productをオーバーライド
している.
double x;
double y;
Vector
Vector add(Vector a);
double inner_product(Vector a);
double length();
Vector3D
double z;
Vector add(Vector a);
double inner_product(Vector a);
Vector3D outer_product(Vector3D a);
Javaによるオブジェクト指向
(継承とメソッド呼出し)

メソッド呼出しの例:
class Test {
public static void main(String args[]) {
Vector a = new Vector(5, 10);
Vector b = new Vector(15, 20);
Vector3D c = new Vector3D(5, 10, 15);
Vector3D d = new Vector3D(20, 25, 30);
System.out.println(a.inner_product(b));
Vectorの
System.out.println(c.inner_product(d));
Vector3Dの
System.out.println(a.length());
Vectorの
System.out.println(c.length());
Vectorの
a = a.outer_product(b);
エラー!!
c = c.outer_product(d);
Vector3Dの
}
}
→変数の型宣言だけを見て呼出し先がわかることに注意!!
Javaによるオブジェクト指向
(多相性1)

ところで…
class Vector {
:
double length() {
return Math.sqrt(this.inner_product(this));
}
どちらの inner_product
}
が呼ばれるか?
class Test {
public static void main(String args[]) {
Vector a = new Vector(5, 10);
:
Vector3D c = new Vector3D(5, 10, 15);
:
System.out.println(a.length());
Vector の length()
System.out.println(c.length());
Vector の length()
:
Javaによるオブジェクト指向
(多相性2)

多相性(ポリモルフィズム):
class Vector {
this の「実際の」型に応じて
:
呼び分けられる
double length() {
return Math.sqrt(this.inner_product(this));
}
this = c
}
this = a
class Test {
public static void main(String args[]) {
Vector a = new Vector(5, 10);
:
Vector3D c = new Vector3D(5, 10, 15);
:
System.out.println(a.length());
System.out.println(c.length());
:
Javaによるオブジェクト指向
(多相性3)

ポリモルフィズムの別の例:
class Test {
public static void main(String args[]) {
Vector a = new Vector(5, 10);
Vector b = new Vector(15, 20);
System.out.println(a.inner_product(b));
Vector c = new Vector3D(5, 10, 15);
Vector d = new Vector3D(20, 25, 30);
System.out.println(c.inner_product(d));
a = c;
cはVectorで宣言されているが,
b = d;
「実際の」型はVector3D
System.out.println(a.inner_product(b));
}
aはVectorで宣言されているが,
}
「実際の」型はVector3D
多相性の考え方

メッセージを送る人は送り先の具体的なクラス
(具象クラス)を知らなくてもよい.

実際に呼ぶメソッドは実行時に決まる(遅延束縛).
Vector a
Vector
Vector a
inner_product()
Vector a
Vector3D
inner_product()
Test
Vector4D
多態性の使い方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メソッドが呼
ばれる