vieweditattachhistorytopchangessearchhelp

第23回


■SqueakではじめるSmalltalk入門   第23回


 本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回はメソッドの再定義、つまりオーバーライドです。

 a StockAccountもa BankAccount同様、「balance」あるいは「balance: …」というメッセージを受けとることができます。ただ、a BankAccountのときとその振る舞いは異なります。つまり“多態”するわけです。

 a StockAccountにとって、「balance」というメッセージを受けて返すべき値は、インスタンス変数balanceの値【註1】ではなく、新しく設けられたインスタンス変数pricePerShareとnumSharesの積でなけければいけません。同様に、メッセージ「balance: …」に対しては、pricePerShareの単価で購入できるぶんの株数をnumSharesに設定すること、がそれに相応しい振る舞いとなります。なお、ここでは簡単のため、株数に端数も許すことにしています。

balance
  ^ self pricePerShare * self numShares


balance: aNumber
  self numShares: aNumber asFloat / self pricePerShare


 メッセージasFloatは、主に整数(an Integer)などに対して送信することで等価の浮動小数点数(a Float)を返します。これは、Integer >> #/ がan Integerをパラメータに取るとき、分数(a Fraction)を生成してしまうので、こうした状況を防ぐための処置です。参考まで、次にInteger >> #/の定義を転載しておきます。【註2】

Integer >> / aNumber
  | quoRem |
  aNumber isInteger ifTrue:
    [quoRem _ self digitDiv: aNumber abs neg: self negative ~~ aNumber negative.
    (quoRem at: 2) = 0
      ifTrue: [^ (quoRem at: 1) normalize]
      ifFalse: [^ (Fraction numerator: self denominator: aNumber) reduced]].
  ^ aNumber adaptToInteger: self andSend: #/


 さて、実はこれでStockAccountの定義は完了です。そう、#deposit:と#withdraw:は再定義の必要はないのです。論より証拠。実際に試してみることにしましょう。

| stock |
World findATranscript: nil.           "transcriptを開く"
stock _ StockAccount new.             "a StockAccount作成"
stock balance: 300.                   "300円預金"
Transcript cr; show: stock balance.   "残高照会   => 300.0 "
Transcript cr; show: stock numShares. "株数に換算 => 10.0 "
stock deposit: 90.                    "90円預入"
Transcript cr; show: stock balance.   "残高照会   => 390.0 "
Transcript cr; show: stock numShares. "株数に換算 => 13.0 "
stock withdraw: 240.                  "240円払戻"
Transcript cr; show: stock balance.   "残高照会   => 150.0 "
Transcript cr; show: stock numShares. "株数に換算 => 5.0 "
stock withdraw: 180.                  "180円払戻"
Transcript cr; show: stock balance.   "残高照会   => 0.0 "
Transcript cr; show: stock numShares. "株数に換算 => 0.0 "


 なぜこのようなことになるのかについては、次回、解説します。


註1:サブクラスには、スーパークラスのメソッドだけでなく、そこで定義されたインスタンス変数も継承されるので、a StockAccountには本来無用なインスタンス変数balanceも継承されてしまっています。継承させる属性を取捨選択するための言語機能が備えられていないことは、Smalltalkでクラス指向、つまり「C++タイプのオブジェクト指向」をすることが難しいことを意味します。純粋なクラス指向で考えたとき、あれもない、これもない状態のSmalltalkは、かなり駄目なオブジェクト指向言語なのです。

註2:メソッドのメッセージパターンには、本来不要な「クラス名 >> 」という表現を追記して、そのメソッドがどのクラスに帰属するのかを明示的にすることがあります。以降の回ではサンプルメソッドにもこのような表記を用いることがあるので、もし、ブラウザなどにコピー&ペーストしてそのまま使用するときは、「クラス名 >> 」の部分は選択せずに、それを省いた残りをコピーするようにしてください。

このページを編集 (3507 bytes)


Congratulations! 以下の 1 ページから参照されています。

This page has been visited 849 times.