Learniverse

Objektorientierte Programmierung in Python lernen

00:00

Hello, everybody, and welcome back. So in this video, you're going to learn about object oriented

00:04

programming and Python and how you can create your own custom objects by making different classes

00:09

in Python. Now, this video is geared towards beginner. So people that have some knowledge of Python

00:14

have written Python code before, but I've not yet stepped up into kind of the intermediate stage,

00:18

which I'm going to call is this working with classes and objects and are looking to learn that.

00:23

So I'm going to be starting completely from the beginning. If you have no knowledge of object

00:26

oriented programming, that's totally fine. And this series is meant for you. If you're someone who just

00:30

wants refresher, I'd recommend maybe watching the video on two times speed and slowing down when

00:34

things get a bit more confusing or when, you know, you need to really learn that topic more.

00:39

So let's go ahead and get started. And what we need to do to discuss object oriented programming is

00:43

first to find what an object is. Now, a lot of people may think that when we talk about object

00:48

oriented programming, that's a completely new thing, you know, you've never seen it in Python before,

00:52

and it's a new kind of thing to tackle and to learn. When in reality, you actually see objects

00:57

all the time when you're working with Python code, and you just don't know that their objects,

01:01

just because they're a little bit disguised, and I'm going to kind of take away that disguise

01:05

and show you what all these different objects are. So we may have heard of the notion of type

01:09

before. We see this function type. And we know when we ask it what type of certain variable is,

01:14

or we ask it what type say, you know, a string is like this, it spits out an answer to us. And

01:19

I'll show you what I mean by that. So if I do print type of hello, so we know that hello is a string

01:24

data type, let's just see what we get in our console down here. Oops, I didn't mean to do that.

01:28

We get class string. So notice that this says class. Now, most people just disregard the fact that

01:34

it says this, but this is actually very important. What this is telling us is this right here,

01:38

this string that we typed in is actually an object of the class string, right? STR. Now,

01:44

what do you think's going to happen when I put in X? Well, we know that X is an integer. So let's

01:48

us have a look here. And we can see that we get class int. So notice that these different data

01:54

types that we've called them before, a string and an int are actually a part of a class. And what

01:59

that means is, even though it doesn't look like we've created an object, when we do something like

02:04

X equals one, we've set X is equal to the object, which is a type integer with the value one.

02:10

That's exactly what we've done. And the fact that we actually create these kind of objects

02:15

is very important in writing Python code. And I know this hopefully shouldn't confuse any of you

02:20

too much. But if I write say a function, so, you know, define hello and in here, we just print

02:25

hello like that. And what I decided to do is I go, okay, let's look at the type of hello. So

02:31

notice I didn't call the function hello with the two brackets. I'm just looking at the actual name

02:35

of hello. And we run this. Well, if we add the final bracket at the end here, we get class function.

02:42

So pretty much everything in Python that we work with is actually an object of some kind

02:47

of class. And later on in the video, what we're going to do is make our own classes so that we

02:51

have our own specific types. So these are what are called the built in types. These are built

02:56

into the Python language. And that's why they work a little bit differently than other classes

03:00

that we'll work with later. But just understand that whatever you create something in Python,

03:05

you are really creating an object, which is an instance of a specific class. And that class defines

03:11

the way in which that object can interact with other things in our program. And to show you what

03:16

I mean by that, let's just look at some common error messages and we'll see exactly what that means.

03:21

So we're going to say x equals one, y equals hello. And watch what happens when I try to do something

03:25

like print x plus y. Well, we get some error. Let's go up and see here. We get type error unsupported

03:32

operand types for plus int and string. So it's saying because our object x isn't int and our

03:39

object y is a string, we cannot add them because the program does not know how to work with objects

03:45

of those two types. Or in better words, the addition operation is not defined for objects of int

03:51

and objects of string at being added together. So it's very important. And pretty much the type

03:57

that we have defines what we're allowed to do with the specific variable or with that specific

04:02

object. And it denotes the actions that we can perform, plus minus all of that. If I were to change

04:07

this right to two and then we just do x plus y, I don't need to print it out. We can see that that's

04:12

totally fine. And there's no issue because these are both ints, which means that that operation is

04:16

defined for them. Okay. So hopefully that is clear and that makes some sense. I hope that gives you

04:22

kind of understanding of what I mean by objects. And now I'm going to talk about methods because

04:26

those are something that we can perform on objects. So I'm sure that many of you see in this

04:30

before, I'm just going to type string equals hello like that. And many of you know that we can do

04:36

something like print string. If I can type this correctly, dot up. Right. So when I write this dot

04:43

upper here, what is that actually doing? Well, let's look at here. We obviously know that puts

04:48

that all to upper case. But we're allowed to use this what we call method. And this is a method.

04:53

Whenever you have this dot operator, you have some name. And then you have the two brackets at the

04:57

the end here. And maybe there's some arguments that go inside of there. That is usually a method

05:02

that is acting on a specific object. And in this case, what it's doing is we have the method

05:07

upper acting on the object of type string that is stored in this string variable. And the reason

05:13

we're allowed to use this method on it is because this is a string. Now notice that I can't do

05:18

something like, you know, x equals one and then do x dot upper. And the reason I can't do that

05:23

is because, well, it's going to say right here, in object, notice in object has no attribute

05:29

upper. So these methods, these different operations, the things that we can do with these objects

05:33

is based on the type of class that they are. So that's something that we really need to nail in

05:38

there. And I hope that makes sense. And now what I'm going to show you is how we can actually create

05:42

our own classes because hopefully that gave you a good enough explanation for what objects really

05:46

are. So to create our own class, I'm going to kind of do like a template here. And then we'll go

05:51

back through and discuss what everything's doing at once. But just try to follow along for now.

05:55

So I'm going to say class. And we're just going to do the classic kind of animal example to start

05:58

here. So I'm going to say class dot. And we're going to define this initialization, which we'll talk

06:03

about later. And actually, no, let's not even do that. Let's just say define, bark like that. And

06:10

then what I'm going to do in here is simply print bark. Okay. So what I've actually done here,

06:15

and I know this is going to be weird for many of you that have not seen this before,

06:19

is created a class called doc. What this means is I'm going to make my own kind of blueprint now

06:24

for any objects that are of type dog. And I'm going to start defining the operations that a dog is

06:30

able to do. Now in this case, I've created a method. Now a method is essentially just a function that

06:35

goes inside of a class. That's the easiest way to define it. And for our basic example right now,

06:40

all of our methods are going to start with a parameter called self. And we're going to talk about

06:44

what this self parameter means and how all this works later on. But let's kind of build our way

06:49

up to that. So I'm going to say D equals dog down here. And what I've done when I did this here

06:55

is I'm actually saying, okay, I'm going to have the variable D and I'm going to assign it

06:59

to a instance of the class dog. So this is class dog. Again, you don't need to know how this works

07:04

right now. We're going to talk about that in a second. But when I write this line here and I put dog,

07:08

which is the name of my class. And then two brackets like that, I am instantiating,

07:13

right, creating a new instance of the class dog. So D is now going to be an object that is of type

07:18

dog. And notice that we don't get any errors there. And when I decide to print out type of D,

07:24

we're going to see that we get class underscore main underscore dot. Now the reason we have these

07:29

underscores is because this is telling us what module this class was defined in. Now by default,

07:35

the module that you run is called the main module. That's why we have these two underscores main

07:40

underscore underscore. But we can see that this is again, an object of the class dog. And that

07:45

means that whatever we define inside of here is going to be what is allowed or the operations that

07:51

can be performed by a dog. And one of those operations is bark. So this is a method. Remember,

07:57

we've talked about methods just like dot upper before. So if I want to use that method on

08:02

an instance of my dog class, because this is an instance of the class dog, then what I can do

08:07

is I can type well, not dot upper, but dot bark like that. So I can call this method on my dog

08:14

object again, because it is of class dog. And I have defined a method that works for dogs.

08:19

So when I do that, we can see that we get bark. And then it's still obviously continues to print

08:24

the type of that object. So this is what we're getting at here. So these are kind of how classes

08:29

work. We name the class, typically the convention is to use an uppercase letter. And usually

08:34

you go camel case. So you do like dog, like you say, we're going to do two words, you do like dog

08:38

hello, right? So camel case like that. And then inside of the method, or inside of the method,

08:44

inside of the class, you can define a few different methods and operations that can be performed

08:48

by this object. So what I'm going to do is I'm going to say define, I don't know. Let's just say

08:53

me out. I know this is wrong because it's not a dog. And we'll talk about self in just a minute,

08:58

but I can define another method here. And instead of printing something, I could say return, let's

09:03

just say me out like that. So I don't necessarily need to print something. I can return something. I

09:08

can have these methods take arguments. So maybe I have me out. And then I put x and maybe what I do

09:14

is I return x plus one or something like that. So maybe let's just call this add, call this add

09:19

underscore one. That'll be the name of our method. So I can return x plus one. And then what I could do

09:23

if I wanted to here is I could say dog, add underscore one, put five there. And let's print out

09:29

the value that we get. So let's have a look at this here. And we can see that we get the value

09:34

six. So we can make methods that have different arguments associated with them or parameters like

09:38

I've put x here. And that just means that when I call that method, I need to pass in a specific value

09:44

or specific values so that that can operate and that can work. So that is how the methods work.

09:49

So now we're going to talk about itself. But before we can do that, we need to talk about what's

09:53

called the init method, which you may have seen me typing at the beginning before I kind of gave

09:57

up on x. I didn't want to get that complex that fast. So right now we have two methods. We have

10:02

this bark method and we have this add one method. And I hope those make sense on how those work.

10:07

And now we're going to talk about this special method here. And by the way, this has two underscores.

10:10

So it has underscore underscore and then a knit and then underscore underscore. Now this is a special

10:17

method. And what this pretty much allows us to do is instantiate the object right when it is created.

10:23

So this method will be called whenever we write this line. So whenever we create a new dog instance

10:29

by writing dog and then the two brackets, let me get rid of this down here for right now.

10:33

This method will be called and it will pass any arguments that we put in here. So maybe I put

10:38

something like Tim in here. It will pass that to this method. So let's say that every time we create a

10:44

dog and we want to give it a name immediately. So to create a dog, the criteria is that you must

10:49

give it a name. Well, what we would do in here is we would put the parameter name and then here

10:56

we would pass in the name. So what we need to do though is what we're passing in this name,

11:01

we need to store this in the dog object somewhere, right? We need to have this stored. We need to

11:06

be able to access this. This is kind of the nice thing about objects. And this is where we're going

11:10

to talk about attributes. What we can do if we want to store this name is we can say self.name

11:17

equals name. Now it's important to note that this doesn't, these don't need to match. But what

11:21

we've just done here is we've created what's called an attribute of the class dog, which is name.

11:27

So what this means is essentially every time we create a new dog object, we will pass a name

11:33

through this parameter. So self just stays here to denote the object itself. So like every time

11:39

one of these things is called, we will pass a reference to which object it was called on

11:43

so that we can access things for each specific object. And we'll talk about that more in a second.

11:48

But here what I've done is to find an attribute called name, which is equal to the name that we

11:52

passed in. So what I'll do is immediately, I'll just print inside of here the name so that we can see

11:58

how this works and notice that when I run this now we get Tim printing out. So even though I didn't

12:03

explicitly call this a knit method, because I wrote this line here, it passed this name that I

12:08

put in here to the name parameter and then it printed out name here inside of the a knit. And we

12:14

also defined an attribute called name that is inside of this dog class. So what self is doing is

12:21

every time that any of these methods is called kind of invisibly, you don't get to see it,

12:26

the actual reference to this dog object is passed so that we can access attributes that are

12:32

specific to each dog. And what I mean by that is I can make another dog. So maybe I say D2,

12:37

which is, you know, another instance of the class dog except this time I name it Bill, right? And now

12:44

we'll do the print statement again. So we'll say print name just to show how this works.

12:48

And here we get Tim and we get Bill. So we actually have two different dog objects now, one name Tim

12:54

and one name Bill, and they both store different names inside of their, you know, instance, if that's

13:00

what you want to call it. So let's just show how this attribute works. So the point of this attribute

13:04

is that it stored permanently for each specific object. So I can actually go ahead and go down here

13:09

in print d dot name after that's defined. And I can print d2 dot name like that. And when we look

13:18

here, we can see that those names get printed out. So Tim and Bill and notice that I remove the

13:22

print statement from up here. So these attributes when we do something like self dot and then

13:27

anything that we want we can call whatever we want is equal to some value, we can reference them

13:31

later on and we can reference them from methods inside of our class. So an example about is

13:36

something like say define get underscore name. So the first argument here is always going to be self

13:43

the first parameter. And the reason for that is because we need to invisibly pass the actual,

13:47

you know, dog object itself so that we know which dog we're accessing when we're going to get

13:53

say the name of the dog. So here we're going to say define get name and all we're going to do

13:57

is return self dot name like that. So now rather than say saying dot name, we can call dot get underscore

14:04

name, which is a method, right? And we can do that down here as well, get dot get underscore name.

14:09

And then we see that we get Tim and we get Bill. So that is the basics behind objects. Now of course,

14:14

I can make more attributes as well. So I could do something like age. So let's say my dogs,

14:18

I want them to have a name. So let's say my dogs want them to have a name and an age. Well,

14:25

what we'll do now is I'll say, okay, so in our initialization for dog, we're going to take a name

14:29

and we're going to take an age. So we'll define the attributes in here. So self dot age is equal to

14:34

whatever age we passed in. And now every time that I make a new dog object, I need to pass a name

14:40

and an age. So these, this Tim will be an old dog here, Bill will be a young one and we'll run

14:45

this and we see that we get no issue. And if I wanted to, I can go ahead and define another

14:49

method here. So get age and we'll return self dot age like that. And then if we change this to get

14:57

age and we change this one down here to get age as well, what is the issue here? Oops, so I'm

15:05

forgot to put myself in here. So notice what happened when I forgot to put myself. So that's

15:09

actually a decent error to run into. I didn't put self in here as a parameter and you can see I know

15:14

that's kind of messy here. It says get age takes zero positional arguments, but one we're given.

15:18

So what does that actually mean? So it's saying it takes your arguments, which it did when I

15:22

didn't have self here, but one was given, but I didn't give any arguments inside of the brackets.

15:27

Well, that's because when we call a method, this right, the actual dog object itself immediately

15:33

kind of invisibly gets passed to that method as the self parameter. So we know which dog it's

15:38

talking about. So now if I go ahead and I add self, we can see that this works fine and we get

15:42

34 and we get 12. So that's an important thing to remember. Now what we can actually do is we can

15:48

other methods that modify these attributes or create new attributes. So I can do something like

15:52

for example, set age. So I can say define set age will give itself, of course, and then we'll put

15:57

an age here. And what I can do now is say self, age is equal to age. And now what I'm going to do

16:02

for Tim and we'll get rid of bill for now because I think we get the point on how it works for

16:06

different objects is I'm going to say d dot set underscore age and I'm going to change his age to 23.

16:12

And when we printed out, we can see that 23 actually gets printed out. So we can modify and we

16:17

can access these different attributes from methods inside our class. And this is where things get

16:22

things get very powerful because this allows us to access data that is stored within a specific

16:28

object and do different things with it based on how different methods and different things are

16:33

being called. Right? And this just is pretty much the blueprint that defines how a dog actually

16:39

works, how it operates, what it can do, the methods associated with it and the attributes that exist.

16:44

Now, some of you may be saying, well, why do I need to do this? Right? Like this seems

16:48

kind of redundant. I could write in a different style. Well, the next thing about object

16:53

oriented programming is once you create one of these classes, you can have an infinite amount of

16:57

instances of this class without having to change anything. So let's say, for example, that we'll

17:02

leave that class up here right now, but we want to simulate what we've just done here for the

17:07

Tim dog, right? We want to have an age and we want to have a name and we want to be able to change

17:11

his age and all that. Well, many of you that were more beginner programmers would probably tell me

17:15

we can do something like this. We can say dog one underscore a name equals Tim. You could say dog one

17:22

underscore age equals, you know, 34 and there you go. You've just defined these two attributes.

17:28

If you want to get it, you can just access the variable. If you want to change it, you can just

17:31

change the variable. Okay, nice. But what happens when I want to make 25,000 dogs or every time I run

17:37

my code, I want to make a different amount of dogs. You can't find a way that you can write all

17:42

these different variables that have one, two, three all the way up to 50,000 or have many dogs I

17:47

have to represent that. That's why we use objects is whenever we're going to be kind of reusing

17:52

something. There is some instances in which we make a class where that we're only going to use once

17:58

or instantiate once, but those are kind of more complex examples that we won't get into here.

18:03

But then okay, so some of you might tell me, all right, well, Tim, I can just do list. I can say

18:06

dogs equals that. I can say dogs underscore name equals that, right? And here we can put,

18:12

well, the first name is Tim and then we had fill. So this will handle the idea that

18:19

we can't just have all these different variables, right? So dogs age equals, and then we go,

18:24

let's say, I don't know, 32, 14. Okay, that's great. But the issue with this is that it's really

18:30

a pain when I want to access the dogs age, the dogs name. And then what if I had like 25 other

18:36

attributes or methods associated with the dog, this is just just a pain. You don't want to deal with

18:41

that because I have to now find the index of whatever dog I want in one list, which is a very time

18:46

consuming operation and computing. And then I need to reference that index and all the other lists

18:50

for all the other attributes. And it just becomes very messy very quickly. And let's say I want to

18:54

delete one instance, like the, um, you know, the dog object bill or something like that, right?

19:00

Then I need to find the index of this. I need to find the index of all of the attributes in

19:04

and all the other lists. And I need to delete them at the same time to make sure that all my data

19:08

stays consistent. And there's no kind of offsetting things or too many attributes in one list.

19:12

So it just does a pain to do it like that. So I hope this makes sense on why we would do object

19:17

oriented style. And now what we'll do is go into one example where we create a more complex object

19:22

and show kind of the advantage of that. Okay, so a lot of people typically will stomp at kind of

19:27

the previous example that I just gave you. Now I want to go a little bit further and show you

19:30

the advantage of doing multiple classes. So rather than just using one class, I want to show you

19:35

how different classes can kind of interact in an example where I have a bunch of students,

19:40

these students all have some great assigned to them. And they're all a part of a course.

19:44

And then that course will have some methods on it to do things like find the maximum grade

19:49

of all students, give us the average grade of all students, tell us the lowest grade.

19:53

Some things that you may actually want to do, say if you were trying to model or create a system

19:57

for a school or something like that, right? So this is obviously going to be a little bit more of

20:01

an example as opposed to super practical, but hopefully this should give you some more insight

20:05

into how we would do something like that. So I'm going to start by creating a class called student.

20:10

I'm going to go a little bit faster here, but I will slow down and talk about what I've done

20:13

after so don't worry if you can't keep up. So we're going to have a student and each student

20:16

is going to have a name, age, and a grade. So we're just going to say self.name equals name self.age

20:24

equals age, and then self.grade equals grade. Now this numeric grade is going to be between 0

20:31

and 100. So I'll just write that down here just so we know that. And that should be good for

20:36

our students. So we could of course go in here and add some methods if we wanted something like

20:40

get underscore grade. And we'll just add one just so we have it in here. And what we can do is return

20:46

self.grade like that. Okay. So this is this is where we're going to leave our student.

20:51

Now we could add a lot more things to this. We could add a change grade. We could add a test. We

20:56

could have weightings. We could do all kinds of crazy stuff. But for now we're going to leave it at

21:00

that. So again, we've defined three attributes here. We have a name and age and a grade. Those are

21:05

equal to the name, age and grade that we pass in when we initially create a student. And then we have

21:10

one method. Remember this is a method that simply returns a student's grade. Now I'm going to

21:15

make a new class called course. Now what I'm going to do in this course class is I'm going to have

21:20

the ability to add students to a course. So when we create a new course, what we're going to

21:25

need to do is we're going to need to define the name of the course and the max underscore students

21:31

that can be enrolled. So here we'll say self.name equals name and self.max underscore students

21:40

equals max underscore students like that. All right. So what we're going to do now is we're going to

21:46

add a method that will allow us to actually add students to this course. But how are we going to do

21:51

that? How are we going to have students stored inside of a course object? Well, what we can actually do

21:57

is we can make a list of students. So I'm going to say self dot students equals a blank list.

22:02

Now notice that I've made an attribute and I didn't assign it directly to one of these things that

22:07

was passed into one of these parameters arguments, whatever you'd like to call them. That is totally

22:11

fine. In fact, a lot of times we'll create attributes like self dot is active, something like that

22:17

equals false. Right. We can do that. That's totally fine. An attributes are just whatever we decide to

22:22

define. And if we want to assign them to say the argument or parameter that's here, that's fine.

22:29

And we can do that. So there we go. We have self dot students, which is a blank list. And I'm going

22:33

to start by creating a method here that's going to allow us to add a student object into this list.

22:39

So I'm going to say define add underscore student like that. And in here, we're going to take

22:44

self and we're actually going to take student. Now this student right here is actually going to

22:49

be an instance of a student object. And I'll show you what I mean by then the second. But all we're

22:54

going to do is say if the length of self dot students is less than and in this case self dot max

23:02

underscore students, then what we'll do is we'll say self dot students dot append student. So

23:11

we're going to create a list of students inside of this, you know, this list right here. Right.

23:16

That's what we're going to do. And we're going to add them in only if this is less than the maximum

23:21

students in the class. Now what I'll do is I'll actually return true if the student was added

23:25

successfully. And then down here, I'll return false if not so that we can tell maybe if we make a

23:31

program down below if that student was added properly or not. Now I'm going to add another method

23:35

and here I'm going to say define get average. Great. Now we'll code that one out in a second. But

23:43

let's do an example of how we can actually now add students to these classes. I'll make that a bit

23:47

smaller so we can read it. So let's make a few different students. So let's say s1 equals

23:54

student. What do we need to pass for student and name agent grades? So let's call that Tim. Let's

23:59

call that 19. And let's call that 95. Tim's a smart guy. All right. And then we'll do s2 equals

24:05

student. We're going to say bill. We'll put him at 19 as well. And he's not as smart. He is 75.

24:12

And then let's do s3 equals and let's go Jill keep with the trend Tim build Jill 19 and maybe

24:21

she has a 65. Okay. So we've created three students here. And these students are proper. They

24:27

should work fine. Let's run this code and make sure everything's all right. Now how can we actually

24:31

add them to our course? Well, the first thing we need to do is make our course. So we're going to say

24:35

course equals course like that. What do we need when we make a course? We need a name and we need a

24:40

maximum amount of students. So let's name this course. Let's say science or something like that.

24:46

And let's say the maximum amount of students is actually going to be two because I want to show

24:50

what happens when we add a student pass the maximum. Now we're going to add students. So how do we

24:55

add them? Well, we have to call that method. So course dot add students. So there we go. We can add

25:00

student s1. And then let's do course dot add student again. And let's add s2. So now let's run this.

25:08

We see everything works fine. And let's actually make a thing that can, you know, print out some

25:13

thing about our student or can show our students. So what I could do is I could say let's print down

25:18

here course dot and this students. And let's have a look here. And we get main dot student

25:24

object at some gibberish location, main student object at some gibberish location. So what this is

25:30

actually telling us is both of these things inside our list right now are student objects.

25:35

And notice what I can actually do is let's say index the zero with item in that list. So the first

25:40

student that we added. And I decide to call dot name on it. Well, then that should hopefully print

25:46

out the name of that first student, which is 10. So that's cool. And that's how we do that, right?

25:51

We can add things into this course. So now this course stores all of our students. And since all

25:57

of these students have a great on them inside of our course, we'll be able to access that.

26:01

So now that we've done that, let's write this method that can get the average grade of all of the

26:05

students that are enrolled in the course. To do that, what we're going to need to do is grab

26:10

all of the students from the students list. We're going to need to add that to an average.

26:14

And then we're going to need to divide that value to figure out what that is. So what we'll do is

26:18

we'll say value equals zero. We're going to say for student in in this case self dot students,

26:28

then we're going to say value plus equals student dot gets grade like that. Now notice that we

26:37

could just type grade. If we wanted to, but I usually just like to use the method because say we

26:42

we were to change any attribute later, then this code wouldn't break. So long as this method was

26:47

still name the same thing. And we can modify the method in here. So they return the proper grade.

26:51

Like say we had a student enrolled in multiple courses. Then we could, you know, determine their grade

26:56

in a different way. And when we call get grade, maybe we don't just return self dot grade. We return

27:01

something different. So this still continues to work. So we'll say value plus equals student dot

27:06

grade. And now all we'll simply do is return in this case value divided by the length of self

27:14

dot students. So let's see what the average grade of our courses. So course dot get average grade

27:19

we'll actually current that out like that and run that. And we can see that the average grade is

27:25

actually 85. And that makes sense with the grades that we have here. So that's the idea behind

27:30

what I'm trying to show you is that we have, you know, we can have different classes. We can have

27:34

attributes with them. And when we can program an object oriented style, now it doesn't matter

27:39

how many students we have or how many different courses we have and what students are enrolled in

27:43

which in fact, what we could do is we could make another course, we could add the same students to it.

27:48

And then we would obviously have to change the way that their grade was calculated. But that's

27:52

something that we could do. Now let's just look at what happens when I decide to try to add that

27:56

third student. And so course dot add student like that. And we decide to add student S3.

28:02

We can see that we get the value false. And notice that the average grade does not change

28:07

because we didn't actually add that into the course, right? Okay, so we finished off the basics

28:13

on classes and objects and how to create our own classes. And hopefully that last example helped

28:17

you to really kind of understand the advantage of doing this. Now what we're going to talk about

28:21

here is something called inheritance. Now this is where we slowly started getting to a little bit

28:25

more complex and some more difficult concepts. So try to follow along, but I don't find

28:29

inheritance is that extremely difficult. So the idea behind inheritance and we'll show what that

28:34

is in a second is you have two classes that are very similar. So let's say we have a general class

28:41

called maybe or let's actually let's do a better example. Let's say we have a class called dog and

28:45

a class called cat. And in fact, let's actually code these out so that we can see this for real.

28:50

So let's say in the init method of the cat, what we're going to do is we're going to have

28:53

self name and age like that. So we're going to say, you know, self dot name equals if I can type

29:01

properly, which apparently is not happening right now. And then self dot age. And then we'll do

29:06

define speak and all we'll do in here is just print, um, you know, what does this cat meow? Okay,

29:13

and then let's say we have a dog. So we'll say class dog like that. And then we'll define

29:19

underscore net underscore underscore put the self, put the name, put the age because that's

29:23

all we want for that. And we'll say self dot name equals name self dot age equals age. And then

29:31

define here speak. And the only difference between these two classes is actually going to be the fact

29:36

that this prince bark instead of meow. So notice that these two classes are almost identical.

29:43

In fact, there's only one line of code that's different other than the class definition at the top.

29:47

So there must be a way that we don't need to write this twice that we can actually use what's

29:51

called inheritance so that these dog and these cat classes can well inherit from an upper level

29:56

class, which means that all that functionality is defined in one place. And we only need to write

30:01

what's different about those two classes inside of them. So ideally what I would like to have

30:05

is to be able to remove this and knit class from both of these and just have the speak method

30:10

because the only thing that's specific to a cat in a dog, at least for my example is the fact that

30:14

one of them says meow and one of them says bark. So let's go show how we can actually do that.

30:19

So by removing that, you know, was a knit method and just having these methods here, what we

30:26

need to do is make an upper level class, which I'm actually going to call pet. So I'm going to say

30:31

class pet. And what I'm going to do in here is define that a knit method that we had before.

30:36

I'm actually going to define a, let's say show. So this show method is just going to show me

30:42

all the things about my object. So I'm going to say print. And in here we're going to say,

30:47

you know, I'm actually going to use an F string. You may not know what that is, but don't worry about

30:50

it. I am self dot name and I am self dot age years old. Okay. So what I've done is I've defined

31:01

this pet class. And this pet class essentially is going to contain the functionality that I want

31:06

the cat class and the dog class both to have. And then inside of the cat class and inside of the

31:12

dog class, what I'll do is I'll define the methods or the attributes or whatever it is that I

31:17

need to do that are going to be different for this specific class. So notice that pet is general.

31:23

We call this a generalization, whereas cat and dog are more specific. So how do I actually allow

31:29

the cat class and the dog class to use this functionality? Well, what I can do is simply add brackets

31:36

and write pet. Now what this stands for is I am inheriting the upper level class pet. So we're saying

31:44

this is the general class. This is a more specific class that's being created and inherits from pet

31:50

and same thing with dog. Let me show you how this works. So let's create an instance. First of all,

31:56

of the pet class. And then we'll make one of the cat and the dog class. And I'll show you how it

32:00

it works. So let's say p equals pet. Notice that for pet we need a name and we need an age. So

32:06

let's say it's him. Let's put him at 19. And then let's do p dot show. So let's look at this here.

32:13

I am Tim and I am 19 years old. So that is how the pet class works. Pretty straightforward.

32:18

Now let's make a cat class. So let's say c. I'm going to say c equals cat. I'm going to say

32:24

the cat's name will be bill. And that cat will be 34 like that. And then let's do the same thing

32:30

here c dot show. Now notice that even though there's no method called show inside of cat,

32:36

it still pops up and says I am bill and I'm 34 years old. That is because it inherits the properties

32:43

from the pet class because I've defined that up here. And notice that even though I didn't

32:48

find an init method in here, this still worked fine. Right? There's, you know, this was okay.

32:53

We initialized because we use the init method that was defined inside of pet. And of course,

32:57

we can do the same thing with dog. So we can say d equals dog. What do we call this one before

33:02

jail? 25. And let's do d dot show like that. And we go, I am jail and I'm 25 years old. So that

33:10

works. But now let's show what happens when we call speak on the cat and the dog. So if I decide

33:16

to call speak like that and we'll call it on both of them here, we can see that we get me out

33:22

and we get bark. And again, that's because the speak method is different for the cat class

33:27

and different for the dog class. And since it's defined inside of here and we created an instance of cat,

33:32

when we make a cat instance, well, we're going to use the speak methods that's defined here.

33:36

And in fact, what I could actually do is define speak up here. And I could say define speak and I

33:42

could say print, I don't know what I say like that. Okay. And then if I decide to change this

33:54

from show to speak, notice that we're calling speak three times. Speak is defined here and it's

33:59

defined in both of our child classes is what we call them. So when they, when this is the upper

34:03

level class, the more general version, any classes that inherit from it are known as the child

34:08

classes or the derived classes. That's not that important to know, but just, you know, figured

34:13

out through that lingo out there. And notice that when I run this, we get, I don't know what to say,

34:17

me out and bark. So if there is a method defined in the lower level class or the child class,

34:23

that is the same name as the upper level class, it will automatically override that method.

34:28

So it will take over anything that's defined in here is more specific to this class. So it will

34:33

use that rather than using this upper one, right? And you might ask, well, why would we even

34:37

bother defining one in here if we were just going to take it over later? Well, we might create

34:42

another pet, right? Maybe like a fish or something, for example, like I can do something like this,

34:47

class fish, pet, like that. I can literally just define that and put pass inside of here.

34:53

And now what I can do is say, okay, let's say f equals fish. And then we need a name. So let's

34:59

call this bubbles, why not give it 10. And now we can say f dot speak. And notice that we get,

35:07

I don't know what to say for this fish class because there was no speak defined inside of here,

35:12

it used the speak that was defined in the upper level or parent class, right? The one that we

35:16

inherited from. So that is the basis behind inheritance. Now it gets a little bit more complicated.

35:22

I'm going to show you the more complex aspects because let's say I want to add one attribute to my

35:27

cat. So let's say that for cats, we actually care what color those cats are as well.

35:32

Well, what I need to do to do that is change this initialization method, right? Because I want to pass

35:37

that in when I create a cat, but I don't necessarily want to rewrite this whole thing. So what I'm

35:41

going to do, and I'm kind of need to rewrite the whole thing, but you'll see why we would actually

35:46

do this in a second. I'm going to say self name, age, color like that. And now all I'm going to do

35:53

let me say self dot color equals color. So what some of you may say here now that we've defined

36:00

the color in here is that what we should do is take this name and age, right? Just copy it

36:04

and paste it in here. Now that would be a correct answer, but I'm going to tell you why we shouldn't do

36:09

that. So the idea here is that sometimes in the initialization method of our parent, other things are

36:16

happening other than just redefining attributes, right? And in that instance, it would not be correct

36:22

for us to simply omit the fact that we're not going to call this a net from the parent. We're

36:27

just going to define the attributes because that could mean that we miss out on a very important

36:31

you know, function that's happening from inside of this initialization. To give you an example,

36:35

like saying some web applications, maybe this initialization actually calls a database, right?

36:40

And then ask for some information for a database and it sets up the object using that.

36:44

It wouldn't necessarily be correct then for me to just, you know, take the attributes that we're in

36:49

here and just redefine them as attributes here. I would actually still need to call that initialization

36:54

to make sure the object was set up properly. So to ensure that that happens when we do an inheritance

36:59

like this, we do need to define the arguments that we need or the parameters that we need for the

37:04

parent's initialization. So name, age, but there's a fancy way to call that. So rather than, you know,

37:10

rewriting this here, I can actually explicitly call this and set up our object that way. So to do

37:17

that, I'm going to say self or super dot underscore underscore net done underscore underscore name

37:22

age. Now what this is saying is super stands for reference the super class and the super class

37:28

is actually the pet class or the class that we inherit from here. So that's what super stands for,

37:33

the class that we have inherited from. Then underscore underscore net underscore underscore defines

37:38

the method that we want to call, right? And then name and age are the arguments that we're going

37:43

to pass to that. So name and age. Notice I don't need to pass self. That's fine. We don't need self.

37:49

And it's going to call that. And what's going to happen is it's going to run whatever's inside

37:52

this initialization. Then that's going to set up the name and the age for our object. So we will have

37:57

those properties to find. And then we will call self dot color equals color. We will execute that

38:02

line. So now we have the color. Right. And if I just go ahead and wanted to find here show,

38:07

so I want to change the show method maybe for this cat object, then what I can do is I say,

38:12

I am self dot name and I am self dot age and I am. And in this case, self dot color, right. So we

38:20

can change the show method in here. And now let's go to cat. Let's change this to show. Let's

38:24

add a color because we need to add a color. Now we have to find that in the in it. And let's run

38:28

this and see what the issue is now that we're getting fish is not defined. Oh, did I? I guess I've

38:38

deleted fish or we got rid of some point and I did not remember. Okay. So anyways, let's run this.

38:43

And we can see that we have I don't know what to say. I'm Bill and I'm 34 years old and I'm brown

38:47

and then we get bark. Right. So that is how that works for inheritance. And this is how we call

38:51

the super class or the upper level parent class. Right. We need to call this initialization method

38:57

before we just go ahead and do anything else because that parent's initialization may be important

39:02

and may do other things. It may call another method. Right. So we can't just simply skip that.

39:06

We need to call that explicitly by writing this line. Now this line is kind of complicated syntax.

39:11

Um, you know, it's easy to forget, but try to remember it super again references the parent class

39:17

and then we have a knit. Um, and like that. So I hope that gives you an idea on how inheritance works.

39:23

Now it's hard to give really good inheritance examples without going more complex and more into

39:28

detail. So I'm going to omit doing that for now, but just remember that when you have classes that

39:32

do a very similar thing, they have almost everything identical except maybe a few attributes or a few

39:37

methods. It might be a good idea to what we call generalize and make a parent class that is a

39:42

general class that defines functionality that will be used in all of your child classes.

39:47

And that is a very common practice and object oriented programming to use inheritance. For example,

39:53

a very good example is, for example, a good example is something like a person hierarchy.

40:00

So let's say you have an, you're working in an organization. And the example we want to consider

40:04

is we have managers and we have employees. Now managers have different access than employees,

40:11

but employees and managers have very similar properties. They'll have a name, they'll have an

40:14

age, they'll have an ID, they have a birth date, they have many different things that they are the

40:18

same for both of them. Well, if we were trying to model that system and we were going to program that

40:23

and make that, what we would likely do is create an upper level general class called person that

40:28

defines all of the attributes and all of the methods that are general to all people, whether they

40:34

are managers or employees. And then we would create two child classes, one for employee and one for

40:39

manager and that would define the specific things that the manager can do and that the employee can

40:45

do that are different from each other. So that's the idea behind inheritance. Hopefully that makes

40:49

sense. And now let's move on to our next topic. Okay, so now it's time to talk about static and

40:53

class methods and class attributes. And in fact, we're actually going to start with class attributes.

40:58

Now previously, you would have seen that every time we defined an attribute for one of our objects,

41:03

we used self, right? And inside the class, we had self everywhere, self was referring to the

41:08

instance in which we were talking about in that context, right? So here, what we're going to do

41:13

now is talk about class attributes. Now class attributes are attributes that are specific to the

41:18

class, not to an instance or an object of that class. So I'm going to do a basic example where I

41:25

just create a class person. And I'm going to say number of people equals zero. Now in here, I'm going

41:32

to define a net method and say to find a net like that. And we're just going to say each person

41:36

person will simply have a name, keep it nice and simple, like that. So self, that name goes name.

41:41

Now let's make P1 person. We'll talk about what I've done in a second here in case anyone's confused.

41:45

And let's say P2 equals person. Let's make this gel. Okay, so we have this number of people

41:54

thing. And I'm sure a lot of you are like, what the heck is that? Well, this is a class attribute.

41:58

And the reason that's not a regular attribute is because it does not use self. So because it's not

42:03

defined inside any method, because it does not have access to an instance of the class,

42:08

it is defined for the entire class, which means that this is not specific again to any instance.

42:14

It's not going to change with from person to person, whereas we know something like self.name

42:18

will be different for each instance of the person class. This is not different for each instance

42:24

of the person class. In fact, it's the same. So what I can show you is that I can actually go ahead

42:29

and print say, you know, P1 dot number of people. And that gives me the value zero. But what I can

42:35

also do because this is not specific to the instance of any class is right person dot number of people.

42:42

And the reason I can write person is because again, this is specific to the class, not to the instance.

42:48

So we can access it by just using the name of the class. And that actually means that I can

42:52

change it using the name of the class as well. So person dot number of people equals eight,

42:57

right? And then if I go ahead and say, okay, P2 dot number of people notice that we get eight,

43:04

even though I didn't explicitly change it on P2, it changed for P2 because this was specific to the

43:11

class. And when I reference this, all this says is when I say P2 dot number of people,

43:16

the way that Python interprets this is, what is the type of P2? Okay, that's person. Notice,

43:21

you can see it's popping up here. It's this person. Then let's say does it have an attribute called

43:25

number of people. No, this person itself does not. Does the class have an attribute called number

43:30

of people? Yes, it does. Let's display that. And since we changed that to eight, that's why we're

43:34

getting that value. And of course, if we do this for P1, like we've shown, right, we'll get the same

43:40

number. We'll get P1 dot number of people get eight. And if we decide to change this halfway through,

43:44

right, so we do a person equals nine, obviously that will become nine now just because we changed

43:48

it right before we printed the next value. So that is the basics behind class attributes.

43:55

Now, there's a lot of different uses for them. Now, in this case, what I want to do is have a

43:58

number of people. So what I was going to do is inside of here, say person dot number of people,

44:03

plus equals one, so that we keep track of how many people or how many instances we have created

44:09

of this class person. So now, if I decide to print P, you know, person dot number of people,

44:16

and we'll do that after we create the second person as well. See, we get one, two, and this

44:20

automatically increments it. So that's a basic example of when you would use a class attribute.

44:24

They're not extremely useful, but, you know, it is something that you may want to consider.

44:28

And sometimes say you want to define a constant something like maybe gravity or something that's going

44:33

to apply to every single person that you want to be a constant value, then you define that as a

44:38

class attribute. So that if you ever decide to take this class and use it somewhere else,

44:42

that constant is still defined as opposed to putting it up here. Like as opposed to saying gravity

44:47

up here and making it equal to negative 9.8 meters per second at the top, what you would do

44:52

is you would make that a constant inside as a class attribute so that now every time you want to

44:58

access the gravity property for, you know, a person, what you would do is you can reference directly

45:03

the person's class constant of gravity rather than a global constant, which may not be there if you

45:09

put this class in a different file. And that's the idea behind these classes as well as that they

45:14

are exportable. I can write a class in one file and I can take it and move it to another file,

45:18

and hopefully it should continue to work, assuming it does not depend on anything from the previous

45:23

file. So ideally you want to make your classes as robust as possible, which means that they don't

45:28

need anything outside of their initial class definition unless that's going to be another class

45:33

that maybe it's interacting with, like in the example before where we had course and we had

45:36

student. But that is the idea behind class attributes. Now, let's talk about class methods.

45:42

So class methods are defined a little bit differently than regular methods. And in fact,

45:47

I'll show you how they work. We have a good example kind of setup here. So I'm going to say

45:51

define. And in this case, we're going to say number of people like that instead of saying

45:57

actually self, we're going to say CLS. Then what we're going to do here is return CLS dot number of

46:03

people. And we're going to use what's called a decorator to denote that this specific method is a

46:09

class method. And to do that, we write at class method directly above the function. All right,

46:15

yeah, I guess function method, whatever you want to call. So I know this seems a little bit weird,

46:19

but the idea behind this is this method here is not going to be acting on behalf of one instance.

46:26

It's not going to be specific to an instance. And in fact, you can call it on instance if you want,

46:31

but that's not really going to be very effective. What this is meant to do is be called on the class

46:36

itself so that it can deal with something like, you know, returning the number of people that are

46:42

associated with this class. So these are class methods. That means they act on the class itself,

46:48

they do not have access to any instance. And that's why I've written CLS here instead of self

46:53

because there's no object. What it's doing is just acting on this class. So for example,

46:58

say we wanted to add to the number of people. Then what I could say is class method

47:03

define add person like that CLS and would say CLS dot what is it number of people like that

47:13

plus equals one. So that would be these are class methods. We denote them with at class method.

47:19

Just so we know that they're not referencing, you know, self like that. They're referencing the

47:24

class. So let's actually have a look at how we use that now. So you don't need to necessarily print

47:28

the number of people anymore. What we can do is we can go down here. We can say person dot number of

47:35

people. And I don't know why there's so many brackets showing up there. But if we look at this,

47:40

what we would need to print it out first, we should hopefully get the value of two. So let's look

47:46

okay. So we need to rename this so that this is not the same as the attribute because that's going

47:51

to be confusing. So let's add an underscore there because I was realizing what that was going on

47:55

and we can see that we get zero. Oh, so that is because I did not continue to add here. So actually,

48:00

what I'm going to do is, and this actually be a good example. So let's illustrate this here,

48:04

is I wanted to say two, but I forgot that I forgot, you know, didn't continue adding this.

48:09

But what I can do is actually use the class method that I've defined here to add a person.

48:14

So I can say person dot add person like that inside of my nits. And what that will do is

48:20

call the class method on the class person. And then it will add to the number of people. So now

48:25

when we run that we get two. So that is how a class method works. I don't need access to the

48:30

instance to call it. Although I can use an instance to call it if I want, I can simply reference

48:34

the actual name of the class. And this does not access any specific instance. It only accesses

48:40

these class attributes or anything specific to the class itself. Okay, so that has been class methods.

48:46

Now let's get rid of those. And let's talk about static methods. So sometimes,

48:50

I'm actually going to delete this entire thing. You want to create classes that kind of

48:53

organize functions together. So for example, you know, when you say like import math like that,

48:59

and then you get access to all these math functions like math dot ABS or math dot square roots

49:04

or whatever it is you're going to use. Well, what they sometimes end up doing in an object

49:08

oriented programming, this is pretty common, is when you have a bunch of functions that you

49:12

normally just define, like you define like add one like this, you know, I would do something,

49:17

you define add to like this. Well, what you want to do is you want to actually organize them into

49:23

a class. And the reason you do that is just so it stays a little bit structured. You can move

49:27

all those classes together to another module and continue to use them. And to do something like

49:32

this, you want to use what's called a static method. Now, let's make a class called math.

49:38

And what I'm going to do in here is I'm going to define some methods or some functions that

49:42

I'd like to be able to use, but that are not specific to an instance. So I don't want to have to

49:47

make an instance of this math class to be able to use these methods. I want to be able to call them

49:52

at any points. And it doesn't matter if I have an instance of the math math class or not,

49:56

I would like to be able to use them. So what I'm going to do is actually create what's called

50:00

a static method. Now static means not changing, right? It means staying the same. And that is a

50:06

really good way to describe what these methods do because they do not have access to an instance,

50:10

just like the class method. All they do is something. They do something, but they don't change anything.

50:16

And that's the idea behind a static method. They don't change anything because they can't. They don't

50:20

have access to anything. So in here, what we're going to do is just say define ad five. And in here,

50:26

I don't even need to put a cell for a CLS because this is not going to access anything. All

50:31

it's going to do is just act as a function that is defined inside of this class. And again,

50:36

some of you, I'm sure are yelling saying, what's the point of doing that? Why don't I just

50:39

find a function globally? Well, it's more of an organizational thing. And there's some more

50:44

specific applications in which you would use a static method. So I do need to show them to you.

50:48

So here we're going to take a number and all we're going to do in this method is return x plus five.

50:53

So now if I want to actually use this, what I can do is I don't need to say like m equals math,

50:59

like that, and make an instance. That's not necessary. I can simply write the name of the class

51:04

and say math dot add five. Let's put five in here. Let's have a look if I got rid of the s and we

51:09

get the value 10. So this is called a static method. And we can make as many of these as we would

51:15

like just as we can make as many class methods as we want. So maybe we do add 10, right? And then we have

51:20

that like that. And we can change this method to say add 10. And now if we run this, we get 15.

51:25

So that is a static method. Notice it doesn't need anything. In fact, what I can actually do is say

51:30

define PR. Let's say that's going to stand for print. Let's make this an static method. And now

51:37

let's just print run. Like I'm just showing that you that you don't need any attributes in there

51:43

or arguments. And let's just call PR. And now you can see that we get run. And since I printed the

51:47

value of that, it printed out none. But there we go. Like that. Okay. So that is static methods

51:53

and class methods. And to be honest with that, that is pretty much everything you need to know about

51:58

classes and objects at least at a beginner level. Now, there's some more interesting things that we

52:02

could talk about. But in the idea of keeping this more for beginners and so that everyone can kind of

52:07

understand doesn't get too confused. I'm never afraid from discussing anything further. But I hope

52:11

this really gave you a fundamental knowledge of how classes and objects work in Python. A little

52:16

recap here is to remember that everything we work with is an object in some sense. We have functions

52:22

which are objects. We have strings which are objects, integers are objects. And what an object does

52:27

is it's an instance of some class. And that class defines the properties and almost kind of the

52:32

blueprint for that object. It says, okay, so if we have a string, we can use the method like dot

52:38

upper dot lower. If we have an int, we can add integers together. And a class, the type of an object

52:43

is very important because it defines the behavior in which it can exhibit. So that has been

52:48

classes and objects in Python and introduction to object or into programming. I hope you guys

52:53

enjoyed. If you did, please make sure you have a like. These videos are not that easy to make and they

52:57

are definitely time consuming. So I would appreciate it. Subscribe to the channel. And of course,

53:01

let me know if you have any questions or if there's anything you would like to see in the future.

00:00

Einführung in die objektorientierte Programmierung

00:43

Objekte in Python verstehen

02:56

Eingebaute Typen und Klasseninstanzen

05:41

Erstellen von benutzerdefinierten Klassen

16:11

Warum Klassen in Python verwenden?

20:06

Erstellen einer Schülerklasse in Python

21:20

Verständnis Kurs Klasse

23:53

Schüler zu einem Kurs hinzufügen

32:52

Vererbung in Python-Klassen

39:22

Die Bedeutung der Superfunktion

40:50

Verstehen von Klassenattributen

45:40

Klassenmethoden definieren

49:37

Statische Methoden in Python verwenden

50:16

Funktionen innerhalb von Klassen definieren

51:47

Verstehen von statischen und Instanzmethoden

52:15

Rückblick auf Python-Klassen und -Objekte

02:56

Wie stehen eingebaute Typen zu Objekten in Python?

06:44

Was bewirkt das Schlüsselwort 'self' in Objektmethoden?

15:13

Was passiert, wenn ich 'self' in einer Methode vergesse?

17:06

Wie helfen Objekte dabei, viele Fälle wie Schüler einfacher zu managen?

19:12

Welche Vorteile bieten Klassen, wenn's um die Datenkonsistenz geht?

29:50

Wie hilft Vererbung dabei, Code-Duplikate zu vermeiden?

36:59

Was macht die super() Funktion bei Vererbung?

42:02

Wie unterscheiden sich Klassenattribute von Instanzattributen?

48:49

Was können statische Methoden im Klassendesign tun?

49:51

Wie unterscheiden sich statische Methoden von Instanzmethoden in Python?

50:43

Warum würdest du Funktionen innerhalb einer Klasse definieren und nicht global?

52:32

Was bedeutet es eigentlich, dass alles in Python ein Objekt ist?


FehlersucheAttribut (Rechnen)AlgorithmusVererbung (objektorientierte Programmierung)Lösung von ProblemenPython (Programmiersprache)Objektorientierte ProgrammierungStruktur der DatenKlasse (Computerprogrammierung)Polymorphismus (Informatik)Wertobjekt

Beschreibung

Das Video beginnt damit, was ein Objekt in Python ist. Der Host erklärt, dass Objekte Instanzen von Klassen sind und dass jedes Objekt seine eigenen Attribute oder Eigenschaften hat, die sein Verhalten definieren. Dann gibt der Host Beispiele dafür, wie Objekte im Python-Code verwendet werden, zum Beispiel beim Erstellen von benutzerdefinierten Objekten mit spezifischen Attributen. Er spricht auch über das Konzept der Vererbung, bei dem eine Unterklasse die Eigenschaften und Methoden einer Oberklasse erben kann. Im Laufe des Videos betont der Host, wie wichtig es ist, OOP zu verstehen, wenn man mit Python-Code arbeitet, da es ein grundlegender Aspekt der Programmierung in dieser Sprache ist. Das Video endet damit, dass die Zuschauer ermutigt werden, ihre eigenen benutzerdefinierten Objekte und Klassen zu erstellen.