BankAccount
人はなぜ BankAccount を書くのでしょうか?
知らんけど.
ってことで ECMAScript 3rd Edition での BankAccount サンプルです.
ブラウザ向けなので alert() を使ってますがそれ以外の環境なら別の出力関数を使いましょう.rhino*1 や SEE*2 なら print(),WSH の JScript なら WScript.Echo() あたりが使えます.
以下書いてみた感想.
- メソッド呼び出しとプロパティへのアクセスは文法上明確に区別されるのでちゃんと多態しようと思ったらすべてメソッド経由でアクセスする必要がある.自己カプセル化万歳.
- アクセサメソッドを書いたとしてもプロパティは public なままなので直接変更できてしまう.
- チャイルドオブジェクトを作るのにコンストラクタとなる関数オブジェクトを作らないといけないのが面倒.(clone() メソッドを作ればいいんでしょうけど http://d.hatena.ne.jp/sa-y/20060304#1141499154 )
ECMAScript 4th Edition ならもっと違うでしょうけど.
BankAccount = new Object() BankAccount.setDollars = function(dollars){ this.dollars = dollars } BankAccount.getDollars = function(){ return this.dollars; } BankAccount.setDollars(200) alert(BankAccount.getDollars()) // => 200 BankAccount.deposit = function(x){ this.setDollars(this.getDollars() + x) } BankAccount.deposit(50) alert(BankAccount.dollars) // => 250 BankAccount.withdraw = function(x){ this.setDollars((x > this.getDollars()) ? 0 : (this.getDollars() - x)); } BankAccount.withdraw(100) alert(BankAccount.getDollars()) // => 150 BankAccount.withdraw(200) alert(BankAccount.getDollars()) // => 0 BankAccountChild = function(){} BankAccountChild.prototype = BankAccount account = new BankAccountChild() alert(account.getDollars()); // => 0 account.deposit(500) alert(account.getDollars()); // => 500 alert(BankAccount.getDollars()) // => 0 # prototype の dollars には影響しない StockAccount = new BankAccountChild() StockAccount.numShares = 10 StockAccount.pricePerShare = 30 StockAccount.getDollars = function(){ return this.numShares * this.pricePerShare; } StockAccount.setDollars = function(x){ this.numShares = x / this.pricePerShare; } alert(StockAccount.getDollars()) // => 300 # 株数、株単価から計算 StockAccount.setDollars(150) alert(StockAccount.getDollars()) // => 150 alert(StockAccount.numShares) // => 5 # 株数値が変更されている StockAccountChild = function(){} StockAccountChild.prototype = StockAccount myStock = new StockAccountChild() myStock.setDollars(600) alert(myStock.getDollars()); // => 600 alert(myStock.numShares); // => 20 myStock.deposit(60) alert(myStock.getDollars()); // => 660 alert(myStock.numShares); // => 22