Building bigger abstractions
All ball objects in a program are similar to each other in some ways.
All paddle objects are similar to each other.
So we write Ball and Paddle classes to
capture those two kinds of objects that exist.
We saw examples of this is the Classes slides.
class Ball {
constructor(x, y, size, color) {
this.x = x;
this.y = y;
this.size = size ?? 15;
this.color = color ?? 'blue';
}
draw(g) {
g.drawFilledCircle(
this.x, this.y, this.size, this.color
);
}
}
class Paddle {
constructor(x, y, width, height, color) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color ?? 'blue';
}
draw(g) {
g.drawFilledRect(
this.x, this.y, this.width, this.height, this.color
);
}
}
Both have x, y, and
color properties.
Both have a draw method (though they do different
things).
Not only are all Balls the same kind of object and all
Paddles the same kind of object, in an important sense,
all Balls and Paddles together are also
the same kind of more general object.
Inheritance is a way to make more explicit what it means to be the same kind of thing.
Things in games that can be shown on the screen and moved around are often called “sprites”.
We might say that balls and paddles are both kinds of sprites in our game.
Let’s write a class to capture the idea of what a sprite, in general, is.
Sprite classclass Sprite {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.dx = 0;
this.dy = 0;
this.color = color;
}
accelerate(dx, dy) {
this.dx += dx;
this.dy += dy;
}
move(elapsed) {
this.x += this.dx * elapsed;
this.y += this.dy * elapsed;
}
}
Ball as a Spriteclass Ball extends Sprite {
constructor(x, y, size, color) {
super(x, y, color);
this.size = size ?? 15;
}
draw(g) {
g.drawFilledCircle(
this.x, this.y, this.size, this.color
);
}
}
A Ball is a kind of Sprite. It can be
moved and accelerated and drawn.
Paddle as a Spriteclass Paddle extends Sprite {
constructor(x, y, width, height, color) {
super(x, y, color);
this.width = width;
this.height = height;
}
draw(g) {
g.drawFilledRect(
this.x, this.y, this.width, this.height, this.color
);
}
}
A Paddle is also a kind of Sprite. It can
also be moved and accelerated and drawn.
Ball and Paddle inherit things from
Sprite
They don’t have to initialize the x,
y, and color properties themselves.
They automatically get accelerate and
move methods.
draw method
All Sprites should have a draw method but
there’s no easy way in Javascript to require that.
The reason there’s no draw method in
Sprite is because there’s no way to draw a sprite in
general—we can only draw actual specific kinds of sprites.
Note, however, that the point is not to use inheritance just to avoid having to copy code.
The point is that by defining a class and then extending it with
other classes you are creating a new higher level abstraction. (Or
making explicit an implicit abstraction like we had with
Ball and Paddle before we introduced the
Sprite class.)