CHAPTER 4 · 14 lessons · 182 exercises
One blueprint, many objects
Write a blueprint once, then make as many objects of that shape as you like. Data and behaviour, kept in one place.
With objects you can now hold one person's data. So what about ten people's? You end up writing { name: ..., age: ... } ten times. Want one more field and you are adding it in all ten places.
A class is the machinery that gets rid of that repetition. You write a blueprint once — "make things that hold these fields" — and then make as many real ones from it as you like. Fix the blueprint and everything made from it follows.
The blueprint is the class, and a real thing made from it is called an instance. Think of it as a waffle iron and the waffles that come out of it. One iron, any number of waffles. Whatever the filling, the shape is the same.
What settles the contents as you make one is the constructor. Write new Person("Yui", 15) and the constructor gets called, putting the values you handed over into that instance. This is where this shows up, pointing at "this very real thing, the one being made right now". this.name = name means "into the field called name on this real thing, put the value I caught". this is standoffish at first, but read it as "myself" and it gets much easier.
Next come methods. Functions written inside the class, doing something with that instance's data. This is the real value of a class: the data, and the work that handles that data, gather in one place. A person's information and the things you want to do to a person do not drift apart.
The second half of the chapter is inheritance, the machinery for basing a slightly different class on one you already have. There is an "animal" class, and you make a "dog" class from it. You do not rewrite the shared parts, only add the ones that differ. extends takes it over, and super calls the original class's work. Write a method of the same name and you can override the original behaviour.
A class is also the sum of everything the chapters so far taught you. You cannot put one together without variables, functions and objects; and once you do have those, you can see that a class is only those things with "rules for gathering them" added.
Inheritance has an overuse trap in it, too. It is safest used only where you can say "an A is a kind of B" and mean it. "A dog is a kind of animal" holds up; join two things because "they happen to have similar work in them" and fixing one starts breaking the other. Inheritance is not a tool for sharing code, it is a tool for expressing a relationship — keep that in mind.
The thing you are most likely to stumble on in this chapter is, again, this. The same this points at different things depending on where you wrote it. Inside a constructor it means "the real thing being made right now"; inside a method, "the real thing that called that method". When you get muddled, say out loud whose business you are talking about.
One more thing that matters: do not confuse the class with the instance. A class is a mould; there are no concrete values in it. Values live in the real thing you made with new. Mix those two up and you can spend a long time wondering "why can't I get the value out".
As you work through the chapter, try writing the blueprint on paper or in a note first. Put "what fields does this class hold" and "what can it do" into words before you drop it into code. Start writing straight away and you tend to notice halfway that a field is missing, and rewrite it several times.
One note: plenty of real development is written without classes. Even so, they certainly turn up in other people's code, and the idea itself — gathering data and work into one thing — carries over into designs that use no classes at all. There is plenty of point in being able to read them.
Lessons in this chapter
The blueprint and the real thing
- 50Objects, one more timeRemember the shape that holds information as name-and-value pairs. No new grammar here; this one is for getting the feel back.Go to the exercises
- 51A class is a blueprint for one shapeMeet the thinking and the writing behind the class, the blueprint for turning out objects of the same shape.Go to the exercises
- 52Making a real one from the blueprintBring a real one into being from a blueprint with
new, give it properties and read them back. That real one is called an instance.Go to the exercises
Set values up as you create
- 53Work that runs by itself as you make oneSee for yourself how a constructor written inside a class runs by itself every time you
new.Go to the exercises - 54Giving it contents with thisWrite
this.name = valueinside the constructor and have the properties ready the moment it is made.Go to the exercises - 55Handing values over as you make oneHave the constructor catch arguments and give each real one different contents.Go to the exercises
Give it behaviour
- 56Giving a class something it can doCall a method — a function written inside a class — from an instance.Go to the exercises
- 57Looking at your own contents from a methodWrite
this.propertyinside a method and use the values held by the very thing it was called on.Go to the exercises - 58Calling one method from anotherWrite
this.otherMethod()inside a method and put pieces of work together.Go to the exercises
Inherit, then change what differs
- 59Building on a class you already haveUse
extendsto make a new class that takes over the contents of one you already have.Go to the exercises - 60Using what you took overCall a method written on the parent class from an instance of the child class.Go to the exercises
- 61Adding something the child alone can doWrite a method of its own on the child class and give it behaviour the parent does not have.Go to the exercises
- 62Swapping out behaviour you took overRewrite a method of the same name on the child and change the behaviour for that child alone.Go to the exercises
- 63Calling the parent's work, then adding to itUse
super()when you rewrite a constructor on the child, andsuper.method()to call the parent's method.Go to the exercises