2015年5月11日月曜日

JavaScriptのクラスの承継について

JavaScriptでは、クラスがありません

従って、C#、C++のプログラマは、JavaScriptを使うとなると、まずクラスを使って、承継方法について悩みます。
そこで、prototypeを使って擬似的にクラス表現を使います。

以下はその手段について記載します。

【コード例(1)】
var ClassA = function(cname) { this.name = cname; }
 ClassA.prototype.print = function() { console.log(this.name); } 
var a = new ClassA("クラスA"); 
a.print();
  ⇒クラスAと表示
var a = new ClassA("クラスB"); 
a.print();
  ⇒クラスBと表示 

1) まず、関数(function)を作成します。
var ClassA = function(cname) { this.name = cname; }

2) Classはnewでイスタンス(オブジェクト)を作成する
var a = new ClassA("クラスA");

3) 関数を登録する
ClassA.prototype.print = function() { console.log(this.name); }
※関数を作成すると、prototypeは自動で作成されます。
「prototype=自分の親クラスへの参照」だと考えると、理解しやすいです。

尚、もし、prototypeを使わないで以下のコードのようにすると、毎回functionが作成されます。
(下赤字に記載したように、毎回オブジェクトを作成して、print関数を定義しています)
var ClassA = function()  {
 // var this = {};  
this.print = function() { console.log(this.name); }
 // return this; 
}
prototypeを使うと、function内で、関数を定義する必要がないので、一回prototypeで定義すれば、共通で使うことができます。
var a = new ClassA("クラスB"); 
a.print();
  ⇒クラスBと表示 

4) オブジェクトを通して3)で設定した関数を実行する
 a.print();
⇒親クラスのprintを実行する

【まとめ】
汎用的な関数はprototypeに定義する


【コード例(2)】
var ClassA = function() {
    this.name = "
クラスA";

  this.surname = "クラス"
 }
var inheritsFrom = function (child, parent)
 { child.prototype = Object.create(parent.prototype); };
 var a = new ClassA();
ClassA.prototype.print = function() {
    console.log(this.name);
}
var ClassB = function() { this.name = "クラスB"; this.surname = "子クラス"; } 
inheritsFrom(ClassB, ClassA);
var b = new ClassB();
b.print();
   ⇒クラスBと表示 

1)承継関係を行う関数作成
次のような継承関数(inheritsForm)をつくり、子オブジェクトのprototypeに親オブジェクトのprototypeを設定しなおすことで、擬似継承する手もあります。

var inheritsFrom = function (child, parent)
 { child.prototype = Object.create(parent.prototype); };

上記の関数で親クラス(parent)の関数を全て、子クラス(child)にコピーします。

var a = new ClassA();
ClassA.prototype.print = function() {
    console.log(this.name);
}
var ClassB = function() { this.name = "クラスB"; this.surname = "子クラス"; } inheritsFrom(ClassB, ClassA);

クラスBはクラスAを継承しますので、ClassAのprint関数を実行できます。
var b = new ClassB();
b.print();
   ⇒クラスBと表示 

ClassBのprint関数をoverrideするには、次のように記載します。
ClassB.prototype.print = function() { 
  ClassA.prototype.print.call(this); 
  console.log(this.surname);
 }
   ⇒クラスB
   子クラス と表示

Call(this)関数によって、ClassBのprint関数が実行されます。


では、さらなる継承クラスClassCをつくるには、次のようにします。

var ClassC = function () {
    this.name = "クラスC";
    this.surname = "子のまた子クラス";
}
inheritsFrom(ClassC, ClassB);
ClassC.prototype.foo = function() {
    // Do some funky stuff here...
}
ClassC.prototype.print = function () {
    ClassB.prototype.print.call(this);
    console.log("Sounds like this is working!");
}
var c = new ClassC();
c.print();

   ⇒クラスC
   子のまた子クラス と表示



【参考URL】
http://www.codeproject.com/Articles/899662/Simple-inheritance-with-JavaScript
http://qiita.com/takeharu/items/809114f943208aaf55b3

0 件のコメント:

コメントを投稿