![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
実装抜きで宣言することによって、実装に依存しないクラス間の関係を構築でき、 コードの再利用を促進します。
The Online Sather Code Browser をみるとわかるように、 Sather では、継承の多くは抽象クラスを用いて行われており、通常のクラスの継承は底のほうで少しあるだけです。
抽象クラスは、次の章で説明するパラメター付クラス (Parametrized Class) と組み合わせることにより、柔軟なデータ型を構築することができます。
01: -- an example of abstract class; $CRYPT and $MESSAGE 02: 03: 04: -- algorithm for cryptogram 05: abstract class $CRYPT is -- 暗号化アルゴリズムの抽象クラス。抽象クラスは $ に続けて全て大文字で書く。 06: encrypt(s:STR):STR; -- 暗号化と 07: decrypt(s:STR):STR; -- 復号化の2つのメソッドを持つ。 08: end; -- end $CRYPT 09: 10: -- sipher message 11: abstract class $MESSAGE is -- メッセージ用抽象クラス 12: send(s:STR):STR; 13: receive(s:STR):STR; 14: end; -- end $MESSAGE 15: 16: -- Plain text 17: class PLAIN < $CRYPT is -- 何もしない暗号化アルゴリズム 18: create:SAME is 19: return new; 20: end; 21: 22: encrypt(s:STR):STR is 23: return s; 24: end; 25: 26: decrypt(s:STR):STR is 27: return s; 28: end; 29: end; -- end PLAIN 30: 31: -- Simple XOR cryptogram 32: class XOR < $CRYPT is -- キーとの排他的論理和をとる暗号化アルゴリズム 33: 34: private attr keylist:ARRAY{INT}; 35: 36: create(key:STR):SAME is 37: return new.init(key); 38: end; 39: 40: private init(key:STR):SAME is 41: keylist:=#(key.size); 42: loop 43: keylist.set!(key.elt!.int); -- キーを整数の配列として保持 44: end; 45: return self; 46: end; 47: 48: private key_rotate!:INT is -- 呼ばれるたびに keylist の次の要素を返す。最後まで行ったら最初に戻る。 49: i:INT:=0; 50: n:INT:=keylist.size-1; 51: loop 52: yield keylist[i]; 53: if i=n then 54: i:=0; 55: else 56: i:=i+1; 57: end; 58: end; 59: end; 60: 61: encrypt(s:STR):STR is 62: fs:FSTR:=#(s.size); -- FSTR は変更可能な文字列 63: loop 64: fs := fs + s.elt!.int.bxor(key_rotate!).char; -- fs の最後にメッセージとキーの XOR で作った一文字を追加していく。 65: end; 66: return fs.str; 67: end; 68: 69: decrypt(s:STR):STR is -- 排他的論理和による暗号化では、復号化は暗号化と同じ。 70: return encrypt(s); 71: end; 72: end; -- end of XOR 73: 74: partial class MESSAGE < $MESSAGE is -- メッセージに共通する要素を部分クラスとして書き出す。 75: stub cry:$CRYPT; -- 暗号化アルゴリズム。下部クラスで再定義される。 76: 77: send(s:STR):STR is 78: return cry.encrypt(s); 79: end; 80: 81: receive(s:STR):STR is 82: return cry.decrypt(s); 83: end; 84: end; -- end MESSAGE 85: 86: -- Plain Message 87: class USUAL < $MESSAGE is 88: include MESSAGE; 89: private const cry:PLAIN:=PLAIN::create; -- cannot use #PLAIN here. 90: 91: create:SAME is 92: return new; 93: end; 94: end; -- end USUAL 95: 96: -- Sipher Message 97: class IMPORTANT < $MESSAGE is 98: include MESSAGE; 99: private attr cry:XOR; 100: 101: create(key:STR):SAME is 102: return new.init(key); 103: end; 104: 105: private init(key:STR):SAME is 106: cry:=#(key); 107: return self; 108: end; 109: end; -- end IMPORTANT 110: 111: class MAIN is 112: 113: private const key:STR:= "qwertyuiop@asdfghjkl;zxcvbnm,"; -- key for XOR 114: 115: main(av: ARRAY{STR}) is 116: if av.size=2 then 117: plain:USUAL:= #; 118: sixor:IMPORTANT:=#(key); 119: msg:STR:=av[1]; -- 最初の引数を暗号化する。 120: plain_send:STR:=plain.send(msg); 121: plain_receive:STR:=plain.receive(plain_send); 122: xor_send:STR:=sixor.send(msg); 123: xor_receive:STR:=sixor.receive(xor_send); 124: #OUT + "Sipher Test using \"" + msg + "\"\n\n"; 125: #OUT + "Plain send: " + plain_send + "\n"; 126: #OUT + "Planin receive: " + plain_receive + "\n\n"; 127: #OUT + "XOR send: " + xor_send + "\n"; 128: #OUT + "XOR receive: " + xor_receive + "\n\n"; 129: else 130: #ERR + "Usage: crypt \'STRING\'\n"; 131: end; 132: end; 133: end; -- end of MAINコンパイルして実行すると以下のようになります。
$ sacomp crypt.sa -o crypt
$ ./crypt 'Welcome to Satehr World.'
Sipher Test using "Welcome to Satehr World."
Plain send: Welcome to Satehr World.
Planin receive: Welcome to Satehr World.
XOR send: (表示できない文字列)
XOR receive: Welcome to Satehr World.
暗号化アルゴリズムは抽象クラスになっているので、もっと強度の強い暗号を用いたいときにはコードのほかの部分を
ほとんど変えることなく暗号化アルゴリズムを変更することができます。
99: private attr cry:AES;
クラス名 | インターフェース | 説明 |
---|---|---|
$OB | 全てのクラスは $OB のサブクラスです。 | |
$IS_EQ | is_eq(e:$OB):BOOL; | self と e が等しければ true を返します。 |
$IS_LT | is_lt(e:T):BOOL; | self が e より小さければ true を返します。 $IS_EQ のサブクラスです。 |
$IS_NIL | is_nil:BOOL; | self が nil なら true を返します。 |
$NIL | nil:SAME; | self を nil にします。 |
$STR | str:STR | self を文字列に変換します。ほとんど全てのクラスは $STR のサブクラスです。 |
$NEF{NTP} | abs, plus, minus, tiems, div, ... | 代数のクラスです。サブクラスに $NUMBER{NTP}, $CPX_NUMBER{ETP} があります。 |
$ELT | elt!:$OB | イテレーター elt! を定義するクラスです。$ELT{T} の親クラスです。 |
$ELT{T} | elt!:T | 実質的にイテレーター elt! を定義しています。 |
$CONTAINER{ETP} | copy, has, size | 入れものクラスです。パラメター付クラスのほとんどがこのクラスのサブクラスです。 |
$HASH | hash | ハッシュ値を計算するクラスです。ハッシュ表のキーになることができるクラスは $HASH のサブクラスです。 |
抽象クラスについての詳しい情報は Sather 1.1 : Language Essentials をみてください。 また、 The Online Sather Code Browser を眺めると感じをつかむことができます。
次回はパラメター付クラス (Parametrized Class) について説明します。
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |