8. 2011/4/7 オブジェクト指向プログラミング入門 9 8
例外メカニズム
? 救助と再開
? rescue 句:例外発生時に実行される
? retry 命令:ルーチン本体がはじめから再開される
routine is
do
body
rescue
rescue_clause
end
? 実際に試さずに失敗する方法
Rescue 句の実行が, retry 命令を実行せずに終了した場合,現在ルーチンの
呼び出しは失敗となる.
失敗の原則
9. 2011/4/7 オブジェクト指向プログラミング入門 9 9
例外処理例:脆弱な入力
Maximum_attempts: INTEGER is 5 -- 断念する前に整数入力を試す回数
get_integer is
-- 最大 Maximum_attempts 回まで,整数を読もうとする
local
attempts: INTEGER
do
if attempts < Maximum_attempts then
print(“ 整数を入力して下さい:” )
read_one_integer
integer_was_read := True
else
integer_was_read := False
attempts := attempts + 1
end
rescue
retry
end
10. 2011/4/7 オブジェクト指向プログラミング入門 9 10
例外処理例:ハードウェアあるいは
オペレーティングシステムの例外か
らの回復? 例外を引き起こすイベント
? シグナル群,オーバーフロー,アンダーフロー,不可能な I/O 操作,不正命
令,メモリ不足 , etc.
? 理論的にはこのような状態は表明違反と見なすことができる.
? 例:
quasi_inverse(x: REAL): REAL is
-- 可能なら 1/x ,さもなくば 0
local
division_tried: BOOLEAN
do
if not division_tried then
Result := 1/x
end
rescue
division_tried := True
retry
end
15. 2011/4/7 オブジェクト指向プログラミング入門 9 15
例:多角形と長方形
class POLYGON creation
…
feature
perimeter: REAL is -- 周囲の長さ
do … end
display is -- スクリーンに多角形を表示する
do … end
rotate(center: POINT; angle: REAL) is -- center を中心に angle だけ回転す
る
do … end
translate(a, b: REAL) is -- 水平に a, 垂直に b 移動する
do … end
feature {NONE} – 実装
vertices: LINKED_LIST[POINT]
invariant
same_count_as_implementation: count = vertices.count
at_leaset_three: count>= 3
end
16. 2011/4/7 オブジェクト指向プログラミング入門 9 16
例:多角形の回転
rotate(center: POINT; angle: REAL) is
-- center を中心に angle だけ回転する
do
from
vertices.start
until
vertices.after
loop
vertices.item.rotate(center, angle)
vertices.forth
end
end
17. 2011/4/7 オブジェクト指向プログラミング入門 9 17
例:多角形の周囲の長さ
perimeter: REAL is
local
this, previous: POINT
do
from
vertices.start; this := vertices.item
check not vertices.after end – at_least_three の結果
until
vertices.is_last
loop
previous := this; vertices.forth; this := vertices.item
Result := Result + this.distance(previous)
end
Result := Result + this.distance(vertices.first)
end
19. 2011/4/7 オブジェクト指向プログラミング入門 9 19
長方形の例
class RECTANGLE inherit POLYGON
redefine perimeter end
creation make
feature
make(center: POINT; s1, s2, angle: REAL) is
do … end
feature -- アクセスする
side1, side2: REAL -- 2辺の長さ
diagonal: REAL -- 対角線の長さ
perimeter: REAL is
do
Result := 2 * (side1 + side2)
end
invariant …
end
20. 2011/4/7 オブジェクト指向プログラミング入門 9 20
基本的な慣習と用語
クラス C の子孫( descendant )とは, C 自身を含み, C から直接的また
は間接的に継承するクラスを指す(形式的にいえば, C もしくは,再帰的
に C の後継者の子孫)
クラス C の真の子孫( proper descendant )とは, C 自身を除く子孫を
指す.
クラス C の祖先( ancestor )とは, C が A の子孫である場合の A を指す
.
クラス C の真の祖先( proper ancestor )とは, C が A の真の子孫である
場合の A を指す
継承の用語
POLYGON
RECTANGLE
? 継承の関係 perimeter
diagonal
perimeter++ ~継承している
21. 2011/4/7 オブジェクト指向プログラミング入門 9 21
不変表明の継承
class RECTANGLE inherit POLYGON
…
invariant
four_sides: count = 4
first_side: (vertices.i_th(1)).distance(vertices.i_th(2)) = side1
second_side: (vertices.i_th(2)).distance(vertices.i_th(3)) = side2
…
end
? B が A から継承されたということは, B のインスタンスすべて
が, A のインスタンスとも見なされることを意味する.
クラスの不変表明は,自分の invariant 句に表される表明と親の不変表明
(もし存在すれば)との論理積 and となる
不変表明の継承規
則
27. 2011/4/7 オブジェクト指向プログラミング入門 9 27
多相性の制限
? B が A の子孫であり, Y が X の子孫であるとき, B[Y] は A[X]
に適合する
? より特殊なものからより一般的なものへは代入可能であるが,
逆は不可能である.
U の基本クラスが T の基本クラスの子孫であるとき,型 U は型 T に適合す
る.また,総称的に派生された型においては, U のすべての総称パラメー
タは, T の対応する総称パラメータに(再帰的に)適合しなければならない
.
定義:適合性
( conformance )
アタッチ先 x とアタッチ元 y のアタッチメント(すなわち,代入 x := y ,も
しくは,仮引数 x のルーチンコールで,実引数が y の場合)は, y の型が x
の型に適合する場合にのみ許される.
型の適合性規則( Type Conformance Rule )
28. 2011/4/7 オブジェクト指向プログラミング入門 9 28
インスタンス,静的な型と動的な
型
p1, p2: POLYGON; r: RECTANGLE
create p1 …; create r …; p2 := r
? POLYGON の直接インスタンスは p1 のみ
? 静的な型:エンティティを宣言するのに使われた型
? 動的な型:実行時にアタッチされたオブジェクトの型
? 動的な型は再アタッチメント操作によって変更され得る
クラス C の直接インスタンスとは, C の厳密な定義に従い,生成命令
create x を通して作成されたオブジェクト,もしくは,再帰的に, C の直接
インスタンスをコピーしたものを指す.ただし, x は型 C に属する.
C のインスタンスとは, C の子孫の直接インスタンスを指す.
定義:直接インスタンスとインス
タンス
型 T で宣言されたエンティティは,実行時に T のインスタンスにアタッチ
され得る.
静的および動的な型の整合性
29. 2011/4/7 オブジェクト指向プログラミング入門 9 29
型を強要したいとき
? どうしても継承に反した代入をせざるを得な
い特殊な状況もある
? 例:特定の型であると公表されたオブジェクトを
ネットワークを通して受け取る場合
? オブジェクトのもとになるものを制御できないので,ア
クセス前に型を確認する必要がある
? 試行代入
? r ?= p
? 「もしオブジェクトの型が r に対して許される型
であるならば代入をしなさい.さもなくば r を
void にしなさい」
30. 2011/4/7 オブジェクト指向プログラミング入門 9 30
多相的生成
? T に真の子孫 U があると仮定
x:T
create {U} x -- U の直接インスタンスが生成
create {U} x.make(…)
? 生成型
? 生成命令によってつくられるオブジェクトの型
? 例:
f: FIGURE
…
if chosen_icon=rectangle_icon then
create {RECTANGLE} f
elseif chosen_icon = circle_icon then
create {CIRCLE} f
else
…
end
31. 2011/4/7 オブジェクト指向プログラミング入門 9 31
動的束縛
? 複数バージョンを持つルーチンを多相的エンティティで実行し
たらどうなるか?
p:POLYGON
…
if chosen_icon = rectangle_icon then
create {RECTANGLE} p.make(…)
elsif chosen_icon = triangle_icon then
create {TRIANGLE} p.make(…)
…
end
x := p.perimeter
? どのバージョンの操作を使うかはオブジェクトの動的形式に
よって決定される.
32. 2011/4/7 オブジェクト指向プログラミング入門 9 32
暫定特性と暫定クラス
? 任意の図形を移動する
transform(f: FIGURE) is
do
f.rotate(…)
f.translate(…)
end
? FIGURE は全図形を網羅した相対的なものなので, rotate や
translate を実装することができない...
? 何もしない rotate や translate を書いておくことは危険である
? かといって特性が無いと,型チェックにひっかかる
? 特性を暫定とする
rotate(center: POINT; angle: REAL) is
-- center を中心に angle だけ回転する
deferred end
FIGURE
OPEN_
FIGURE
CLOSE_
FIGURE
???
???