「JavaScript/クラス」の版間の差分

削除された内容 追加された内容
Ef3 (トーク | 投稿記録)
タグ: 2017年版ソースエディター
Ef3 (トーク | 投稿記録)
タグ: 2017年版ソースエディター
105 行
この行は表示確認用メッセージ
</pre>
 
=== 包含と継承 ===
クラス間の関係で混乱しやすいのが、包含と継承です。
;包含:クラスAがクラスBを1つまたは複数プロパティに持っている。⇒ クラスAはクラスBを包含している。
;継承:クラスAのプロパティPを参照したとき、A.Pが定義されていなかっクラスBのプロパティPが参照される。⇒ クラスAはクラスBを継承している。
;包含と継承のサンプルコード:<syntaxhighlight lang="javascript" highlight='16,27' line>
class Point {
constructor(x = 0, y = 0) {
console.info("Point::constructor")
return Object.assign(this, { x, y });
}
move(dx = 0, dy = 0) {
this.x += dx
this.y += dy
console.info('Point::move');
return this
}
}
 
class Shape {
constructor(x = 0, y = 0) {
this.location = new Point(x, y)
console.info("Shape::constructor")
return this
}
move(x, y) {
this.location.move(x, y)
console.info('Shape::move');
return this
}
}
 
class Rectangle extends Shape {
constructor(x = 0, y = 0, width = 0, height = 0) {
super(x, y)
Object.assign(this, { width, height })
console.info("Rectangle::constructor")
return this
}
}
 
console.info("Create a Rectangle!")
let rct = new Rectangle(12, 32, 100, 50)
console.info("rct = ", rct)
console.info('rct instanceof Rectangle => ', rct instanceof Rectangle)
console.info('rct instanceof Shape => ', rct instanceof Shape)
console.info('rct instanceof Point => ', rct instanceof Point)
rct.move(11, 21)
console.info("rct = ", rct)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="javascript" line>
Create a Rectangle!
Point::constructor
Shape::constructor
Rectangle::constructor
rct = Rectangle { location: Point { x: 12, y: 32 }, width: 100, height: 50 }
rct instanceof Rectangle => true
rct instanceof Shape => true
rct instanceof Point => false
Point::move
Shape::move
rct = Rectangle { location: Point { x: 23, y: 53 }, width: 100, height: 50 }
</syntaxhighlight>
;包含関係:<syntaxhighlight lang="javascript" start=14 highlight='3' line>
class Shape {
constructor(x = 0, y = 0) {
this.location = new Point(x, y)
</syntaxhighlight>
:ShapeはPointを包含している。
;継承関係:<syntaxhighlight lang="javascript" start=27 highlight='1,3' line>
class Rectangle extends Shape {
constructor(x = 0, y = 0, width = 0, height = 0) {
super(x, y)
</syntaxhighlight>
:RectangleはShapeを継承している。
:{{code|super(x, y)}}はスーパークラス(この場合はShape)のコンストラクターの呼び出し。
ES/JSは、単一継承しかサポートしませんが包含やMix-inを使うことで、多重継承を使う動機となる「機能の合成」は実現できます。
 
=== ES6 の class を使ったコードと相当するES5のコード ===
122 ⟶ 199行目:
let a = new Complex(1, 1)
let b = new Complex(2, 3)
console.loginfo("a = " + a)
console.loginfo("b = " + b)
console.loginfo("a + b = " + a.cadd(b))
console.loginfo("a - b = " + a.csub(b))
console.loginfo(a instanceof Complex)
</syntaxhighlight>
;ES5版:<syntaxhighlight lang="javascript" line>
139 ⟶ 216行目:
let a = new Complex(1, 1)
let b = new Complex(2, 3)
console.loginfo("a = " + a)
console.loginfo("b = " + b)
console.loginfo("a + b = " + a.cadd(b))
console.loginfo("a - b = " + a.csub(b))
console.loginfo(a instanceof Complex)
</syntaxhighlight>
;実行結果(ES6/ES5双方同じ):<syntaxhighlight lang="javascript" line>