//名前空間用オブジェクト生成
if (typeof (js) == "undefined") js = {};
if (typeof (js.tomaton) == "undefined") js.tomaton = {};
if (typeof (js.tomaton.Class) == "undefined" ) js.tomaton.Class = {};
//無名関数内でクラス定義
//いちいち名前空間付で定義するのはめんどいので最後に名前空間に登録する。
(function () {
var define = function(data) {
//クラス名
var classname = data.name;
//スーパークラス(継承するクラス)
var superclass = data.extend || Object;
//コンストラクタ
var constructor = data.construct || function(){};
//メソッドを定義したオブジェクト
var methods = data.methods || {};
//静的変数、メソッドを定義したオブジェクト
var statics = data.statics || {};
//Mixin用クラス(or その配列)
var borrows;
//ダックタイピング検証用クラス(or その配列)
var provides;
//Mixin用クラスをローカル変数に格納
//単体・配列に対応
if (!data.borrows) borrows = [];
else if (data.borrows instanceof Array) borrows = data.borrows;
else borrows = [data.borrows];
//ダックタイピング検証用クラスをローカル変数に格納
//単体・配列に対応
if (!data.provides) provides = [];
else if (data.provides instanceof Array) provides = data.provides;
else provides = [data.provides];
//プロトタイプの元となるオブジェクトを生成
//スーパークラスを指定した場合はスーパークラスのprototypeを引き継ぐ
var proto = new superclass();
//継承されたプロパティ以外は削除する
for (var p in proto)
if (proto.hasOwnProperty(p)) delete proto[p];
//Mixinクラスからメソッドをプロトタイプにコピー
for (var i = 0;i < borrows.length;i++) {
var c = data.borrows[i];
borrows[i];
//メソッドを、cのプロトタイプから新しいクラスのプロトタイプにコピー。
for (var p in c.prototype) {
if (typeof c.prototype[p] != "function") continue;
proto[p] = c.prototype[p];
}
}
//インスタンスメソッドをプロトタイプオブジェクトにコピーする
//Mixinメソッドを上書きする場合もある。
for (var p in methods) proto[p] = methods[p];
//ダックタイピング検証
//想定したメソッドが全て存在するかどうかチェックする
for (var i = 0;i < provides.length;i++) {
var c = provides[i];
for (var p in c.prototype) {
if (typeof c.prototype[p] != "function") continue;
if (p == "constructor" || p == "superclass") continue;
//同じ名前のメソッドを持ち、引数の数が同じかどうかチェックする
//同じ場合は処理続行
if (p in proto &&