1 00:00:00,792 --> 00:00:05,705 In C# objects, we learned that inheritance can be used to create an is 2 00:00:05,705 --> 00:00:08,219 a relationship between two types. 3 00:00:08,219 --> 00:00:12,680 For example, map location is a type of point. 4 00:00:12,680 --> 00:00:15,720 We subclass the point class to create a new type of 5 00:00:15,720 --> 00:00:18,620 point which we called map location. 6 00:00:18,620 --> 00:00:23,660 Map location, by virtue that it inherits from point, also has fields for 7 00:00:23,660 --> 00:00:24,830 X and Y coordinates. 8 00:00:26,030 --> 00:00:29,360 Objects often share many of the same attributes and 9 00:00:29,360 --> 00:00:32,060 behaviors as other types of objects. 10 00:00:32,060 --> 00:00:34,200 A classic example is an animal. 11 00:00:35,270 --> 00:00:38,990 All animals have similar characteristics and behaviors. 12 00:00:38,990 --> 00:00:44,350 For example, a defining characteristic of all animals is the ability to move. 13 00:00:44,350 --> 00:00:48,630 There are two types of animals, vertebrates and invertebrates. 14 00:00:48,630 --> 00:00:50,400 Vertebrates have backbones and 15 00:00:50,400 --> 00:00:53,820 invertebrates don't, but they're both still animals. 16 00:00:53,820 --> 00:00:55,620 So, they can both move. 17 00:00:55,620 --> 00:00:58,480 But, not all animals move in the same way. 18 00:00:58,480 --> 00:00:59,240 Mammals and 19 00:00:59,240 --> 00:01:03,730 birds are both types of vertebrates, but they move quite differently. 20 00:01:03,730 --> 00:01:07,210 In object oriented programming, we also need the ability for 21 00:01:07,210 --> 00:01:11,540 objects to behave differently based on the type of object that they are. 22 00:01:11,540 --> 00:01:13,710 This is called polymorphism. 23 00:01:13,710 --> 00:01:17,920 And it's one of the core principles of object oriented programming. 24 00:01:17,920 --> 00:01:19,470 Let's see what this looks like in code. 25 00:01:21,120 --> 00:01:24,030 Let's create a new type of invader. 26 00:01:24,030 --> 00:01:25,870 First let's create a new file. 27 00:01:27,152 --> 00:01:30,170 We will call our new invader type shielded invader. 28 00:01:30,170 --> 00:01:35,000 So we'll name this file shielded invader.cs. 29 00:01:35,000 --> 00:01:39,480 We'll copy the namespace and class name from invader paste 30 00:01:39,480 --> 00:01:43,510 it in shielded invader and add the closing curly braces. 31 00:01:43,510 --> 00:01:47,750 Instead of invader, we want our class to be named shielded invader. 32 00:01:47,750 --> 00:01:50,030 And we want it to inherit from invader. 33 00:01:51,250 --> 00:01:55,900 We'll add a constructor that takes a path parameter and all this constructor will do 34 00:01:55,900 --> 00:02:00,510 is pass the path parameter up to the constructor of the base class like so. 35 00:02:02,320 --> 00:02:04,960 Now we have a new type of invader. 36 00:02:04,960 --> 00:02:06,940 As the code stands right now, 37 00:02:06,940 --> 00:02:11,660 shielded invader behaves exactly like the original invader class. 38 00:02:11,660 --> 00:02:16,470 That's because it inherits all of the attributes and behaviors from invader. 39 00:02:16,470 --> 00:02:20,100 Let's make it so that when a shielded invader is hit, 40 00:02:20,100 --> 00:02:23,180 there's a chance that it won't sustain any damage. 41 00:02:23,180 --> 00:02:27,630 For that we need to change the way decrease health method works. 42 00:02:27,630 --> 00:02:32,120 But wait, the decrease health method is in the invader class definition. 43 00:02:32,120 --> 00:02:34,780 We don't have it here in ShieldedInvader. 44 00:02:34,780 --> 00:02:38,250 Let's take a look at the decrease health method in invader. 45 00:02:38,250 --> 00:02:40,710 When the decrease health method is called, 46 00:02:40,710 --> 00:02:44,450 it will decrease the health of the invader by the factor passed in. 47 00:02:44,450 --> 00:02:48,200 This is exactly how we want it to work for most invaders. 48 00:02:48,200 --> 00:02:51,150 But if the invader is a shielded invader, 49 00:02:51,150 --> 00:02:55,560 we don't always want to decrease the health every time the method is called. 50 00:02:55,560 --> 00:02:59,440 One way we could implement this is to check if the current object 51 00:02:59,440 --> 00:03:01,840 is an instance of shielded invader. 52 00:03:01,840 --> 00:03:08,209 We can type, if(this is ShieldedInvader), 53 00:03:08,209 --> 00:03:11,560 then do something here. 54 00:03:14,380 --> 00:03:19,350 Else decrease health by the factor passed in. 55 00:03:19,350 --> 00:03:22,180 There are many problems with writing code like this. 56 00:03:22,180 --> 00:03:26,050 For one, it requires the invader class to know about the other classes that 57 00:03:26,050 --> 00:03:27,190 inherit from it. 58 00:03:27,190 --> 00:03:31,850 This is not an extendable way to add new types of invaders because 59 00:03:31,850 --> 00:03:36,580 we have to change the invader class each time we want to add a new type of invader. 60 00:03:36,580 --> 00:03:41,290 Also, our elegant single line method would end up being polluted 61 00:03:41,290 --> 00:03:45,830 by code that doesn't directly have to do with this specific type of invader. 62 00:03:45,830 --> 00:03:50,630 We could eventually end up with a lot of these if this is statements here. 63 00:03:50,630 --> 00:03:56,212 The is operator is C#'s way of checking to see if an object is of a certain type. 64 00:03:56,212 --> 00:04:00,091 When I find myself tempted to write a bunch of type checks like this, 65 00:04:00,091 --> 00:04:04,390 it's a tell tale sign that I should make the class polymorphic. 66 00:04:04,390 --> 00:04:08,410 This means, making it so that subclasses of this class can provide 67 00:04:08,410 --> 00:04:11,020 their own implementations of decreased health. 68 00:04:11,020 --> 00:04:15,050 The word polymorphic means to have many forms. 69 00:04:15,050 --> 00:04:17,709 Just like how birds move differently, 70 00:04:17,709 --> 00:04:22,153 shielded invaders should have a different way to decrease help. 71 00:04:22,153 --> 00:04:26,867 We can make it possible for subclasses to provide their own implementation of 72 00:04:26,867 --> 00:04:31,012 decreased health by adding the keyword virtual to the method here. 73 00:04:31,012 --> 00:04:35,749 Adding virtual is telling C# that this is just one possible implementation of 74 00:04:35,749 --> 00:04:37,615 the decrease health method and 75 00:04:37,615 --> 00:04:42,260 subclasses can provide their own implementations of this method. 76 00:04:42,260 --> 00:04:45,780 Let's copy the declaration and paste it in ShieldedInvader. 77 00:04:46,980 --> 00:04:49,320 And we'll add the curly braces here. 78 00:04:49,320 --> 00:04:53,920 Because this is a subclass, we need to change the virtual here to override to 79 00:04:53,920 --> 00:04:58,980 show that ShieldedInvader is overriding the virtual method of the invader class. 80 00:04:58,980 --> 00:05:04,963 In C# objects, we learned about the random class and it can help us out here as well. 81 00:05:04,963 --> 00:05:09,932 Let's create a static random instance in the shielded invader and call it random. 82 00:05:13,263 --> 00:05:19,994 Then in DecreaseHealth, we'll say, if(random.Nextdouble 83 00:05:22,324 --> 00:05:27,108 Is less than .5, Then call 84 00:05:27,108 --> 00:05:33,100 the base classes DecreaseHealthMethod and pass in the factor. 85 00:05:33,100 --> 00:05:36,900 Next double returns a random number between zero and one. 86 00:05:36,900 --> 00:05:40,040 Because it is uniformly random, half of the time, 87 00:05:40,040 --> 00:05:42,530 this number will be less than 0.5. 88 00:05:42,530 --> 00:05:47,160 So the body of this if statement will only be executed 50% of the time. 89 00:05:48,160 --> 00:05:50,080 Here we just call the base classes, 90 00:05:50,080 --> 00:05:53,770 that is the normal invaders, decrease health method. 91 00:05:53,770 --> 00:05:55,750 We do this by typing base. 92 00:05:56,930 --> 00:05:59,470 It's not enough to just type decrease health, 93 00:05:59,470 --> 00:06:03,510 because now there are two decrease health methods that can be called. 94 00:06:03,510 --> 00:06:06,280 We need to specify which one we want called. 95 00:06:06,280 --> 00:06:10,342 You should know that overridden methods don't have to call the base classes 96 00:06:10,342 --> 00:06:10,855 method. 97 00:06:10,855 --> 00:06:14,690 We could have done something other than call base.decrease health. 98 00:06:14,690 --> 00:06:18,880 It just so happens that what we want to do here is what is already done 99 00:06:18,880 --> 00:06:21,600 in the base classes decrease health method. 100 00:06:21,600 --> 00:06:25,582 Now when towers attempt to decrease the health of a shielded invader, 101 00:06:25,582 --> 00:06:28,835 they will be successful only half of the time on average. 102 00:06:28,835 --> 00:06:31,987 Other than its implementation of decrease health, 103 00:06:31,987 --> 00:06:35,780 a shielded invader is exactly like a normal invader. 104 00:06:35,780 --> 00:06:40,246 We would not have wanted to write an entirely new shielded invader class that 105 00:06:40,246 --> 00:06:43,479 was just a copy of most of the code of the invader class. 106 00:06:43,479 --> 00:06:48,241 Instead we're reusing most of the functionality of the Invader class and 107 00:06:48,241 --> 00:06:53,010 making one small alteration to make the shielded Invader class. 108 00:06:53,010 --> 00:06:56,530 The really neat thing about this is that all of the code that is 109 00:06:56,530 --> 00:06:59,800 already designed to work with the based Invader type 110 00:06:59,800 --> 00:07:04,610 will also work with the shielded Invader type without making any changes. 111 00:07:04,610 --> 00:07:09,470 A shielded invader is still an invader, it's just been enhanced a bit. 112 00:07:09,470 --> 00:07:15,690 So we can go to Game.cs and change one of these invaders here to ShieldedInvader. 113 00:07:15,690 --> 00:07:19,120 Notice that this is still an array of invaders. 114 00:07:19,120 --> 00:07:21,120 We don't have to change anything else. 115 00:07:21,120 --> 00:07:25,560 These invaders get past the level which knows about the base invader type. 116 00:07:26,730 --> 00:07:30,233 There is no reference to ShieldedInvader in here. 117 00:07:30,233 --> 00:07:33,832 In the play method, these invaders get passed through the towers 118 00:07:33,832 --> 00:07:37,710 FireOnInvaders method. 119 00:07:37,710 --> 00:07:41,740 See here again, there is no reference to a shielded invader yet, but 120 00:07:41,740 --> 00:07:43,316 all this code will still work. 121 00:07:43,316 --> 00:07:46,590 When decrease health is called on an invader, 122 00:07:46,590 --> 00:07:50,220 that is a normal invader, its health will be decreased. 123 00:07:50,220 --> 00:07:54,120 However, if decreased health is called on an invader that is actually 124 00:07:54,120 --> 00:07:58,740 of type shielded invader, it may or may not suffer damage. 125 00:07:58,740 --> 00:08:02,445 To really see what's going on, let's move this console output. 126 00:08:02,445 --> 00:08:08,940 We'll reprint shot at and hit an invader to the invaders decrease health method. 127 00:08:08,940 --> 00:08:12,800 We could add a using system directive to the top of the file, but 128 00:08:12,800 --> 00:08:15,436 instead we'll just add the namespace name here. 129 00:08:15,436 --> 00:08:19,428 Now in ShieldedInvader's DecreaseHealthMethod, 130 00:08:19,428 --> 00:08:21,916 let's add some output here too. 131 00:08:21,916 --> 00:08:25,133 If the shield block the shot, 132 00:08:25,133 --> 00:08:30,026 we'll say System.Console.Writeline and 133 00:08:30,026 --> 00:08:34,144 print (Shot at a shielded invader but 134 00:08:34,144 --> 00:08:39,550 it sustained no damage.") Let's compile this 135 00:08:39,550 --> 00:08:46,520 to make sure that we didn't introduce any compilation errors. 136 00:08:48,760 --> 00:08:57,011 We'll say msc- out:TreeHouseDefense, *.cs. 137 00:08:57,011 --> 00:08:58,530 Now let's run it to see what we get. 138 00:09:02,535 --> 00:09:03,895 As you can see, 139 00:09:03,895 --> 00:09:08,995 even though fire on invaders accepts an array of the base invader type, we still 140 00:09:08,995 --> 00:09:13,945 get different behavior when decreased health is called on a shielded invader. 141 00:09:13,945 --> 00:09:16,755 That's because the DecreaseHealth method is 142 00:09:16,755 --> 00:09:18,895 overridden in the shielded invader class.