1
00:00:00,000 --> 00:00:03,990
The object model in Python is really very powerful and well-designed.

2
00:00:04,000 --> 00:00:07,990
And Python does support inheritance and polymorphism.

3
00:00:08,000 --> 00:00:13,990
So let's take a look at an example of how we do inheritance and polymorphism in Python.

4
00:00:14,000 --> 00:00:28,990
First, we'll make a working copy of oop2.py, and we'll open our working copy, and

5
00:00:29,000 --> 00:00:33,990
here we have a number of classes, and you'll see we have these animals:

6
00:00:34,000 --> 00:00:41,990
Dog, Person and Duck. And each of these inherits AnimalActions.

7
00:00:42,000 --> 00:00:46,990
So AnimalActions has the code in it.

8
00:00:47,000 --> 00:00:48,990
It has these four methods:

9
00:00:49,000 --> 00:00:52,990
quack, feathers, bark and fur. And you will notice that each of these methods is

10
00:00:53,000 --> 00:00:53,990
defined on one line.

11
00:00:54,000 --> 00:00:58,990
So because each of these methods has just one line of code, you can do it all on one line.

12
00:00:59,000 --> 00:01:04,990
You have the def keyword, and then you have the name of the method and then the code.

13
00:01:05,000 --> 00:01:08,990
In this case, it's return self.strings 'quack'.

14
00:01:09,000 --> 00:01:14,990
This notation here is because strings is a dictionary, and we'll get into that

15
00:01:15,000 --> 00:01:19,990
later on in the course when we talk about data types. But these strings,

16
00:01:20,000 --> 00:01:26,990
self.strings, are actually defined in the classes that inherit AnimalActions,

17
00:01:27,000 --> 00:01:30,990
and so this is an example of inheritance.

18
00:01:31,000 --> 00:01:35,990
This is also an example of data abstraction, because each of these classes

19
00:01:36,000 --> 00:01:37,990
has different data.

20
00:01:38,000 --> 00:01:41,990
So here we have the duck, and it has these four strings in it:

21
00:01:42,000 --> 00:01:46,990
quack, feathers, bark and fur. And the duck says quack. The duck has gray

22
00:01:47,000 --> 00:01:50,990
and white feathers. The duck cannot bark. The duck has no fur. And then we

23
00:01:51,000 --> 00:01:55,990
have a Person, which also inherits AnimalActions, and the Person has quack,

24
00:01:56,000 --> 00:01:57,990
feathers, bark and fur.

25
00:01:58,000 --> 00:02:01,990
But for quack, instead of saying quack, the person imitates a duck.

26
00:02:02,000 --> 00:02:04,990
The person takes a feather from the ground and shows it for feathers.

27
00:02:05,000 --> 00:02:07,990
For bark, the persons says woof.

28
00:02:08,000 --> 00:02:11,990
For fur, the person puts on a fur coat, and then we have dog, which also has

29
00:02:12,000 --> 00:02:16,990
quack, feathers, bark and fur, and does dog-like things with these.

30
00:02:17,000 --> 00:02:22,990
So this allows us to abstract all of this data, and to use it in exactly the same

31
00:02:23,000 --> 00:02:24,990
way in each of these classes.

32
00:02:25,000 --> 00:02:29,990
Because each of these classes inherits AnimalActions, these methods become

33
00:02:30,000 --> 00:02:32,990
available in each of these other classes.

34
00:02:33,000 --> 00:02:39,990
So when I create a duck object, here we have donald = Duck,

35
00:02:40,000 --> 00:02:45,990
that duck object will have these dictionary strings, Quaaaaak!

36
00:02:46,000 --> 00:02:50,990
The duck has gray and white feathers, and it will also have these action methods:

37
00:02:51,000 --> 00:02:52,990
quack, feathers, bark and fur.

38
00:02:53,000 --> 00:02:58,990
And so I can call duck.quack and I can call duck.feathers.

39
00:02:59,000 --> 00:03:06,990
The beauty of this is that I can also define a Person, john, and I can call

40
00:03:07,000 --> 00:03:11,990
in_the_forest, where it's expecting a duck, I can call it with john.

41
00:03:12,000 --> 00:03:15,990
And so here we have an iterator. We are calling for o in ( donald, john, fido),

42
00:03:16,000 --> 00:03:19,990
so o will be sequentially don and john and fido.

43
00:03:20,000 --> 00:03:21,990
john is a person; john is not a duck.

44
00:03:22,000 --> 00:03:29,990
But in_the_forest(o) calls in the forest with john and in_the_forest expects a

45
00:03:30,000 --> 00:03:33,990
duck object, so it calls duck.quack and duck.feathers.

46
00:03:34,000 --> 00:03:39,990
Well, john implements - because john is a person, a person inherits AnimalActions,

47
00:03:40,000 --> 00:03:42,990
and it implements quack and feathers.

48
00:03:43,000 --> 00:03:44,990
So this is called polymorphism.

49
00:03:45,000 --> 00:03:47,990
And let's see how this works.

50
00:03:48,000 --> 00:03:53,990
Remember, we are going to be calling in the doghouse and in the forest for each

51
00:03:54,000 --> 00:03:54,990
of these three objects:

52
00:03:55,000 --> 00:03:56,990
donald, john and fido.

53
00:03:57,000 --> 00:03:57,990
A Duck, a Person and a Dog.

54
00:03:58,000 --> 00:04:01,990
First, we'll call in the forest for each of them, and then we'll call in the

55
00:04:02,000 --> 00:04:03,990
doghouse for each of them.

56
00:04:04,000 --> 00:04:08,990
So I am going to run this.

57
00:04:09,000 --> 00:04:09,990
And we'll take a look at the results.

58
00:04:10,000 --> 00:04:12,990
In the forest, we have Quaaaak!

59
00:04:13,000 --> 00:04:14,990
And the duck has gray and white feathers.

60
00:04:15,000 --> 00:04:16,990
So we are calling Quaaaak!

61
00:04:17,000 --> 00:04:19,990
and feathers for each of these.

62
00:04:20,000 --> 00:04:20,990
We are calling Quaaaak!

63
00:04:21,000 --> 00:04:23,990
and feathers also for the person, and it says the person imitates a duck, and

64
00:04:24,000 --> 00:04:28,990
the person takes the feather from the ground and shows it, and also for the dog,

65
00:04:29,000 --> 00:04:32,990
and then in the doghouse, the duck cannot bark, the duck has not fur, the person says woof!

66
00:04:33,000 --> 00:04:35,990
the person puts on a fur coat and then for the dog Arf!

67
00:04:36,000 --> 00:04:39,990
and the dog has white fur with black spots.

68
00:04:40,000 --> 00:04:47,990
So this is an example of polymorphism and inheritance in Python.

69
00:04:48,000 --> 00:04:53,990
Now real quick, I want to also show you this example that's been rewritten as a Model-View-Controller.

70
00:04:54,000 --> 00:04:59,990
Model-View-Controller is a very common pattern in object-oriented programming,

71
00:05:00,000 --> 00:05:03,990
and I just want to show you that we can do exactly the same thing and actually

72
00:05:04,000 --> 00:05:06,990
separate it out a little bit further.

73
00:05:07,000 --> 00:05:11,990
In this case, we are not bothering to define the data for that which doesn't

74
00:05:12,000 --> 00:05:13,990
apply for each of these.

75
00:05:14,000 --> 00:05:15,990
So the dog doesn't quack,

76
00:05:16,000 --> 00:05:18,990
so I am not having a string for dog.

77
00:05:19,000 --> 00:05:24,990
So this is the modeling, and we have the model for the duck and the person and

78
00:05:25,000 --> 00:05:28,990
the dog, and each of these inherits AnimalAction. And in this context, we don't

79
00:05:29,000 --> 00:05:32,990
really care about the implementation of AnimalActions, because all that matters

80
00:05:33,000 --> 00:05:39,990
is that we are modeling each of these types of objects.

81
00:05:40,000 --> 00:05:46,990
The view is the implementation of how do we view each of these things?

82
00:05:47,000 --> 00:05:47,990
So we have these four methods:

83
00:05:48,000 --> 00:05:53,990
bark, fur, quack and feathers. And they each call doAction with the word bark,

84
00:05:54,000 --> 00:05:54,990
fur, quack and feathers.

85
00:05:55,000 --> 00:06:00,990
And then doAction is a local method, and you will notice it has this underscore.

86
00:06:01,000 --> 00:06:04,990
That doesn't make it special in Python, but it does tell the person who is

87
00:06:05,000 --> 00:06:08,990
reading it that this is something that's just going to be called internally.

88
00:06:09,000 --> 00:06:10,990
You are not going to want to call this on the object.

89
00:06:11,000 --> 00:06:15,990
You are just going to want to call it from inside of the object, or inside of the class.

90
00:06:16,000 --> 00:06:21,990
So this gets called from each of these methods. And if the action is not found in

91
00:06:22,000 --> 00:06:25,990
the strings, then it has a default that it does, where it says, this animal name

92
00:06:26,000 --> 00:06:34,990
has no action. And so that allows us to model these, and to actually expand them,

93
00:06:35,000 --> 00:06:40,990
and define more actions, and to not have to worry about doing a whole lot of

94
00:06:41,000 --> 00:06:47,990
extra modifications to the parent class. And then the controller is, of course,

95
00:06:48,000 --> 00:06:50,990
how we call all of this stuff, which is pretty much the same.

96
00:06:51,000 --> 00:06:56,990
So this does exactly the same thing. If I go ahead and run this, we'll see that

97
00:06:57,000 --> 00:07:04,990
our result is exactly the same, but what we have here is a refined version of the

98
00:07:05,000 --> 00:07:08,990
same thing using a model, view and controller pattern.

99
00:07:09,000 --> 00:07:13,990
It's a contrived example, but this is commonly how we can do object-oriented

100
00:07:14,000 --> 00:07:24,000
programming in Python 3.

