Understanding Inheritance in Python, JavaScript, and Go

DSL
6 min readJan 1, 2023

--

credit by DALL.E by openAI

Inheritance is a way to make a new class that is based on modifying an existing class. The new class is called a subclass, and the existing class is the super-class. The subclass is a child of the super-class and it inherits from the parent’s attributes and behaviors, at the same time, it also can have attributes and behaviors of its own.

Inheritance is a common feature in OOP languages, and it can be implemented in Python, JavaScript, and Go. However, the way inheritance works and the extent to which it is supported can be very different between languages.

Python

In Python, inheritance is implemented using a simple syntax. A subclass can inherit from a super-class by specifying the super-class in parentheses after the subclass name. Python also supports multiple inheritance, where a subclass can inherit from multiple super-classes.

class Animal:
def __init__(self, name, species):
self.name = name
self.species = species

def make_sound(self):
print("Make some generic animal sound")

class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name, species="Dog")
self.breed = breed

def make_sound(self):
print("Woof!")

dog = Dog("Blanco", "Labrador")
print(dog.name)
print(dog.species)
print(dog.breed)
dog.make_sound()

From the code above, the Animal class has two attributes: name and species, and a method called make_sound and the __init__ is used to initialize the object's attributes.

The Dog class is a subclass of the Animal class. It inherits the name and species attributes and the make_sound method from the Animal class. The Dog class also has an additional attribute called breed, and it has its own version of the make_sound method which overrides the original one from Ainimal class.

Finally, the code creates an object of the Dog class called dog and sets its name, species, and breed attributes. It then prints the values of these attributes and calls the make_sound method on the dog object.

JavaScript

In JavaScript, inheritance can be implemented using the prototype chain and function or using ES6 class syntax. Let’s explore the first approach first, every object in JavaScript has a prototype, which is another object that it can inherit properties from. An object can inherit properties from its prototype, and its prototype can inherit properties from its prototype, and so on, forming a prototype chain.

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

Animal.prototype.makeSound = function() {
console.log("Make some generic animal sound");
}

function Dog(name, breed) {
Animal.call(this, name, "Dog");
this.breed = breed;
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.makeSound = function() {
console.log("Woof!");
}

const dog = new Dog("Blanco", "Labrador");
console.log(dog.name);
console.log(dog.species);
console.log(dog.breed);
dog.makeSound();

In this code, the Animal and Dog functions are used to define the classes. The Animal function has two arguments: name and species, and it has a method called makeSound.

The Dog function is a subclass of the Animal function. It uses the call method to call the Animal function and set the name and species properties of the Dog object. It also has its own breed property.

To override the makeSound method of the Animal class, the Dog class sets its own makeSound method on its prototype. It does this by creating a new object that inherits from the Animal prototype, and then setting this object as the prototype for the Dog function. This is called the prototype chain.

Finally, the code creates an object of the Dog class called dog and sets its name, species, and breed properties. It then prints the values of these properties and calls the makeSound method on the dog object.

The same code can be implemented in ES6 class syntax, which looks more closely related the typical OOP class and constructor pattern. But this approach is just “syntactic sugar”, under the hood, it’s using the same prototype mechanism.

class Animal {
constructor(name, species) {
this.name = name;
this.species = species;
}

makeSound() {
console.log("Make some generic animal sound");
}
}

class Dog extends Animal {
constructor(name, breed) {
super(name, "Dog");
this.breed = breed;
}

makeSound() {
console.log("Woof!");
}
}

const dog = new Dog("Blanco", "Labrador");
console.log(dog.name);
console.log(dog.species);
console.log(dog.breed);
dog.makeSound();

In this code, the Animal and Dog classes are defined using the ES6 class syntax. The Animal class has a constructor method that is used to initialize the object's properties, and a makeSound method.

The Dog class is a subclass of the Animal class. It has its own constructor method that calls the constructor method of the Animal class using the super keyword. It also has its own version of the makeSound method that overrides the makeSound method of the Animal class.

Finally, the code creates an object of the Dog class called dog and sets its name, species, and breed properties. It then prints the values of these properties and calls the makeSound method on the dog object.

Both approaches can be used to achieve the same results in terms of inheritance and method overriding, but the ES6 class syntax can be easier to read and write, especially for developers who are familiar with other object-oriented languages.

Overall, the choice of which approach to use will depend on the specific needs of your project and the preferences of the developers working on it.

GO

In Go, inheritance is not directly supported. Instead, Go has a concept called composition, where a struct can contain one or more fields that are themselves structs. The contained structs can have their own fields and methods, and the containing struct can access them through its fields. This allows for a similar kind of code reuse and organization as inheritance, but in a more flexible and modular way.

type Animal struct {
name string
species string
}

func (a *Animal) MakeSound() {
fmt.Println("Make some generic animal sound")
}

type Dog struct {
Animal
breed string
}

func (d *Dog) MakeSound() {
fmt.Println("Woof!")
}

func main() {
dog := &Dog{
Animal: Animal{name: "Blanco", species: "Dog"},
breed: "Labrador",
}
fmt.Println(dog.name)
fmt.Println(dog.species)
fmt.Println(dog.breed)
dog.MakeSound()
}

In this code, the Animal struct represents the super-class, and the Dog struct represents the subclass. The Dog struct contains an Animal field, which allows it to access the fields and methods of the Animal struct.

The Dog struct also has its own version of the MakeSound method, which overrides the MakeSound method of the Animal struct.

Finally, the code creates a pointer to a Dog struct called dog and sets its name, species, and breed fields. It then prints the values of these fields and calls the MakeSound method on the dog struct.

Overall, this code demonstrates how composition can be used in Go to achieve a similar effect as inheritance, allowing for code reuse and organization in a flexible and modular way.

Conclusion

In conclusion, inheritance is a common feature in object-oriented programming languages that allows a subclass to inherit attributes and behaviors from a super-class. It can be a useful way to reuse code and structure your classes, but it can also make your code more complex and harder to understand if overused or used improperly.

Python, JavaScript, and Go all support inheritance, but the way it is implemented and the extent to which it is supported can vary between languages. Python has a simple syntax for inheritance and supports multiple inheritance, while JavaScript uses the prototype chain to implement inheritance. Go does not directly support inheritance, but it has a concept called “composition that allows a struct to contain other structs and access their fields and methods, providing a similar kind of code reuse and organization as inheritance.

I hope this article helps you, it documents my journey of learning Go while reviewing the concept of inheritance in both Python and JavaScript. If you find any error or mistake please kindly point them out and I will be happy to modify, improve and learn from you. If you like my post please subscribe and also follow me on Twitter.

--

--

DSL

Sr software engineer. Love in Go, JavaScript, Python, and serverless AWS. Follow me for tech insights and experiences. follow me on twitter @terraformia