super()を使った親メソッドの呼び出しと、多段継承の実践例です。
p5.js oop
Learning OOP Object Oriented Programming
OOPの応用編!オーバーライドとsuperの活用方法を学びます。
クラス構造
AbstractShape
├── Circle (基本的な円)
└── AbstractNewShape (拡張ベース)
├── ColoredCircle (色付き円)
└── Rect (色・サイズ変更する四角)super()の使い方
class AbstractNewShape extends AbstractShape {
constructor(c = 0, size = 10) {
super(); // 親のconstructorを呼ぶ
this.c = c;
this.size = size;
}
update() {
super.update(); // 親のupdateを呼ぶ
this.c = (this.c + 1) % 360; // 追加の処理
}
}init()メソッドのオーバーライド
class Rect extends AbstractNewShape {
init() {
this.b = 0; // 追加のプロパティ
}
}学んだこと
super(): 親クラスのメソッドを呼び出す- オーバーライド: 親のメソッドを上書きする
- 多段継承: 複数階層の継承
- 機能の追加と拡張のバランス
これでOOP学習シリーズは完了です!
← 最初から復習する 101.変数ベースの単一キャラ
View Source Code
let W, H, PW, PH;
const PADDING_RATIO = 0.2;
const MAX_SPEED = 10;
let objs = [];
const MAX = 100;
class AbstractShape {
constructor() {
this.pos = {
x: random(width),
y: random(height),
};
this.speed = {
x: (Math.random() - 0.5) * MAX_SPEED,
y: (Math.random() - 0.5) * MAX_SPEED,
};
this.acceleration = 0.1;
this.t = 0
this.init()
}
init() {
}
update() {
this.t++;
this.pos.x += this.speed.x;
this.pos.y += this.speed.y;
if (this.pos.x < 0 + PW) {
this.speed.x += this.acceleration;
} else if (this.pos.x > W - PW) {
this.speed.x -= this.acceleration;
}
if (this.pos.y < 0 + PH) {
this.speed.y += this.acceleration;
} else if (this.pos.y > H - PH) {
this.speed.y -= this.acceleration;
}
}
display() {
// implement in subclass
}
}
class AbstractNewShape extends AbstractShape {
constructor(c = 0, size = 10) {
super();
this.c = c;
this.size = size
}
update() {
super.update();
this.c = (this.c + 1) % 360;
}
}
class Circle extends AbstractShape {
display() {
stroke(0);
fill(0);
ellipse(this.pos.x, this.pos.y, 10, 10);
// text(["1:", Math.floor(this.pos.x), Math.floor(this.pos.y)], this.pos.x + 10, this.pos.y + 10);
}
}
class ColoredCircle extends AbstractNewShape {
display() {
push();
{
colorMode(HSB);
stroke(this.c, 100, 100);
fill(this.c, 100, 100);
ellipse(this.pos.x, this.pos.y, 10, 10);
// text(["1c:", Math.floor(this.pos.x), Math.floor(this.pos.y)], this.pos.x + 10, this.pos.y + 10);
}
pop();
}
}
class Rect extends AbstractNewShape {
init() {
this.b = 0
}
update() {
super.update()
this.b = cos(radians(this.t)) * 32 + 68
}
display() {
push();
{
colorMode(HSB);
stroke(this.c, 100, this.b);
fill(this.c, 100, this.b);
rectMode(CENTER);
rect(this.pos.x, this.pos.y, this.size, this.size);
// text(["2:", Math.floor(this.pos.x), Math.floor(this.pos.y)], this.pos.x + 20, this.pos.y + 20);
}
pop()
}
}
// main
function setup() {
createCanvas((W = windowWidth), (H = windowHeight));
PW = W * PADDING_RATIO;
PH = H * PADDING_RATIO;
for (let i = 0; i < MAX; i++) {
const shapeType = Math.floor(Math.random() * 3);
switch (shapeType) {
case 0:
objs.push(new Circle());
break;
case 1:
objs.push(new ColoredCircle(Math.floor(Math.random() * 360)));
break;
case 2:
objs.push(
new Rect(
Math.floor(Math.random() * 360),
Math.floor(Math.random() * 100 + 10)
)
);
break;
}
}
}
function draw() {
background(255);
for (let i = 0; i < objs.length; i++) {
const obj = objs[i];
obj.update();
}
for (let i = 0; i < objs.length; i++) {
const obj = objs[i];
obj.display();
}
}