Learniverse

Learning Object-Oriented Programming with Python

00:00

Hey, welcome everybody.

00:08

My name is Caleb Curry and this video is going to be about object oriented programming

00:12

using Python.

00:13

Now, if you've never seen anything from me, here's my strategy.

00:17

Teach the concept junk up here and then we go hands on coding through what we talked

00:21

about.

00:22

This allows you just to have a better understanding of what and why you're going to be typing

00:26

before you just start copying code.

00:28

So I think it'll make learning a little bit more fun, hopefully.

00:32

And also object oriented programming is more of an approach or a paradigm of programming.

00:37

So if you learn the principles in this video, you'll be able to apply these to other

00:41

programming languages as well, which will help you be overall a better software developer.

00:46

So let's not waste any time.

00:47

Let's just get started.

00:49

So object oriented programming helps us represent things in our code.

00:54

What exactly do I mean?

00:55

Well, one of the challenges with programming is how do we represent data in our code?

01:00

If you're just working with very simple data, this is easy.

01:03

You can use primitive data types and collections.

01:07

So for example, if you just had to store the value five, hey, it's easy, it's just a number.

01:12

If you need to store a string, no problem.

01:18

And heck, you can be wild.

01:20

You could even store multiple things together in a collection such as this.

01:25

And this would be a list in Python.

01:29

So pretty simple data, very simple to represent in our code, just using simple variable types.

01:36

Now what if you want to represent something a little bit more complex?

01:39

There's various ways to do this.

01:41

You could use JSON or XML, you could use just numerous collections, or you could use object

01:48

oriented programming.

01:49

And that's what we're talking about in this video.

01:51

And another positive side effect of object oriented programming is it allows us to represent

01:55

data as a one-to-one relationship to business problems.

02:00

So for example, if you wanted to create software to represent customers, you can make

02:06

customers in your code, and I'll show you what I mean here in a second.

02:09

So the two big things in object oriented programming are classes and objects.

02:13

represents something such as a customer, and then objects are specific examples of that.

02:20

So let's go through an example here.

02:22

If we want to write software to work with customers, we could create a customer class and

02:27

then give it attributes such as the customer name.

02:32

Or let's say you had some kind of subscription website or something, you could have the membership

02:37

type.

02:38

So this is an example of a class.

02:41

By creating our own classes, we can group things in logical units, customers, in this

02:47

case.

02:48

And then we can instantiate very fancy word, this class into what are known as objects.

02:53

So now instead of having these general attributes, we give it specific values.

02:58

So for example, Caleb and my membership type, oh, you better believe it's going to be

03:03

gold premium, you know, and then we could have another object down here such as Brad.

03:11

And we could give him like, I don't know, bronze.

03:15

So these are both objects.

03:17

That is the very first thing you need to understand with object oriented programming.

03:21

We basically define a structure in what's known as a class.

03:24

And then we use that class to create objects.

03:29

So this is an object, and this is another object.

03:35

And this is very ideal when you're going to have a common structure across numerous

03:40

things.

03:41

You know, every single customer is going to have a name and a membership type.

03:45

So that's the very first thing.

03:46

You create classes, you create the attributes, and then you give them specific values

03:51

by creating objects.

03:52

All right.

03:53

So here we are with a completely blank Python file.

03:55

So hopefully you can get to this point.

03:57

If not, be sure to just check out some basic Python videos because I don't want to distract

04:01

from the point, which is creating classes.

04:04

So here's what we're going to do.

04:05

We're going to say class and then give us some name, which is usually what we're trying

04:10

to describe, such as a customer.

04:13

And by convention, I'll use a capital letter.

04:15

Now after the class, you can put a colon and then everything after that is indented.

04:21

However, many spaces you're using with your code.

04:24

So I got four spaces here.

04:26

Now within this class is where we define our attributes.

04:29

So we're going to define the customer's name and the customer's membership type and everything

04:34

else.

04:35

But before we get into that, we need to create a special method and we're going to get

04:40

into methods soon.

04:41

But for now, just copy this code.

04:43

It's going to be DEF, which is used to define a method and it has the exact name underscore

04:48

underscore init underscore underscore.

04:52

and then put parentheses and a colon.

04:55

So what in the world did I just tell you to do?

04:58

Well, basically any time we create a customer, this function is going to be invoked.

05:03

So any of the code that we want to execute every time a customer is created, we put it

05:08

in this indentation inside of the init method.

05:11

Now this can often be known as a constructor or an initializer, basically the function

05:18

invoked when a customer's created.

05:20

So inside of the parentheses, we can put anything we need for a customer to exist.

05:27

So the very first thing and this is just required for it to work, you put the word self.

05:33

Self is the equivalent to this inside of Java or C sharp and sometimes in JavaScript, basically

05:40

self refers to whatever customer we're creating.

05:43

Then what we do is we put any other attributes for this customer.

05:47

So for example, we can have the customer's name and we can also have the customer's

05:51

membership type and any other attributes you want to define, you can put here.

05:58

And then inside of this method, we basically take these and assign them to that customer.

06:05

So we say self dot name is assigned name and self dot membership type is assigned membership

06:15

type.

06:16

So it seems like there's some redundancy here, but let's just talk about it.

06:20

When we say name by itself, we're referring to this parameter in this function, I'm

06:28

guest posting seriously, all right, it's been 27 years.

06:33

Anytime we have name by itself, we refer to this parameter, anytime we put name qualified

06:39

with self, we are referring to whatever customers being created.

06:44

So that's a lot of jargon.

06:45

So let's just see this in action and just to prove that everything's working, we're going

06:49

to say print customer created, all right, it doesn't necessarily prove everything's working,

06:55

but we can at least confirm that this method is being invoked.

07:00

So outside of the class, here's what we do.

07:03

We create a variable, we can just call it C for customer.

07:07

And then we say customer with parentheses.

07:11

And that is how we create a new customer.

07:13

You can see we actually have some required parameters here.

07:17

So we need to pass those in so we can say Caleb and gold.

07:22

So all of the stuff we were just describing, we just did that.

07:25

We created a customer with the name Caleb and the membership type of gold.

07:31

And we can print this, we can say C dot name and we can say C dot membership type.

07:39

Okay, so let's run this and see what happens.

07:41

Well, let's first talk about what happens.

07:43

Okay, first thing, this method's going to be hit because we're creating a new customer

07:47

here.

07:48

It's going to print customer created and then it's going to print the customer's name

07:52

and the membership type hit run customer created and the name is Caleb and the membership

07:58

type is gold.

07:59

All right, so this is pretty much the framework you need to follow for any of the classes

08:03

you're going to create.

08:05

If you want to create another object, we can do that here.

08:08

We could say C to and we create a new customer and this one's going to be Brad and it's

08:12

going to be bronze and we can also print C to so we can say C to dot name and C to dot

08:20

membership type run this and the very first one is Caleb gold and then Brad bronze.

08:28

Now typically you're not going to have print statements inside of the init method.

08:32

So I just wanted to show you guys that so we're going to get rid of that.

08:35

We usually just like to keep this method as thin as possible.

08:39

Its sole purpose is to basically take these arguments we pass in and assign them to the

08:46

object which is going to be referred to in this method itself.

08:49

So when we create this person, self talks about this object C and when we create this person

08:54

down here, self refers to this object C to.

08:58

So the first time name is Caleb, the second time name is Brad.

09:02

Now obviously if you're going to have thousands and thousands of customers, we probably

09:06

aren't just going to have variables to store this information.

09:09

So instead you can have lists or any other data structure full of these.

09:13

So let's just go through an example with a list.

09:16

We could have customers and immediately we could take C and C to, that would work.

09:22

But then we still have these variables and it's still not the most scalable solution.

09:26

So I'm going to be teaching you how to create customers in line.

09:29

So here's how we do that.

09:31

We would basically take this code here, cut it, paste it right here.

09:39

Take this code here, cut it, and paste it right here.

09:45

Now all of this code we can just get rid of it.

09:48

And I'm going to make a new line just to make this a little bit more readable.

09:51

All right.

09:52

So now we have a list of customers.

09:55

So we can grab that first customer's name by saying customers index zero, which will

10:01

grab this one here, then we say dot name, and we get Caleb.

10:08

You can do the same thing with membership type or we can increment this one to grab the

10:13

next customer.

10:14

Brad.

10:15

All right.

10:16

So this is your basic class and how to create a few objects.

10:20

This is going to be the foundation for the rest of the object oriented programming stuff.

10:24

So make sure you have at least a pretty good understanding of what's going on here.

10:28

Now again, this is just something special you got to do.

10:30

This is an example of a method, basically a function defined within a class, and that's

10:36

going to automatically be invoked.

10:38

But we can create our own methods that we can invoke ourselves.

10:42

And we're going to get into that now.

10:45

Methods are one of the most useful things to give our classes and objects a little bit

10:48

more functionality.

10:50

So now we're moving on to the section on methods.

10:53

So if the attributes provide the data and the values that we need to store about a customer,

10:59

then the methods provide the functionality what customers can do or what we can do with customers.

11:06

Now the very first method you were exposed to was this underscore underscore init.

11:14

And this is just one of those methods where you just have to do it.

11:19

It's part of Python's object oriented programming and pretty much any time you see double

11:23

underscores.

11:25

That is a method that already exists that we can actually override and create our own functionality.

11:31

So we created our own version of this init method that did things.

11:38

What did it do?

11:39

Well, it actually assigned a value to the name and the membership.

11:44

And this method, the init method.

11:46

Well, often here, it known as the initializer or what you might probably hear more often

11:52

because it correlates better with other programming languages is the constructor.

12:01

So we constructor.

12:02

It's just a method, a section of code that is executed whenever we create a new customer.

12:10

Inside a Python, the way we create a new customer is in our code.

12:13

We just say customer and have parentheses.

12:20

A lot of other programming languages, this will actually be prefixed with the new keyword.

12:25

Although that is not how we do it inside a Python.

12:27

But if you're coming from like Java or C sharp, you'll probably see that new keyword a lot.

12:32

So the other thing is when we define this init method, we put a couple of things in here.

12:36

The very first one was self.

12:41

And that is going to be put inside of any method we create to work with individual customers.

12:48

So we put self and then anything extra we want to add about customers.

12:54

So we had the name and the membership type.

12:59

Yeah, I think this has actually membership underscore type.

13:05

All right, so this is what it looks like now.

13:08

Now these here, when we define these variables inside of some method we're creating, these are known as parameters.

13:19

So hopefully you have some experience with just creating functions and this is not all brand new to you.

13:24

The parameters are the variables attached to the method we're creating.

13:30

Now what about arguments?

13:32

Arguments is another word that's often thrown around in exchange for parameters, but they're technically different.

13:38

So when we create a customer, we assign values to these parameters.

13:43

And those are passed in here.

13:45

So we had the value Caleb and let's just say the value gold.

13:52

So these here are known as arguments.

13:57

So it's basically which side of the process are you want?

14:01

If you're in the definition side where we define the outline for the method, they're known as parameters.

14:07

If we're actually applying specific values to these variables, they're known as arguments.

14:14

So parameters, definition, arguments in vocation.

14:20

We're not wanting to talk about overriding methods here because I'm tired of talking about stuff that already exists.

14:24

I want to create some of our own stuff.

14:27

So what if we wanted to create a method to actually do something with a customer?

14:32

Let's say we wanted to create a method to upgrade the members, membership status.

14:38

So it might look like this, upgrade membership.

14:41

First parameter in here is always going to be that self keyword whenever we're talking about methods to work with the customers.

14:50

And then anything else, maybe the new membership.

14:53

So we could say new membership.

15:01

So we could define all the code what this does inside of our code.

15:06

And the way we would invoke this is we would take some customer, in this case we have this C variable that's

15:13

referring to a customer and we would say dot, upgrade membership.

15:18

Now as for the arguments, the self is always in place that you never have to pass anything in for that.

15:23

So skip it.

15:25

The new membership, we could put something like bronze.

15:29

And then as for the actual functionality, what does this method do?

15:33

I mean, that's ultimately up to you.

15:34

But as an example, it could basically figure out what to charge the person because I'm downgrading my membership.

15:42

So maybe I need to get a refund.

15:44

And then it could basically invoke our billing system to do that and return whether worked or not.

15:53

So that's another thing with methods they can return a value.

15:56

So for example, the upgrade membership might return the value negative one.

16:02

If it didn't work or it might return zero, if it did work.

16:10

So zero tends to be like it worked fine.

16:14

Negative one is often it broke or any other number could mean something.

16:18

But if you have had experience with like C++ or C, you'll often see something like return zero.

16:28

This basically means it worked.

16:29

But anyways, the point here is not necessarily what this method does, but

16:34

more so that you can create methods to work with individual customers.

16:39

The way you do it is you define it inside of the class and you put this self word here.

16:46

The actual code for this method probably looks something like this.

16:50

So we're going to have a colon.

16:52

And then we would have maybe some API call and assuming that was successful,

16:59

we could say self dot membership type is now assigned the value new membership.

17:09

Like so.

17:10

All right, so that was just a bunch of junk to say that hey,

17:12

we can create our own functions and put them inside of classes to call them methods.

17:16

So let's get some hands on experience with this now.

17:19

So here we have the most basic customer class and we have one method in here,

17:25

the init method.

17:27

And this is where we define the attributes we want attached to each of our customers.

17:32

Now inside a Python, it is a little dynamic in that we can add attributes after the fact.

17:38

So as an example, I can say customers index one to grab this customer here.

17:45

And we can say something like verified and we could set this to some value like false.

17:51

And this is something we can use later on in print and there you go.

17:56

So Python is more dynamic than a language like C sharp or Java,

18:01

because you can add attributes on the fly.

18:04

It's more like JavaScript in that nature.

18:06

However, it is best to put any data that you expect customers to have inside of this init method.

18:15

So it is considered best practice to have that there.

18:18

So let's go ahead and put this back to how it was.

18:21

We will get rid of this verified line because we're not going to need that.

18:26

And we're just going to print the name.

18:29

So beyond this init method, we can create other methods and just do that below here.

18:34

So for example, the one we talked about was, I forget the exact side.

18:38

I think it was upgrade membership or let's just do update memberships because, you know,

18:42

maybe we could use it to downgrade the membership as well and we're going to have self in there.

18:50

And then we can have the new membership that we want to change it to.

18:54

So the most basic thing we're going to do is just say self dot membership type and change it to the new membership.

19:04

And we can just check to see if this works.

19:07

Let's go ahead and print the membership and invoke this by saying customers index one dot update membership and pass in actually will pass in gold.

19:23

It's going to put bronze there, but it's already bronze.

19:25

So we'll stick to upgrading this to gold.

19:28

And then after the fact what we're going to do is we're going to print the membership type and just confirm that it was changed.

19:37

So let's run this.

19:38

All right, we have an issue.

19:40

We have to print the membership type.

19:43

Sorry.

19:43

So run this.

19:44

We start with bronze.

19:46

This method gets invoked on the customer.

19:50

And then the membership is gold.

19:53

Now, this method as is is kind of pointless because you can actually change attributes directly.

20:02

So instead of doing update membership, you could just say membership type and assign it the value gold.

20:11

This works just the same way and we don't even need this method anymore.

20:15

You can just get rid of it.

20:17

However, if you need to do custom functionality, which is a little hard to see in our very simple application, but here are some examples of custom functionality, you could invoke an API, you could update a database, you could charge the customer, you can calculate costs, you can conquer the world and pretty much anything else.

20:42

So anytime you need some kind of functionality like this, the appropriate place to do that is within a method.

20:48

So the easiest way to simulate something like this is to just print.

20:53

And we'll just say calculating costs just to simulate some math there and charging the customer.

20:59

So we'll leave that as that there.

21:02

And now you can see that functionality because if we invoke this method, update membership, pass in a value, you can see that it actually shows up.

21:12

Down here in the console.

21:13

Now I wanted to take a second just to talk about the self here.

21:16

Anytime you want these methods to appear on a customer, then you put that self keyword there.

21:22

So you could create a method such as read customer and leave off the self.

21:27

Well, this is not going to be invocable on any individual customer.

21:33

So let me just write your print and we can just imagine reading customer from DB.

21:40

Well, if we try to invoke this, we say something like customers would just grab that first customer in that list.

21:46

And then we say read customer run this.

21:50

It says take zero positional arguments, but one was given.

21:54

What in the world does that mean?

21:56

Well, when we invoke a method like so on an object, a customer object, the instance itself is implicitly passed.

22:05

So that's what gets assigned to this self variable here.

22:08

So when we don't have that there, it's basically saying, yo, you're passing something,

22:13

but there's nothing to apply it to.

22:16

It's not working.

22:17

So that's what this type error here means.

22:20

So what would you do with this method instead?

22:22

Well, this is something that would be used if you want a method to describe

22:26

customers in general, but not any specific customer.

22:29

So for example, if we're just reading a customer from the database,

22:33

that's not tied to Caleb, but that has nothing to do with Caleb.

22:37

So here's what we would do instead.

22:39

We would just invoke it on the customer class like so and run it now.

22:46

Here it says reading customer from DB.

22:48

This method is often known as static methods.

22:51

So basically methods that are not attached to any individual object,

22:56

but instead are invoked on the class itself.

22:59

So here's an example from some other code that I wrote.

23:02

Basically, it's this method parse camera.

23:05

It does not have self in the parameter list.

23:07

And this is the code that I used to basically read some data from a text file and

23:13

parse it into information and it ultimately returned a new camera object.

23:18

So although we're not going into a complex example where we implement something like this,

23:23

I was hoping that just by showing you an example without self,

23:27

you would have a better understanding of self.

23:30

And as a result, have a better understanding of your own true self.

23:34

But enough of this talk about self, let's get back to methods.

23:37

The only other thing I wanted to talk about was first, let's just get rid of this read

23:42

customer. We're not going to need that.

23:43

There are a couple of other methods we can override that are definitely useful.

23:48

So the very first one you should know about is STR.

23:53

And this is also going to take self and this is going to be invoked anytime.

23:58

We try to convert a customer to a string.

24:03

So we created this method and now let's try to invoke it.

24:07

How do we invoke it?

24:09

Well, instead of printing customers to our membership type,

24:12

let's just print that individual customer.

24:15

And now what happens when we run this, it says returned non string.

24:20

So anytime we override this string method, we actually need to return a string.

24:25

So we can say return and in here, we could say self dot name plus a space plus self dot membership

24:36

type. Running this now, we can look through our code here.

24:40

Any time this is executed, it says converting to string, which is basically hitting this line here.

24:48

And then it prints the person's name and their membership type at once,

24:54

which is very, very convenient.

24:55

If, for example, you did not have this method here,

24:59

let's just comment this out for a sec.

25:02

When we printed an entire customer, so we printed this customer right here,

25:07

what it would do is it would just give us a memory address and say the type,

25:11

which is useful. I'm not going to say it's not useful.

25:15

However, oftentimes we want to get the actual data and not just the location of the data.

25:21

So that is why we would override the string method.

25:26

And we can also get rid of this print here.

25:28

I was just showing you guys that for simplicity.

25:31

So now we can very easily see our customers just by printing them here.

25:36

So what a useful line of code might be would be to print all of our customers.

25:42

So let's go up here into our class and we're going to define a new method.

25:47

We'll just say print all customers and this is not going to have self.

25:52

However, I will take a list of customers and we can say for customer in customers,

25:59

print customer.

26:00

So you can see oftentimes we'll put methods in here that are somewhat related to customers

26:04

just for organization's sake and we don't need to put that self in the parameter list.

26:10

So now inside of our code, we can create a list of customers.

26:14

So what we'll do is just say customer the class with capital C there,

26:18

dot print all customers and we'll pass in our customers list.

26:23

We defined right here like so and running this,

26:27

we get all of the information for all of our customers.

26:30

Another useful method is the equals method.

26:32

So we could say death underscore underscore EQ underscore underscore self.

26:39

And this is also going to have another parameter.

26:41

We're just going to call it other, which is going to refer to what we're comparing

26:46

our customer to.

26:47

So this will see if two customers are equal.

26:50

So what we can do is we can say if self dot name is equal to other dot name and self dot membership

27:00

type is equal to other dot membership type.

27:05

Then what we're going to do is we're going to return true, otherwise we're going to return false.

27:11

So pretty much if you're comparing two customers and they have the same name and they have the

27:15

same membership type, then you can assume they're the same customer.

27:19

Now that's a pretty weak comparison, but you can do whatever kind of comparison in here you want.

27:24

You know, maybe you compare addresses, maybe you compare social security cards,

27:29

maybe you compare DNA sequences, whatever you got to do,

27:33

you can pretty much compare whatever you want here.

27:34

Just remember that any of these attributes are comparing,

27:37

you're probably going to need to define them up in the init method.

27:41

So let's just test this out a couple of times.

27:44

We have two customers down here and what we can do is we can print to see if they are equal.

27:50

So we'll say print.

27:54

Customers index zero is equal to customers index one.

27:59

Running this and we get false, which is to be expected because they're two totally different

28:03

people, but if we change their name, let's go with Caleb and go with again, we run this

28:09

now we get true. If we did not override the equals method, then by default it compares by memory

28:16

location. So we'll just comment this out for a second.

28:19

And even though logically it seems like these are the same customers,

28:22

we run this and we get false. And the reason that is is you can actually see if you pass these

28:28

to ID and just put a comma here, run for got a parent sees there, run this and you can see

28:39

that these are two different objects in memory. So by default, it looks at these IDs,

28:46

sees that they're different and says yuck nope, these are not the same people.

28:49

So we're going to say false for the equals. However, we can override that behavior with this

28:54

equals method. And running this, we still have different IDs, but if we were to compare the data

29:04

like so getting rid of this ID here, we run this and we get true.

29:09

And the last method I want to discuss with you right now is the hash method. I've done stuff

29:14

on hash. If you need to know the juicy details. However, for now, I'd recommend just saying underscore

29:20

underscore hash is none. This isn't going to really ruin any functionality or break anything.

29:27

The only thing is that you're not going to be able to use your customers inside of hashable

29:32

data structures. So I mean, you can use them in the value side of a dictionary, but not trying to

29:38

get in the weeds here. But let me just show you real quick. If we were to create a set

29:42

and try to pass in customers zero, this is going to give us an error on hashable type customer.

29:52

But if you need to understand hashing and all that, do some extra research. One other thing is you

29:56

can actually print this list altogether at once. So you could say print customers. And when we do

30:02

this, we don't get the pretty output like we would expect in our method print all customers.

30:07

So one way we can fix this is to override the underscore underscore R EPR for representation

30:15

probably. And we can just assign this to the same thing as the stir method. So we'll just say

30:22

underscore underscore stir. And I think that should fix the problem. Now you get all of the data

30:29

in a nice list. And you can just change the data right here. So there you go. All right, I think

30:36

that's all the overriding methods I'm going to be talking about right now. So let me just zoom

30:40

out for you guys. Make sure you can get a good overall picture of the code. We'll start at the top

30:45

and just scroll down to the bottom real quick. There you go. All right. So now we're going to be

30:53

talking about some object oriented programming principles. These are the three pillars of object

30:59

oriented programming. If you haven't heard of them yet, you probably will a bunch in the future.

31:04

And they are encapsulation inheritance and polymorphism. Now for being honest, each one of these

31:12

needs a dedicated video to go into the depths. So we're just going to scratch the surface.

31:18

But the main thing you need to understand here is that these are the Y of object oriented

31:23

programming. Why would you want to use object oriented programming? Well, if you need to do

31:28

any of these three things, you can do that with OOP. It's like the value proposition. This is what

31:34

you can get using OOP. These things can also help you in your object oriented programming journey

31:40

by enabling you to do certain things. So it basically allows us to have more scalable code

31:47

and so forth. But not all of the time because some of these are even controversial,

31:51

such as inheritance. If you do it wrong, you can actually make your code more complex

31:56

and not really help anybody. And the approach to this really depends on the language because I

32:03

think different languages have different approaches and ways of thinking. And for Python,

32:09

it's a very open free kind of language. The way you feel, you know, the vibe of Python is very

32:15

open and free. As opposed to Java, it's very strict. And what you can and can do is very thorough.

32:22

So when we are creating this stuff in Python, our classes might end up being very thin. And if

32:28

you're coming from, say, a Java background, you might be like, what? And it does take some time to

32:34

kind of adjust to the approach. But basically in Python, our approach is if you don't need it,

32:40

don't do it. And also the person using your classes, you can trust them to be well educated

32:46

and they're going to use your classes in an appropriate way. Whereas the approach for other languages

32:52

might be to restrict anybody from doing anything wrong. But as a result, the classes end up being

32:58

huge, huge files with tons of code. So I don't think there is one yes or no or right or wrong way

33:04

of doing this stuff. And I don't want to start any debates in the comments. But I do want to try to

33:11

keep our classes very thin and just do exactly what we need. No extra. All right, with that

33:16

prefix in mind, let's just go through each one of these very briefly in encapsulation. The whole

33:21

idea behind encapsulation is that you can hide the inner details of a class or of certain data.

33:29

And you only need to share or expose what is needed for the user of the class to use this class.

33:36

So we might have the backing field, as you might hear it called, store some data. And instead of

33:43

just people accessing this data directly, they access it through getters and setters,

33:58

which are basically methods that will give us access to the data. So when we have an attribute

34:05

such as name, well, we don't necessarily have to have that same exact thing on the back end.

34:15

There is a separation here where you only set the data through a method and you only get the

34:23

data through a method. So that is the most basic form of encapsulation, the most popular thing

34:28

inside of languages. You often have tons of getter methods, tons of setter methods inside of Python.

34:33

We don't really create those unless we need to. And there's a specific way we need to do that

34:39

with what's known as a property. And the good thing about a property is that you can

34:48

add in a property when it is needed and none of the invoking code changes. So you would still

34:53

access that data like so. But now we added some extra functionality in a setter method

35:00

and a getter method using a property. So we're going to touch on that briefly.

35:05

And inheritance allows us to automatically have certain attributes for objects because they're

35:10

defined in a base class. So we've been talking about the example of a customer.

35:19

And this is for some subscription website. Let's say it's a subscription website to get courses.

35:24

Well, we could also have a teacher. And these are going to have a lot in common. So we could

35:31

create a base class with all of the commonalities. And let's say this could be called user.

35:38

Then when we define a customer, it's automatically going to have anything defined inside of this

35:44

user class. So that is the basics of inheritance. Polymorphism is kind of just an extra step of

35:50

that where we can treat customers and teachers as the same thing if we approach them as users.

36:00

So we could say, hey, users, we need you to do this or we need to update this data.

36:07

And as a result, since a customer is a user, that's okay. And a teacher is a user, that's okay.

36:12

But the customers can do something specific and the teachers can do something specific.

36:16

You know, there might be a time of the month where we do the finances for the customers.

36:21

We charge them money. And for the teachers, we pay them money. But we can address all of them

36:28

together as a set of users. So yeah, when you're just talking about the theory here without

36:33

some examples, it can be a little bit confusing. But I just wanted to just get a really quick

36:39

overview of these three pieces. And now we're going to go hands on just to get some really

36:44

simple examples of these. So my goal now is to give you what you need for encapsulation, inheritance,

36:48

and polymorphism. Probably can't do it justice in just a few minutes, but we're going to give you

36:53

the essentials here. So this is our class so far. We have a customer class. Pretty simple.

37:00

And then we have a list of two customers and we print the customers here. So the very first thing

37:05

I want to do is show you guys how to create a property. Now, a property is basically just like a normal

37:13

attribute, but instead of it being just a variable, such as name here or membership type,

37:22

it actually has an extra layer. And this layer allows us to basically abstract away the variable

37:29

itself using methods. So it allows us to have additional functionality. It's pretty cool if you

37:36

need it. But in my opinion, don't use it if you don't need it. And that's just the approach

37:42

of Python. That's what I've seen other people do. And that's what I have learned is best practice.

37:47

However, if you're coming from, let's say C sharp and C sharp, you just make properties

37:52

from the get go. So if you want to make every single one of your attributes, a property,

37:56

then be my guess, but I don't think you're going to be adding a whole lot of value. And we want

38:00

to make these classes as much potent value as possible if that makes any sense at all. So let's

38:06

just get into it enough of my rambling. So if we wanted to make name a property, what we're going to do

38:11

is we're going to create two methods. We're going to create one that's called name,

38:16

so we'll say name like so. As always, we're going to put self in there. And what this is going to do

38:22

is it's just going to return self dot underscore name. When you see something prefix with a single

38:29

underscore, this is basically a way to say, Hey, this is private. Don't touch this if you're not

38:36

within the class. So outside of the class, you should not be typing anything like customer index

38:45

zero dot underscore all these underscore things. Don't touch them. You can see your underscore name

38:51

right there. Leave that alone. So we're going to get rid of that and go back up here and leave

38:56

this as so. And one extra step we're going to put at property. This is an example of a decorator.

39:04

It gives extra functionality. And this is how we say that this is a property. So when we try to

39:12

get the name, this is going to be invoked. The underscore name is basically the backing field. It's

39:19

the data behind the scenes. And anytime we try to set this data, we need, we're actually going to

39:24

invoke another method. And the way you define that is you say at and then you put whatever the attribute

39:30

is. So name dot setter. And then we say def name self. And then the data that we're going to assign

39:39

it. So we'll just call that name here. And then inside of here, we're just going to assign

39:46

a value to self underscore name. And we're going to assign it the parameter value here. So if we

39:54

save this and run, we get the same exact output, which is what we want none of the invoking

40:00

code should have to change to use this. However, we can know that there's an extra step to get

40:06

and set this data where we can actually add functionality in here if we wanted. So we'll just say print

40:12

getting name and print setting name, running it now. You can see some extra stuff is going on behind

40:21

the scenes. These methods are being invoked. Anytime we get or set the value of name. But note

40:29

that we don't actually have to invoke it like a function, we can just get it like normal. So we

40:34

can say customers, let's say we want that first customer dot name around this we get Caleb,

40:41

we did not have to say name with parentheses or get name or anything like that. We just used it

40:48

like normal. And that's what we want. So that is how to create a property. You can do any kind of

40:54

functionality you want in here. You may also see what's known as a delete or which will be used

41:00

if you use the Dell operator. So that'll look like this name dot the leader def name self. And then

41:10

we just say del self dot underscore name. So we're not going to use that a whole lot. But just in

41:17

case you want to know about that now what that means is we can go down here and we could say

41:24

Dell customers index zero dot name and running this it's going to delete it and it's no longer

41:32

available. If we got rid of that line it works fine. So let's go in here and just delete that extra

41:38

printing because it's not really doing anything. Just know that that is where the functionality would

41:44

go. Now let's take a moment to talk about inheritance. And I'm going to keep this really simple. But

41:49

basically we can create another class that customer derives from such as user. And we'll just give

41:56

this user a method. So for example, we'll say def log. So if we wanted to log some data or something

42:02

and inside of here, don't forget self. We always want to put self there. Inside of here we could just say

42:09

print self. So as is if we go down to the very bottom of our code and we try to invoke that

42:19

so let's just grab our first customer and we say log. We run this and it has an issue. But if we

42:27

inherited from that base class, then this would be available to us. So here's how you do that.

42:33

Let's go back up to where we define customer and inside of parentheses you can put user.

42:39

And now anything defined inside of a user is also going to be defined in a customer.

42:44

So when we run this now, you can see that this log here works and actually prints all of that

42:51

user's data. So that's pretty simple when it comes to inheritance. Nothing too crazy. The next step

42:58

of this is polymorphism. So if we actually had a couple of classes that inherited from user,

43:06

let's say we went in here and we created a teacher or something. And this also inherits from user.

43:12

And we'll give teacher a new log method. And what this is going to do, it's going to do pretty

43:20

much the same thing but it's going to say I'm a teacher. Instead of just printing all the details

43:25

about them, it's just going to do this blanket statement for all teachers. So now you can really see

43:31

polymorphism if you have a list of teachers and customers. You can treat them all as users. So let's

43:38

scroll down to the bottom of our code here. And we have two customers in here. Let's go ahead and

43:43

add a teacher. And just to make sure that we can invoke the log method on each one of these, we'll

43:50

try it on the second customer. That works. And we can also try it on the teacher and you see that

43:58

works. So what we can do now is we can basically take this concept where we take the log method

44:04

and we're going to do that for all of these people. So instead of customers here, we're going

44:08

to have users and we say for user and users and we say user dot log. So we invoke the log method

44:18

on every single item in this list. And we run it and we don't get any issues. So what exactly

44:25

is the magical part here? Well, we treat them all as users and we invoke dot log because that is

44:32

part of the user definition. But if a derived class has an override, such as in this case here,

44:40

we overrid the log method and gave a new implementation, then it's going to do the teacher

44:46

version of that. If we did the same thing for customer, it would do the same thing. So let's say we

44:52

take this, paste it in here. We can say, I'm a customer. And running this, we get I'm a customer,

45:02

I'm a customer and I'm a teacher. Nowhere does it just do this general print. This would just be

45:10

for the users and you don't see that anywhere. So that is the basics of polymorphism,

45:15

basically the ability to create code that works with general users, but is still fully functional

45:23

when you're past something more specific, such as a teacher or a customer. Now, I know that's a lot

45:29

and probably these principles will take a lot more practice to truly grasp and see where to

45:35

apply these. We've touched all the basics of object-oriented programming and now some more advanced

45:39

stuff might come a little bit easier. If you're looking for other stuffs of research, you can look

45:43

into object relational mappers. This is basically going to take database data and correlate it to

45:50

a bunch of objects in your code. So instead of just working with hard-coded stuff in here,

45:55

you could be working with actual teachers and customers in a database. You could also look into

46:01

some different object-oriented design patterns. These get pretty advanced and basically

46:06

teach you how to design programs using these OOP principles. And there's probably like six

46:12

petroleum other things you can study. So just look up some more advanced object-oriented programming

46:17

things and start learning. Thank you guys for watching. If you've enjoyed this content,

46:21

please be sure to subscribe to this channel. Also be sure to check out my channel,

46:24

kaleb curry. We got stuff on Python, JavaScript, C++, Java, C sharp database design,

46:31

all kinds of different things and would love to have you guys there. So be sure to check

46:35

it out and I'll see you in the next one on the next one. Next one to the next one to the next one.

00:00

Introduction to OOP

01:40

Classes and Objects

04:00

Creating a Customer Class

07:00

Defining Attributes in Classes

10:40

Understanding the Init Method

15:52

Returning Values from Methods

17:20

Creating Custom Methods

21:13

Using the Self Keyword

24:02

Understanding String Representation

30:53

Exploring OOP Principles

33:28

Encapsulation in OOP

35:04

Understanding Inheritance

41:43

Polymorphism Explained

45:34

Advanced OOP Concepts

10:00

Why is the init method crucial in OOP?

02:13

How do objects differ from classes in Python?

13:32

What role do parameters and arguments play in methods?

01:54

How does OOP help represent real-world problems?

15:52

How can methods return specific values in Python?

21:16

Why is the self keyword crucial for method accessibility?

24:19

How does overriding the string method enhance class usability?

30:58

What are the three pillars of object-oriented programming?

33:42

What are getters and setters in encapsulation?

35:14

How does inheritance simplify code management?

42:58

What is polymorphism in OOP?


DebuggingAPIMethod (computer programming)Mutator methodSoftware developmentAlgorithmInheritance (object-oriented programming)Python (programming language)Software architectureObject-oriented programmingClass (computer programming)Property (programming)Program optimizationInformation hiding

Description

In this video, the author introduces the concept of object-oriented programming (OOP) using Python. He explains that OOP is a programming paradigm that allows developers to create more organized and maintainable code by representing real-world objects in their programs. The video covers the basics of OOP, including defining classes and objects, inheritance, polymorphism, and encapsulation. The author also highlights the benefits of using Python for OOP, such as its simplicity and readability. Throughout the video, the author provides hands-on coding exercises to help viewers understand the concepts better. The video is suitable for beginners who want to learn OOP in Python.