La INHERITANCE is a mechanism that allows the creation of new classes, based on existing classes. This facilitates code reuse and the organization of classes in hierarchies.
In this context “inherit” means that classes (or types) have some of the characteristics of the classes they inherit from. As in the biological sense 👪.
Inheritance: This child has inherited the same hair as his mother!
In programming, inheritance is a mechanism by which classes can copy attributes and methods from another class. We will call,
- Child class or subclass: The inheriting class
- Parent class or superclass: The class being inherited from
For example, if we have a class Animal
as a parent class, we could have child classes like Dog
, Cat
, Bird
, Cow
, etc.
In addition to copying the methods of the parent class, the child class can add new attributes or methods, or even overwrite the ones it inherits (if not, inheritance would not be very useful).
In this way, a child class can extend and specialize the behavior of the parent class. It copies part of the behavior, but adds “its own details” and customizations.
When to use inheritance
The most common way to identify that we have a case of INHERITANCE between classes is to detect that they share common code and we want to avoid copying it.
For example, imagine that we are working on the management system of a school. We have the class Person
class Person
{
string Name;
string Surname;
// many more things
}
Now we need the classes Student
, Teacher
, Tutor
, Principal
. But they all have Name
and Surname
. So, instead of copying it, we can make them inherit.
class Student extends Person
class Teacher extends Person
class Tutor extends Person
class Principal extends Person
Simply, with that, our four child classes Student
, Teacher
, Tutor
, Principal
have Name
and Surname
available, because they inherit them from Person
.
// type Student inherits from Person
class Student
{
// 👇 this has it, without needing to define it
// string Name;
// string Surname;
}
Indeed, avoiding repeating code is one of the main purposes of inheritance. Therefore, it is one of the first indicators that we may have a case of inheritance.
But, the thing is much more interesting. The real reason to use inheritance is to identify that we have a specification of the parent class. A specification is a more concrete case of a concept.
That is, Person
is a broader concept than Student
or Teacher
. These students and teachers are specific cases of people, but they ARE people.
Inheritance is a relationship where the child class is a more specific version of the parent class. You can detect it if you can construct a phrase that contains “is a”.
For example:
- A teacher is a person
- A bird is an animal
- A car is a vehicle
- A shoe is a product
Example of Inheritance in different languages
Let’s see how the syntax would be for inheritance between classes in different programming languages.
Imagine that you have to draw geometric shapes on a 2D video game monitor. For that we have a parent class Shape
. From it inherit Rectangle
, Circle
and Triangle
.
In C#, inheritance is achieved using the symbol :
. When a class inherits from another, the child class acquires all the fields and methods of the parent class.
// parent class
class Shape
{
public Point2D Position;
public int Rotation;
public int Width;
public int Height;
}
// child classes that inherit
class Rectangle : Shape { }
class Circle : Shape { }
class Triangle : Shape { }
In C++, inheritance is implemented using the public
keyword followed by :
. This public inheritance relationship allows the public members of the base class to be accessible in the derived class.
// parent class
class Shape
{
public:
Point2D Position;
int Rotation;
int Width;
int Height;
};
// child classes that inherit
class Rectangle : public Shape {};
class Circle : public Shape {};
class Triangle : public Shape {};
In JavaScript, inheritance is achieved using the extends
keyword, which allows a child class to inherit from a parent class.
// parent class
class Shape {
constructor() {
this.Position = new Point2D();
this.Rotation = 0;
this.Width = 0;
this.Height = 0;
}
}
// child classes that inherit
class Rectangle extends Shape { }
class Circle extends Shape { }
class Triangle extends Shape { }
In Python, inheritance is achieved by placing the name of the base class in parentheses after the name of the child class. This indicates that the child class inherits from the base class.
Because Python is like that and you have to love it as it is (I suppose).
# parent class
class Shape:
def __init__(self):
self.Position = Point2D()
self.Rotation = 0
self.Width = 0
self.Height = 0
# child classes that inherit
class Rectangle(Shape):
class Circle(Shape):
class Triangle(Shape):
In all these examples, the child classes Rectangle
, Circle
and Triangle
have all the attributes and methods of the parent class Shape
because they inherit from it.
Where does inheritance come from?
Why was the concept of INHERITANCE invented, as a fundamental part of Object-Oriented Programming. Let’s go back to basics once again, and remember that at that time, it was already normal to have groups of variables that abstracted concepts.
However, anyone could come and modify anything. Basically you could have an object Shape
, and by changing shapes make it work for a rectangle, a circle or a triangle.
But we already said that this led to unmaintainable messes. That is why Object-Oriented Programming puts ENCAPSULATION as one of its pillars. With this, no one could come and modify an object.
They had “shielded” the OBJECTS, they could no longer be modified as before. Now you necessarily had to repeat the code for Rectangle
, Circle
and Triangle
, each with all the entire code. It wasn’t very desirable either.
For that reason, INHERITANCE was invented. To allow a mechanism that allowed us to reuse code between classes, so that it would not have to be copied over and over again.
But, this time, doing it in a regulated and controlled way, corresponding to a relationship of kinship.