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 Sprite
class 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 Sprite
class 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 Sprite
s 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.)