Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Inheritance Example and Course Conclusion

In this lesson you’ll see more OOP inheritance examples. We’ll conclude this course with a recap of what you learned.

00:00 Welcome back to our series on object-oriented programming in Python. In the last video, we learned about the idea of inheritance, which allows us to define a child class that automatically inherits attributes and methods from its parent class.

00:15 Now, let’s see how inheritance works in action.

00:18 So, I’m here in Visual Studio Code, and the first thing we are going to do is define a new class called Person. I’ll say here description = "general person", which will be our only class attribute.

00:33 Now, I’ll create our initializer method, and I’ll give it parameters of name and age. As usual, we’ll set the instance attributes equal to these parameters.

00:46 Now, I want to define a few behaviors that every person will have. I’ll create a new instance method called .speak() with the only parameter being self, and I’ll make this print out "My name is {} and I am {} years old". Then to fill in those gaps,

01:04 I’ll use the .format() function and I’ll pass in self.name and self.age as arguments. Next, I want our person to be able to eat whatever food we give them.

01:14 So I’ll say here def eat(self, food):,

01:21 and then I’ll print out "{} eats {}"

01:25 and to fill in those blanks ({}), we’ll pass in self.name as well as our food parameter.

01:32 Lastly, let’s give our person the ability to perform an action. So, I’ll create one last instance method called .action(), and when that’s called, I’ll say "{} jumps" and I’ll pass in self.name to fill in the blank.

01:49 All right. So now that we’ve got our general Person class, let’s create a subclass called Baby. To do this, I’ll type class Baby, just like before, but then I’ll put in some parentheses (()). Inside of these parentheses, we need to specify what the parent class of Baby will be, so we’ll type in Person. And now, technically, if I write pass in the class body, then our Baby will be usable but they’ll do the exact same thing as a Person would, so we want to change that. First, I’ll redefine our .description class attribute.

02:24 I’ll set it equal to something like "baby"—that should work. This redefining here is called overriding because any Baby object we create, will use this specific .description instead of the .description inherited automatically from the Person class. To do this, I’ll type def speak() with self as the parameter, and then I’ll say print("ba ba ba ba ba"), which is just some baby gibberish I came up with. This way, when we call the .speak() method on a Baby, it will say this gibberish instead of whatever the Parent class would have said. Lastly, I want to give this Baby some exclusive functionality.

03:06 Let’s give the baby the ability to nap whenever it wants, I’ll say def nap(), with a parameter of self, and then I’ll write print("{} takes a nap"), and in place of the blank I’ll say self.name. Now, any specific Baby object we create will have the ability to nap, but a more general Person object will not.

03:29 All we have to do is instantiate these classes and put them to work. I’ll create a new Person object called person, and he will have a name of "Steve" and an age of 20.

03:41 Then, I want to call all of the instance methods of the person, so I’ll type person.speak() and person.eat()and we’ll give him "pasta"—and finally, person.action() to see him jump.

03:58 Now, let’s create a Baby object called baby. So, I’ll type baby = Baby(). And take a look at this: Visual Studio is telling

04:07 me that I need to supply a name and an age to the initializer for Baby, but if you look, Baby doesn’t actually have an initializer. That’s because it automatically inherited it from the Person class.

04:21 Remember, this Baby is also considered a Person and as such, it needs to fill out the instance attributes of the Person as well.

04:29 So we’ll give this Baby a name of "Ian" and an age of 1. Then, we’re going to call the same instance methods on our Baby object.

04:39 I’ll print out both the .description of our person and the .description of our baby. Before I run this, take a moment to pause the video and predict what the output will be.

04:51 So, I will right-click and choose Run Code and we get some console output.

04:57 We see: My name is Steve and I am 20 years old, Steve eats pasta, and Steve jumps. Then, for our Baby object, we see that the baby is speaking gibberish.

05:09 Finally, we can see that our Person object has a class attribute of general person, but our Baby object has a class attribute of baby.

05:19 This whole exercise shows us how we can define a child class, or a derived class, that automatically inherits everything from the parent class, or the base class.

05:28 We can override attributes and methods like .description and .speak(), and we can even extend our child class to add new functionality like we did with the .nap() method. Just to make this even clearer, I’m going to move to a new line and type person dot (.).

05:45 If you remember, the dot (.) is the access modifier, which allows us to access attributes and call methods on an object. Since this object is a Person, notice how IntelliSense doesn’t see the .nap() method.

05:58 That’s because it’s specific to the child class and as such, only child objects have it. However, if I delete this and I change this to baby and I hit dot (.), you can see that we have access to everything defined in the Person class, as well as the specific .nap() method.

06:17 But now, what if we’re told we need to make a change to the .action() method? Maybe now we want both people to spin around instead of jumping.

06:26 Rather than having to modify code in several different classes, all we have to do now is change the word "jumps" to the word "spins" in our Person class. Now, if we run this code, you’ll notice that both Steve and Ian are spinning instead of jumping, and we didn’t have to make a single modification to the Baby class.

06:45 This is one of the reasons why inheritance is so powerful. Remember how earlier I said that behind the scenes, Python sees every object as the type object? Well, now that we have our classes coded, I can show you that that’s true. To prove that Baby is a Person, I’ll print out the result of this special function called isinstance().

07:08 This function will tell us if a specific object is of a specific type. This function takes two arguments, so I will pass in the baby object for the first, and I want to check if the baby object is an instance of Person.

07:23 If I run the code here, you’ll see that on the right side we see True, and that’s because a baby is a person: the baby object is of type Baby, but also of type Person because it inherits everything from the Person class.

07:38 Now, let’s see if our baby object is of type object. I’ll change the word Person here to lowercase object, and if we run this code, we will see that our baby is in fact an object. That’s because Baby is a Person, and Person inherits from object. Therefore, Baby inherits from object, too.

07:59 Like I mentioned before, every class in Python inherits from object, and we actually don’t even have to write that inside of the class declaration.

08:07 The reason for the object class even existing is beyond the scope of this tutorial, but for now, just know that our Baby objects are technically seen as a Baby, a Person, and an object.

08:21 And that is a somewhat brief introduction to inheritance. We didn’t cover everything, but this gives you the general gist of how inheritance works. As you can see, inheritance can be extremely beneficial, but if it’s not used correctly, it can be more of a headache than anything else.

08:39 There’s nothing inherently wrong with duplicating code across classes—and in fact, Python won’t even stop you from doing that—but it’s often a good idea to evaluate your classes for is a relationships and then implement inheritance where it makes sense. Remember, Python emphasizes readability and maintainability over having as few lines of code as possible. If it makes more sense for you not to use inheritance, don’t do it. You can always implement it later on, but at that point, it might be more difficult.

09:13 Inheritance is one of the fundamental pillars of object-oriented programming, but it’s not the only one. And there’s even more to inheritance that we didn’t cover here, but this tutorial is focused more on the fundamental principles of OOP rather than any specific features like inheritance, polymorphism, or encapsulation.

09:35 OOP is a huge topic and it’s hard to master, but hopefully now you have at least a basic appreciation for how large software is designed with classes and objects. In my opinion, programming becomes a lot more fun with an understanding of OOP, because you can move beyond writing trivial programs—like a number-guessing game—and move on to writing real software, using frameworks and libraries like Django and matplotlib, both of which we have tutorials for on our website.

10:05 I’m Austin Cepalia with realpython.com, and I wish you the best of luck in your future programming endeavors. Happy coding!

Thanks. Well paced and a nicely gentle introduction to OOP. At least it is gentle if you already have the basic concepts and are treating this as a refresher :-)

Avatar image for Jordan Rowland

Jordan Rowland on March 23, 2019

Great videos. I found my understanding of OOP was really solidified when working with SQLAlchemy for a Flask project, and having Post and User classes.

Avatar image for Aditya Mahapatra

Aditya Mahapatra on March 24, 2019

Will you be doing a follow-up series which delves into multiple inheritance, encapsulation and polymorphism? I hope you do! Good job on the intro to OOP :)

Avatar image for Sohil

Sohil on March 26, 2019

Very good intro to OOP in python.

Avatar image for Vincenzo Fiorentini

Vincenzo Fiorentini on March 27, 2019

Very good intro even for a complete beginner. Sweet and to the point !

Avatar image for DaveCarlson

DaveCarlson on March 27, 2019

This was well presented and helpfu. Thanks!

Avatar image for Edgar Isai

Edgar Isai on March 30, 2019

Really good introductions, i got all the concepts, its easy to follow. Thanks.

Avatar image for Kyle

Kyle on May 6, 2019

Very good introduction!

Avatar image for terrymiddleton

terrymiddleton on May 20, 2019

excellent intro.

Avatar image for elmorem

elmorem on July 29, 2019

I would love to see another series of videos that explains the next level of complexity. How about a series explaining some of the fundamental ‘dunder’ methods? Videos were clear and concise. very … pythonic.

Avatar image for marktripney

marktripney on Aug. 14, 2019

Very good - thanks! I’ve been using classes without really having a good understanding of them. This course helped a great deal.

Avatar image for sspwin

sspwin on Aug. 29, 2019

Good one…can you please cover session 2 on Abstraction, encapsulation and polymorphism and some advance topics on OOPs. Thank you.

Avatar image for Jean Ferreira

Jean Ferreira on Sept. 5, 2019

Very good videos. I started learning the concepts of OOP programming at university, but I needed a more visual way to understand the concepts. Thanks!

Avatar image for malcolmgandrews

malcolmgandrews on Oct. 1, 2019

Nice series of tutorials, great pace and clarity.

Avatar image for eduartef

eduartef on Nov. 10, 2019

Thank you so much, really helpful for beginners.

Avatar image for fjavanderspek

fjavanderspek on Nov. 25, 2019

Great course, clear and concise, with poignant examples! 10/10 honestly, wouldn’t know what to improve

Avatar image for projnabrataseth07

projnabrataseth07 on Nov. 26, 2019

Indeed a superb explanation .

Avatar image for Silver

Silver on Dec. 7, 2019

Awesome intro!

Avatar image for Dev

Dev on Dec. 7, 2019

Very easy to follow. Keep up the great work.

Avatar image for profbiyi

profbiyi on Dec. 10, 2019

Thanks for this. I so much love this.

Very neat and simplified,thanks

Avatar image for Pucho

Pucho on Jan. 6, 2020

5 stars

Avatar image for tsusadivyago

tsusadivyago on Jan. 6, 2020

finally I understood classes

Avatar image for mnemonic6502

mnemonic6502 on Jan. 18, 2020

Despite some nitpicking on mental example context switching and some assumptions made in explanations, this was a better tutorial than most for general consumption on youtube!

Yes, would definitely like to see expanded OOP tutorials moving forwards, in particular passing data dynamically into objects.

Avatar image for chuahengwee

chuahengwee on Jan. 22, 2020

really good…tks for the great content

Avatar image for swapnilc17

swapnilc17 on Feb. 9, 2020

Nice introduction to OOPS

Avatar image for Thomas

Thomas on Feb. 13, 2020

Awesome, I like your enthusiasm

Avatar image for Lokman

Lokman on Feb. 28, 2020

Hi @Austin Cepalia, since class Baby inherit class Person. Why init(self) doesn’t show result to Child class same as Parent class?

>>> I am Steve and 7 years old. # class Person
>>> I am Ian and 1 years old. # class Baby(Person)

Thanks for the video tutorial, I get already the concept and need to practice more about OOP.

Avatar image for horacionesman

horacionesman on March 15, 2020

I have been trying to understand OOP for a while and this is the first tutorial in which I’ve started feeling I know what is all about! Thanks!

Avatar image for markthiele

markthiele on March 17, 2020


Avatar image for koellingh

koellingh on March 28, 2020

I am trying to write a class that takes in an instance of another class in the constructor method. For context, here is how I am trying to do this:

class Family: def init(self, lastname, member_count, hair_color): self.lastname = lastname self.member_count = member_count self.hair_color = hair_color

class Person(Family): def init(self, Family(lastname, member_count, hair_color), name, gender, age): self.name = name self.gender = gender self.age = age self.Family() = Family()

I am getting an invalid syntax error pointed towards my Family instance variable in by Person constructor. How can I effectively pass in instance of a class as a constructor variable in another class?

Avatar image for koellingh

koellingh on March 28, 2020

Shoot, my code did not come in well. Here it is:

class Family:
    def __init__(self, lastname, member_count, hair_color):
        self.lastname = lastname
        self.member_count = member_count
        self.hair_color = hair_color

class Person(Family):
    def __init__(self, Family(lastname, member_count, hair_color), name, gender, age):
        self.Family() = Family()
        self.name = name
        self.gender = gender
        self.age = age
Avatar image for eshivaprasad

eshivaprasad on April 24, 2020

Thanks, Excellent introduction.

Avatar image for Aparna

Aparna on April 25, 2020

Excellent!! Crisp and simplistic way of explaining the most confusing terminologies

Avatar image for yanzaripov

yanzaripov on April 26, 2020

excellent stuff, thank you sir!

Avatar image for zbigniewsztobryn

zbigniewsztobryn on May 1, 2020

Its great how you picture parent and child class. Baby needs a nap(), brilliant! (: Well explained

Avatar image for Wiggers

Wiggers on May 1, 2020

Yes inhertance finally understood thank you

Avatar image for Timm Carson

Timm Carson on May 13, 2020

This was very helpful, thanks

Avatar image for sroux53

sroux53 on May 14, 2020


Avatar image for Robert T Paulsen

Robert T Paulsen on June 11, 2020

Thank You - this cleared up some basic understanding for me.

Avatar image for nihalsaRealPython

nihalsaRealPython on June 28, 2020

Excellent presentation with simple examples.

Avatar image for George Kiknadze

George Kiknadze on July 5, 2020

That was amazing introduction to OOP. Thanks 👍

Avatar image for Nemo the Coding Cat

Nemo the Coding Cat on July 7, 2020

Great video, it truly helps with my understanding! ^^ Thanks !

Avatar image for Brian Custer

Brian Custer on July 13, 2020

Great intro. I need to start designing classes for the project I am working on so it was good to get a quick intro. I would like to see more advanced topics discussed at some point.

Avatar image for Arnaud Tsombeng

Arnaud Tsombeng on July 17, 2020

Awasome tutorial on OOP

Avatar image for illapavankumar

illapavankumar on July 18, 2020

excellent.. can we get the slides of this topic(download)

Avatar image for Perryg

Perryg on July 22, 2020

Thank you for this series. I helped job my memory and review the concepts.

Very well done. I wish I had this back when I was in school.

Avatar image for Jason

Jason on July 22, 2020

Great explanation! Helped me to grasp the idea of inheritance.

Avatar image for Leah T

Leah T on July 22, 2020

This was just what I needed to solidify my understanding of OOP. As a new programmer it seemed so abstract and complicated, but here it was simple. Thanks!

Avatar image for alvesmig

alvesmig on July 22, 2020

Finally, I found a course which explained me OOP.

Avatar image for avalidzy

avalidzy on July 23, 2020

Excellent speaking voice and content presentation! Quite motivated now to move ahead with Object Oriented Programming. Apparently very versatile in building applications and website construction. :)

Avatar image for vikrant06

vikrant06 on Aug. 16, 2020


Avatar image for Julie Myers

Julie Myers on Aug. 19, 2020

Well done! The best intro, by far, I have found on OOP. Even better than the one I got from Univ of Michigan’s online class. You are the hard to find very good programming teacher.

Avatar image for acquatellamax

acquatellamax on Aug. 22, 2020

I finally see the light!

Avatar image for Austin Cepalia

Austin Cepalia RP Team on Aug. 22, 2020

@acquatellamax That’s how I felt too :)

Avatar image for abhijitchouhary01

abhijitchouhary01 on Aug. 23, 2020

Good Job!!

Avatar image for Ghani

Ghani on Oct. 7, 2020

Very well explained; thumbs up!

Avatar image for Manick

Manick on Nov. 13, 2020

Thanks Austin. Very well explained.

Avatar image for Jack

Jack on Dec. 9, 2020

Thanks, great videos. Very clear to help understand “DRY” and “overwriting” in inheritance. I am wondering whether Python have the concept of interface or abstract classes like Java? So that the it can just define the behaviour of a particular set of methods, that child class must implement. If we want to create new classes that have behaviours of multiple parent class or “interface”, what is the way of doing this.

Avatar image for sangeeth2kin

sangeeth2kin on Jan. 22, 2021

Can you please explain why baby is not an instance of person in below example:

class person:
    description = "general person"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def speak(self):
        print ("My name is {} and Im {} years old".format(self.name,self.age))

    def eat(self,food):
        print ("{} eats {}".format(self.name,food))

    def action(self):
        print ("{} jumps".format(self.name))

class baby(person):
    description = "Baby"

    def speak(self):
        print ("bla bla bla")

    def nap(self):
        print ("{} naps".format(self.name))

p = person("Saat",8)
b = baby("Sammu",1)
b.eat("baby food")
print(isinstance(baby, person))


My name is Saat and Im 8 years old
Saat eats Pizza
Saat jumps
bla bla bla
Sammu eats baby food
Sammu jumps
Sammu naps
Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on Jan. 22, 2021

@sangeeth2kin The word instance is synonymous with an object. The isinstance() function can tell you whether a given object is an instance of a particular class:

>>> isinstance(b, person)

To check if two classes belong to the same hierarchy, you want to use the issubclass() function instead:

>>> issubclass(baby, person)

To avoid this confusion, people generally follow a naming convention, which uses PascalCase for class names and snake_case for their instances or objects:

class Person:

person = Person()
Avatar image for sangeeth2kin

sangeeth2kin on Jan. 25, 2021

Got it, thank you.

Avatar image for dbristow31

dbristow31 on Jan. 28, 2021

This was a fantastic intro to OOP! The step-by-step process and clear instruction helped me understand concepts I couldn’t before. One topic that was especially difficult for me was the use of the ‘self’ parameter and the ‘initializer.’ This video tutorial clarified those features of OOP and made it easy for me to use them. I’m excited to build on this knowledge with the other OOP video tutorials at RealPython!! Thanks, Austin!

Avatar image for tom77-ai

tom77-ai on Feb. 11, 2021

Wow, great intro to OOP. Finally got it.

Avatar image for stHaggie

stHaggie on April 10, 2021

This was really nice Tutorial. My understanding of OOP is getting better now.

Avatar image for Walisson

Walisson on April 15, 2021

Hi all! I’m new here and for sure me a member was the best thing that I did to keep myself on Python Learn track! All videos, articles and stuffs on this website are amazing! Topics are well explained, lean samples and directly to the point. Nice tutorial!

Avatar image for Terry

Terry on April 22, 2021

Great tutorial, I watched it several times and kept coming back for clarity. Within days I wrote two classes/modules and had them running. The concepts, especially the architecture framework, are well explained. This helped me finally get into OOP, Thanks

Avatar image for ljob

ljob on May 21, 2021

Great, clear explanation. Overriding is mentioned, is this different that overloading? Does Python support method overloading?

Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on May 21, 2021

@ljob Overloading is about having a couple of functions with the same name but different signatures. There is no concept of function overloading in Python, particularly method overloading. You cannot have several functions defined with the same name and different implementations in one lexical scope.

It’s not a syntax error, though. The last function definition will simply overwrite all previous ones with the same name because Python treats namespaces like dictionaries. And, a dictionary cannot have duplicate keys.

Instead of creating many different functions, you might take advantage of the default parameter values to simulate function overloading. Alternatively, you can take a look at the @singledispatch decorator in the standard library or a more versatile third-party @multipledispatch one.

Avatar image for ljob

ljob on May 21, 2021

Thank you for the clarification!

Avatar image for gilpinbmchs

gilpinbmchs on May 26, 2021

What if you were going to create several persons? would it be best to do like this:

person1 = Person("steve", 20)
person2 = Person("charles", 18)

or like this:

steve = Person("steve", 20)
charles = Person("charles", 18)
Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on May 27, 2021

@gilpinbmchs Descriptive variable names such as steve and charles are preferable. If you wanted to spawn arbitrary number of Person instances, then you could use a list or a list comprehension:

# list (could be another sequence type like a tuple)
users = [
    Person("steve", 20),
    Person("charles", 18)

# list comprehension
users = [Person("some_name", i) for i in range(2)]
Avatar image for gilpinbmchs

gilpinbmchs on May 27, 2021

ok thanks. now I’m going to explore list comprehension, thanks!

Avatar image for ebelax

ebelax on June 18, 2021

nice topic

Avatar image for ikanyeng89

ikanyeng89 on July 20, 2021

Good stuff - I am new to Python but I have good experience in C++ - for me it was all about how to create Python class and method in Python and it was well said - it was easy learning for me because of the experience I have in C++ programming language.

Avatar image for Jonathan Chatfield

Jonathan Chatfield on Oct. 16, 2021

Probably one of the best introductions to classes I have seen.

Avatar image for Yogi

Yogi on Oct. 17, 2021

Thank you so much for this great tutorial session. Very well explained for novices like me to get a grasp of the concepts and the usage as well in the initial stages.

Avatar image for anaghost

anaghost on Nov. 4, 2021

This was great but left me hungry for the next level(s)! Could you please add lessons on the other important topics in OOP?

Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on Nov. 4, 2021

@anaghost Sure! What what topics would you be most interested in?

Avatar image for anaghost

anaghost on Nov. 4, 2021

Thank you, Bartosz! A few people before me mentioned multiple inheritance, encapsulation and polymorphism. For me, personally, it would be very beneficial to see a more complex real world example of OOP use. Basically, how an SDE thinks when using OOP for a real world application, not just a Dog class. That would be great!

Avatar image for vishweshvar

vishweshvar on Dec. 4, 2021

This course gave a gentle introduction to OOP, loved the way it was clear, concise and straightforward not beating around the bush, highly recommended for beginners. Thanks Austin, you’re awesome.

Avatar image for Chevabecks

Chevabecks on Jan. 6, 2022

Thanks for this very clear explanation!

Avatar image for Joeey G

Joeey G on Aug. 22, 2022

Very good introduction! Thank you!

Avatar image for madpenguin07

madpenguin07 on Aug. 26, 2022

Great intro/refresher to OOP. Thanks!

Avatar image for Konstantinos

Konstantinos on Sept. 13, 2022

Though an introductory course, it could still demostrate some classes implementation from real world situations, instead of Dog and Person classes.

Avatar image for odaihamza

odaihamza on Dec. 1, 2022

Extensive exercise on every topic can help retaining everything in mind.

Avatar image for Sneha Nath

Sneha Nath on Sept. 20, 2023

Thank you for this excellent course!! clear and thorough understanding..

Avatar image for Andres Galarza

Andres Galarza on March 19, 2024

This was a short but clear explanation of how OOP works. Thanks, Austin, for sharing all this knowledge. This introduction was brief, and there is much more to cover, but now we have a solid foundation to move forward.

Become a Member to join the conversation.