はてなキーワード: スーパークラスとは
お前のいう通り書いたったわ(C#だが)。
//宇宙 namespace Universe { //あらゆる神の根底に存在する唯一神とその司る運(スーパークラス) public class GodLuck { public string Name { get; } //神の名前 public string Power { get; } //神の力 public string Plan { get; } //神の計画 public string Factor { get; } //運の要因 public GodLuck(string name, string power, string plan, string factor) { Name = name; //神の名前 Power = power; //神の力 Plan = plan; //神の計画 Factor = factor; //運の要因 } //神が何かを創造するメソッド public void Create(string thing) { Console.WriteLine($"{Name} created {thing}."); } //神が何かに対して支配や介入をするメソッド public void Control(string thing, string action) { Console.WriteLine($"{Name} {action} {thing}."); } //運が何かに対して影響を与えるメソッド public void Affect(string thing, string outcome) { Console.WriteLine($"{Name} affected {thing} and the outcome was {outcome}."); } } //恵比須様 public class EbisuSama : GodLuck { public EbisuSama() : base("恵比須様", "商売繁盛や五穀豊穣の力", "人々に幸せを与える計画", "商売繁盛や五穀豊穣の要因") { } //作物を守る public void Save(string crops) { Control(crops, "守る"); } //人間を成功させる public void MakeSuccessful(string person) { Affect(person, "成功"); } } }
(大いなる力を別のクラスに移譲したくなったが、神と大いなる力は同一のオブジェクトという要件があるからやめた)
//宇宙 namespace Universe { //神の振る舞いを定義したインターフェイス public interface IGodLuck { public string Name { get; } public string Power { get; } public string Plan { get; } public string Factor { get; } //神が何かを創造するメソッド public void Create(string thing); //神が何かに対して支配や介入をするメソッド public void Control(string thing, string action); //運が何かに対して影響を与えるメソッド public void Affect(string thing, string outcome); } //恵比須様 public class EbisuSama : IGodLuck { public string Name { get; } //神の名前 public string Power { get; } //神の力 public string Plan { get; } //神の計画 public string Factor { get; } //運の要因 public EbisuSama() { Name = "恵比須様"; //神の名前 Power = "商売繁盛や五穀豊穣の力"; //神の力 Plan = "人々に幸せを与える計画"; //神の計画 Factor = "商売繁盛や五穀豊穣の要因"; //運の要因 } //神が何かを創造するメソッド public void Create(string thing) { Console.WriteLine($"{Name} created {thing}."); } //神が何かに対して支配や介入をするメソッド public void Control(string thing, string action) { Console.WriteLine($"{Name} {action} {thing}."); } //運が何かに対して影響を与えるメソッド public void Affect(string thing, string outcome) { Console.WriteLine($"{Name} affected {thing} and the outcome was {outcome}."); } //物を守る public void Save(string thing) { Control(thing, "守る"); } //人間を成功させる public void MakeSuccessful(string person) { Affect(person, "成功"); } } }
javascriptでスーパークラスのメソッドを簡単に呼び出したかった。それだけだった。
var Class = inherit(SuperClass, {hoge: ...});
作ったクラスはprototypeに、第二引数のオブジェクトがコピーされたスーパークラスのインスタンスを持つ。
第一引数がnullだと、スーパークラスにObjectを用いる。つまり、
var Class = inherit(null, {hoge: ...});
は
var Class = inherit(Object, {hoge: ...});
と同等となる。
また、第一引数が"prototype"をメンバに持たない普通のオブジェクト、つまり、
var Class = inherit({hoge: ...});
だと
var Class = inherit(Object, {hoge: ...});
と同等となる。
var obj = new Class({hoge: ...});
でインスタンスを作ると、引数のオブジェクトのコピーを持つオブジェクトとなる。
また、メソッド"initialize"が自動的に実行される。
ただし、コンストラクタに引数を渡さなかった場合は、initializeは実行されない。
this.superapply(arguments);
としてスーパークラスのメソッドを呼べる。第一引数は呼び出すメソッドの引数の配列とする。
このとき、呼び出し側のメソッドはコンストラクタやinheritでオーバーライドしたメソッドでなくてはならない。これは呼び出し側のメソッド名を記録する必要があるためである。
そうでない場合は第二引数にメソッド名を渡す必要がある。
var obj = new Class({}); obj.foo = function(){ this.superapply(arguments); // X this.superapply(arguments, "foo"); // O };
<html><head> <script type="text/javascript"> function inherit(superclass, override) { if (!superclass) superclass = Object; if (! "prototype" in superclass) { override = superclass; superclass = Object; } var that; var func; function superapply(arg, name) { var prev = {that: that, func: func}; try { var my = this.superapply; if (!arg) arg = []; if (!name) name = arguments.callee.caller.caller.methodName; if (that && func && (!name || name == func.methodName)) { that = that.superapply.obj; name = func.methodName; } else if (name) { that = my.obj; func = arguments.callee.caller.caller; func.methodName = name; } else { throw new Error("methodName is null"); } var result; if (func === that[name]) { result = this.superapply(arg, name); } else { func = that[name]; func.methodName = name; result = func.apply(this, arg); } } finally { that = prev.that; func = prev.func; } return result; }; var prototype = new superclass(); prototype.superapply = function(){superapply.apply(this, arguments)}; prototype.superapply.obj = superclass.prototype; if (override) for (var i in override) { prototype[i] = override[i]; if (typeof override[i] == "function") prototype[i].methodName = i; } var subclass = function(obj) { this.superapply = function(){superapply.apply(this, arguments)}; this.superapply.obj = prototype; if (obj) { for (var i in obj) { this[i] = obj[i]; if (typeof obj[i] == "function") this[i].methodName = i; } this.initialize(); } }; subclass.prototype = prototype; subclass.prototype.constructor = subclass; return subclass; } var C1 = inherit(Object, { fn: "C1", initialize: function(){ alert("C1.initialize"); this.second(this.fn); }, second: function(a){ alert("C1.second: "+a); } }); var C2 = inherit(C1, { fn: "C2", initialize: function(){ alert("C2.initialize"); this.superapply(); // }, //second: // function(a){ // alert("C2.second: "+a); // this.superapply([a]); } }); var C3 = new C2({ fn: "C3", //initialize: // function(){ // alert("C3.initialize"); // this.superapply(); // }, second: function(a){ alert("C3.second: "+a); this.superapply([a]); } }); </script> </head><body> </body><html>
methodNameなんとかならんもんか。
やっぱりprototype.jsのClass.create?
使った事無いけどスーパークラスのメソッド呼び出しできるんだっけ?
http://iandeth.dyndns.org/mt/ian/archives/000664.html
とか参考に自分で書いたら段々でかくなって、4行が今57行w
やっぱ言語のサポートないと辛いわ。こんなに大変だと思わなかった。
って事で「javascriptの継承方法の決め手」なーい?と聞いてみる。
欲しいのは、多重継承が可能で、オーバーライドした子クラスのメソッドから、簡単にオーバーライドされてる親クラスのメソッド呼びたい。ただし、thisは子クラスのオブジェクトのままで、しかも何段でもチェーンをたどれるように。
それとも、あきらめて、クラス名付きで直接親メソッド呼んだ方が良いのかな。やっぱり。
ま。とりあえずシュミグラマだから趣味に走ってみるけれども。
趣味グラマーのおいらに言わせりゃ、オブジェクト指向だなんだとかっこいい言葉を使っちゃいるけど、現状の実態は構造化のなれの果てのような気がする。
というかなんか酷い。こんな現状ならオブジェクト指向なんかない方がいい。
結局使われ方だってメンバっつうか、メソッドレベルのクラス化だし、
なんていうのかな・・・
たとえるのなら、
windowsのフォルダの階層を無駄に山のようにつくって、迷路のようにした挙句、
プロはこんな風にあらかじめ決まったフォルダ構造を導入すると何がどこにあるかわかるんだ!
とかいっちゃいながら、結局なにをどこにしまったかわらなくなって、案内用のドキュメントをつくったりしてる、
そんな滑稽な姿がおもいうかぶんだ。
いや、100人月いくぐらいのサイズのものだったらわかるよ?
そうやった方が効率的だし、再利用効くよね。
でも、ファイル数個格納するのにこのフォルダ数は意味ないだろ?的な、
大変だ!このままじゃ利用しにくいからデスクトップにショートカットつくろう!
これがスーパークラスだー!
とか、なんつうか本末転倒。
オブジェクト指向もほどほどにねー。