DEV Community

Cover image for Classical vs Prototypal Inheritance
Christine Garaudy
Christine Garaudy

Posted on

Classical vs Prototypal Inheritance

Inheritance is an important concept in all object-oriented programming languages. Inheritance methods create reusable and DRY (don't repeat yourself) code, which is quicker to write, easier to maintain over time, and quicker to run. The idea is to create a class or a primary object that passes down or shares its properties and methods to subsequent related objects, thereby reducing the amount of code to write each time a new object is made. The new objects can have additional characteristics the original object or class does not, but they will all share the original properties. This also makes for more readable code, as it will be immediately clear what the relationship between the objects are.

There are two main types of inheritance patterns- classical and prototypal. Most programming languages follow the classical pattern, including Simula (which was the first object-oriented language), Java, C++, C#, Ruby. Class-based languages usually have somewhat rigid inheritance rules and go from the top down, beginning with a general idea and moving toward specifics. Prototypal inheritance is more flexible and can move in either direction. The most commonly used prototype-based programming language is JavaScript, which was greatly influenced by Self, the first language to use prototypal inheritance.

With prototypal inheritance, new objects are direct clones of the original. They can have additional properties the original prototype did not have, and any property or method lookup not found on the new object will fall through to the prototype. In classical inheritance models, the new instances are instantiated through a more complicated process involving the interpretation of the blueprint of the parent.


//Java

class Animal {
  private name;
  public Animal(String name) {
    this.name = name;
  }
  public String getName() {
    return this.name;
  }
}

class Cat extends Animal {

}

Cat cat = new Cat("Fluffykins");

JavaScript uses its built-in prototype chain to link the Constructor.prototype of the child directly to the Constructor.prototype of the parent, resulting in a tightly-coupled single-ancestor parent-child hierarchy that some prefer to describe as “behavior delegation” rather than true inheritance.


//JavaScript

function Animal(name) {
  this.name = name;
}

Animal.prototype.getName() {
  return this.name;
}

function Cat(name) {
  Animal.call(this, name);
}

Cat.prototype = Object.create(Animal.prototype);

const cat = new Cat("Fluffykins");

JavaScript's prototypal inheritance model can be strange and confusing for programmers coming from a background of class-based language experience, so the class keyword was introduced to JS as a major update of ES6. Now, we would write the code above like this:


//JavaScript ES6

class Animal {
  constructor(name) {
    this.name = name;
  }
  getName() {
    return this.name;
  }
}

class Cat extends Animal {

}

const cat = new Cat("Fluffykins");

This new class syntax does not change the way objects inherit, but is simply syntactic sugar that obscures the process going on under the hood, making it look similar to other languages.

Here are the main takeaways:

1) In class-based languages like Java, a class is like an architectural plan all future objects will follow, like a template or a blueprint with directions.

2) In prototypal inheritance as in JavaScript, the prototype is itself an object from which new objects will inherit properties directly.

For example, in class-based languages Java and C++, classes only exist when the code is compiled, and the inheritance occurs then, at compile time, statically. With JavaScript's prototypal inheritance model, any object can be extended to allow access to its properties, creating a new object. This new object can do the same, creating a dynamic chain of objects at runtime.

The addition of the class keyword in ES6 has resulted in JavaScript having a sort of split personality regarding inheritance, so it's useful to have a basic understanding of both classical and prototypal inheritance models to see what's really going on behind the scenes, particularly for developers coming to JavaScript from other languages.

Top comments (0)