What is Inheritance in Object-Oriented Programming?

1 year ago 342
ARTICLE AD

Inheritance is one of the core features of object-oriented programming. It’s a programming procedure that allows you to reuse code by referencing the behaviors and data of an object. In other words, a class that inherits from another class shares all the attributes and methods of the referenced class.

An inherited class is called a subclass or child class of the class it inherits from. And the class being inherited is called either a parent class, superclass, or base class.

Some languages, like Go, are object-oriented but use composition instead of inheritance. Composition is an alternative approach that creates new complex objects by aggregating other objects. Most object-oriented programming languages have both composition and inheritance.

Ahead, we’ll take a closer look at how inheritance comes in handy, the many types of inheritance you can implement, and other important details you’ll need to know.

How inheritance makes development easier

Inheritance is a core element of object-oriented programming that serves as a powerful instrument for reusing code. Let’s use an example to illustrate how using inheritance can make creating an application easier.

Say you’re designing a video game with vehicles you can drive. You want to create a lot of vehicles that people can use, including coupes, sedans, trucks, four-wheel-drive vehicles, and maybe even some airplanes.

If you’re already somewhat familiar with object-oriented programming, you might consider making all of these vehicles as objects. You could create a class for each of the types of vehicles you want and encapsulate all the functionality and data necessary for that vehicle in the class.

So you start by creating a class for a simple car. Let’s use Python for our examples. Python is a general-purpose programming language that is used for all types of projects, including data science, machine learning, web development, desktop application development, and scripting. It supports procedural and functional programming styles, as well as object-oriented programming. But back to the simple car class.

class Car:  def init(self):  self.wheels = 4  def drive(self, direction):  print('car will drive ' + direction)

Of course, the class for Car could have many more attributes and methods than this, but you get the idea. But what if you wanted something a bit more creative — like a car with arms that could throw turtle shells or bananas (à la Mario Kart). You can add a throw method to the car class, but if a user has a car without arms, that wouldn’t apply.

You could try creating a copy of this class, renaming it, and adding all the methods and attributes — but if you planned on creating dozens of vehicles, that would take a lot of work. And if you changed one of the basic methods or attributes that affects all of your vehicles, you’d have to modify each one of these objects.

This is exactly where inheritance can help. Instead of copying the class and adding new things to it, you can create a new class that inherits from a base class. So for a car with arms, we could create a class like this:

class ArmedCar(Car):  def throw(self, direction): print('car will throw to the ' + direction)

By inheriting from the base class of Car, you still get all the base functionality you need and you can add a throw method without affecting the original class. And if you ever want to change any of the base methods or attributes, you can do that in the base class and all of the child classes will be updated. Now let’s see how far we can take this concept by looking at the types of inheritance.

Types of inheritance

Many modern programming languages support the object-oriented programming paradigm, including JavaScript, Python, Java, PHP, C#, C++, Swift, and Ruby. Each of these languages handles inheritance slightly differently using different syntax, but most of the concepts remain the same. Not all languages support every one of these types of inheritance, but Python does.

Single inheritance

In single inheritance, one class inherits from only one parent class. This is also called simple inheritance because it’s the simplest type of inheritance you can use.

class Vehicle:  def move(self):  print('method to move vehicle called')  class Motorcycle(Vehicle):  def use_kickstand(self):  print('method to use motorcycle kickstand called')  motorcycle1 = Motorcycle()  motorcycle1.move() # Prints "method to move vehicle called"  motorcycle1.use_kickstand() # Prints "method to use motorcycle kickstand called"

The Motorcycle class inherits from the Vehicle class because it’s a type of vehicle and can use all the methods and class variables of the Vehicle class. This is the same type of inheritance we used in the first example.

Multiple inheritance

In Python and a lot of the other object-oriented programming languages, you can also create a class that inherits from more than one class. Here’s an example of multiple inheritance using animal traits:

class Animal:  def breathe(self):  print('breathe in and out')  class Vertebrate:  def bend_spine(self): print('bending spine')  class Dog(Animal, Vertebrate):  def pant(self):  print('cooling off')     dog1 = Dog() dog1.breathe() # Prints "breathe in and out"  dog1.bend_spine() # Prints "bending spine"  dog1.pant() # Prints "cooling off"

Multiple inheritance allows us to build up a class by inheriting from many classes.

Multilevel inheritance

In multilevel inheritance, one class inherits from another class, which inherits from yet another class, and on and on. Instead of using multiple inheritance for the Dog class from above, we could use multilevel inheritance.

class Animal:  def breathe(self): print('breathe in and out')  class Vertebrate(Animal):  def bend_spine(self):  print('bending spine')  class Dog(Vertebrate):  def pant(self): print('cooling off')    dog1 = Dog()    dog1.breathe() # Prints "breathe in and out"    dog1.bend_spine() # Prints "bending spine"    dog1.pant() # Prints "cooling off"

The results are the same for our simple case, but with more complex classes, one of the other types of inheritance will be more effective.

Hierarchical inheritance

In hierarchical inheritance, child classes all inherit from a single base class. It’s basically the same as single inheritance, except you’re creating more child classes. Going back to our video game example:

class Vehicle:  def move(self): print('method to move vehicle called')  class Motorcycle(Vehicle):  def use_kickstand(self): print('method to use motorcycle kickstand called') class Skateboard(Vehicle):  def ollie(self): print('method to do an ollie called')  motorcycle1 = Motorcycle()  skateboard1 = Skateboard()  motorcycle1.move() # Prints "method to move vehicle called"  motorcycle1.use_kickstand() # Prints "method to use motorcycle  kickstand called" motorcycle1.ollie() # This will throw an error skateboard1.move() # Prints "method to move vehicle called"  skateboard1.ollie() # Prints "method to do an ollie called"  skateboard1.use_kickstand() # This will throw an error

Using hierarchical inheritance, each child class has all the functionality and data of the base class and also custom attributes and methods that apply only to that specific child class.

Hybrid inheritance

Hybrid inheritance involves using more than one of the other types of inheritance. When you know inheritance well and work on complex applications, chances are that this is the type of inheritance you will use most often to get the results you want.

class Vehicle:  def move(self):  print('method to move vehicle called')  class Motorcycle(Vehicle):  def use_kickstand(self):  print('method to use motorcycle kickstand called')  class Racing:  def go_fast(self):  print('method to go fast called')  class RacingMotorcycle(Motorcycle, Racing):  def win_cup(self):  print('method to win cup called')

Access modifiers and inheritance

Object-oriented languages that use inheritance usually have a concept called access modifiers, which restrict access to variables and methods in a class. So while a child class inherits from a base class, you can limit the child class’ access to specific methods and variables in the base class. You can also limit access to these by using code outside of the class. Most object-oriented languages have three forms of access modifiers.

Public

These variables and methods can be accessed from anywhere in your application, whether it’s running inside or outside of the class. In Python, class methods and variables are public by default. In the examples above, all the methods and classes were public. Some of the other object-oriented programming languages have class methods and variables public by default. Others require using the public keyword before the method or variable, like in Java.

public class Car { public int wheels; public move() { } }

Protected

Protected variables can only be accessed by a class (or classes) that inherit from it. In Python, you can make a variable or method protected by putting an underscore before the name. Many other languages use a protected keyword similar to the private keyword Java example above.

class Car:  def init(self):  self._wheels = 4  def _drive(self, direction):   print('car will drive ' + direction)

Both the variable wheels and the method drive are protected. If Car is only going to be a base class and you’ll only use child classes to create objects, this makes sense.

Private

Private variables and methods are not intended to be accessed in the class. They can’t even be accessed by child classes. In Python, you can make a variable or method private by adding a double underscore to the front of its name. In most other languages, you have to use a private keyword.

class Car:  def init(self):  self.__wheels = 4  def __drive(self, direction):  print('car will drive ' + direction)

In the code above, the variable wheels and the method drive are private. Note that the notation of protected and private variables is really more of a convention to highlight how a given object should be used. The use of underscores doesn’t really offer any security, ultimately any of these can be overridden.

Overriding and inheritance

When you’re creating a child class in most object-oriented programming languages, you also have the option to override the variables of a parent class in the child class. Below, the Vehicle class moves on the ground and the Helicopter class overrides the move method by flying in the air. The wheels variable also gets overridden in the child classes.

class Vehicle:  def init(self):  self.wheels = 4  def move(self):  print('move on the ground')  class Motorcycle(Vehicle):  def init(self):  self.wheels = 2  class Helicopter(Vehicle):  def init(self):  self.wheels = 0  def move(self):  print('take to the air')  motorcycle1 = Motorcycle()  motorcycle1.wheels # Prints "2"  motorcycle1.move() # Prints "move on the ground"  helicopter1 = Helicopter()  helicopter1.wheels # Prints "0"  helicopter1.move() # Prints "take to the air"

Learn more about inheritance

Inheritance can make object-oriented coding easier by adding a lot of flexibility to how you create objects and by giving you the ability to reuse your code. While this article gives you an overview of how inheritance works, it’s best to learn it in practice to see all the power it can bring to your coding projects.We have courses on object-oriented programming languages that will teach you inheritance, including Learn Python 3 and Learn JavaScript. And for a deep dive into inheritance, check out Java: Inheritance and Polymorphism.

Subscribe for news, tips, and more

Read Entire Article