Classes: Constructors, Inheritance, Super

Classes: Constructors, Inheritance, Super
namecheap placeholder image

Classes in JavaScript provide a blueprint for the creation of objects. This means that once you define a class (including its member variables and methods), you can endlessly create new objects from it. This is useful because it allows us to reduce the amount of code we need to write when we want multiple objects that are similar to one another.

Defining a Class

Defining a class in JavaScript is simple thanks to the built-in class keyword. Let's say we run a pet store and want a JavaScript object to represent each pet. Thus, we create a Pet class.

	
    class Pet {

    }
    var pet = new Pet();
    console.log(pet);
	
	
    Pet {}
	

We have created a new Pet object using our defined class, assigned it to the pet variable, and printed it out.

But let's make Pet useful.

Constructing a Class

How you construct a class is just going to depend on what you need the class to do. In our case, since they represent a pet in a pet store, we should probably have variables for the pet's name, weight (in pounds) and price (in USD).

	
    class Pet {
        constructor(name, weight, price) {
            this.name = name;
            this.weight = weight;
            this.price = price;
        }

        getInfo() {
            return "Hi, my name is " + this.name + ". I weigh " + this.weight + " pounds and cost $" + this.price + ".";
        }
    }
    var pet = new Pet("Fluffy", 20, 200);
    console.log(pet);
    console.log(pet.getInfo());
	
	
    Pet {
        name: "Fluffy",
        weight: 20,
        price: 200
    }
    Hi, my name is Fluffy. I weigh 20 pounds and cost $200.
	

In this case, we are using the constructor keyword. You can think of constructor as just a special function that asks for the data required to create a new object out of the class. Since we want every pet to have a name, weight and price, we are specifying that in our constructor.

If you noticed, we also defined a getInfo function that simply returns back a user-friendly string that describes the pet.

As mentioned before, the cool thing about classes is that you no longer need to define multiple objects but instead can use one common class. Look how easy it would be to define three different pets:

	
    class Pet {
        constructor(name, weight, price) {
            this.name = name;
            this.weight = weight;
            this.price = price;
        }

        getInfo() {
            return "Hi, my name is " + this.name + ". I weigh " + this.weight + " pounds and cost $" + this.price + ".";
        }
    }

    var pet1 = new Pet("Oreo", 15, 300);
    console.log(pet1.getInfo());

    var pet2 = new Pet("Dashy", 25, 400);
    console.log(pet2.getInfo());

    var pet3 = new Pet("Ninja", 20, 350);
    console.log(pet3.getInfo());
	
	
    Hi, my name is Oreo. I weigh 15 pounds and cost $300.
    Hi, my name is Dashy. I weigh 25 pounds and cost $400.
    Hi, my name is Ninja. I weigh 20 pounds and cost $350.
	
namecheap placeholder image

Class Inheritance

While our current solution works for now, it can certainly be improved upon. Our Pet class doesn't offer any distinction between a cat or a dog, which each would have additional information that doesn't apply to the other. Luckily for us, JavaScript offers class inheritance, which means we can create new classes that inherit everything from another, but adds unique information for itself.

This means that since a dog is still a pet, we can just inherit from the Pet class and add any dog-specific stuff in the Dog class. To keep things basic, let's add the ability to bark if it's a dog.

	
    class Dog extends Pet {
        bark() {
            console.log("BARK BARK BARK");
        }
    }

    var dog = new Dog("Cooper", 20, 200);
    console.log(dog.getInfo());

    dog.bark();
	
	
    Hi, my name is Cooper. I weigh 20 pounds and cost $200.
    BARK BARK BARK
	

We created a new Dog, but since it is still a pet because we inherited from the Pet class, it was able to both bark, something only dogs can do, but also return back info thanks to the getInfo function, something any pet can do.

The information we passed to the Dog class is automatically passed to the Pet class which is how getInfo worked as expected.

Function Overriding and Super Keyword

To serve as an introduction to another useful JavaScript feature, let's create a Cat class. This time, we'll have all cats have a unique feature that they each have a favorite brand of cat food, and thus will need a string to keep track of that.

	
    class Cat extends Pet {
        constructor(name, weight, price, brand) {
            super(name, weight, price);
            this.brand = brand;
        }
        getFavoriteBrand() {
            return this.brand;
        }
        getInfo() {
            return "Hi, I'm a cat named " + this.name + " and I like " + this.brand +  ". I weigh " + this.weight + " pounds and cost $" + this.price + ".";
        }
    }

    var honey = new Cat("Honey", 15, 300, "Purina");
    console.log(honey.getInfo());
    console.log(honey.getFavoriteBrand());
	
	
    Hi, I'm a cat named Honey and I like Purina. I weigh 15 pounds and cost $300.
    Purina
	

A couple of very interesting things is happening here. First, in the constructor for Cat, you'll notice the super keyword. This is simply manually calling the constructor of the class that Cat is inheriting from, in this case, the Pet class. The only reason this is needed is because we added a new parameter to the constructor of Cat, and that is the brand string.

Since brand is unique to cats, we assign it under the super call.

The second interesting thing that is happening here is that we defined a getInfo function inside Cat, even though there is already one inside Pet. When we do this, we are overriding the function, which means that cats will use the one defined in Cat instead of Pet, which is what we want.

Classes in JavaScript are extremely useful and versatile, as these examples have hopefully shown. You can define base classes (the Pet class) and create an endless number of classes that inherit from it (the Dog and Cat classes) which have their own unique features and functionality only private to them, which still retaining the features and functionality available to all.

You could even go further and have different breeds of dogs and cats have their own classes that inherit from the Dog and Cat class!

Resources