1 00:00:00,572 --> 00:00:03,640 In C# not everything has to be an object. 2 00:00:03,640 --> 00:00:06,860 We often have a need to create a set of methods and properties that can 3 00:00:06,860 --> 00:00:10,840 be accessed from any class without having an instance of a class to work with. 4 00:00:10,840 --> 00:00:13,380 This is what static classes are for. 5 00:00:13,380 --> 00:00:16,160 Static classes can't inherit from any other class. 6 00:00:16,160 --> 00:00:18,900 Nor can static classes be inherited from. 7 00:00:18,900 --> 00:00:21,740 We also can't instantiate a static class. 8 00:00:21,740 --> 00:00:24,060 Instead of working with objects of the class, 9 00:00:24,060 --> 00:00:26,590 we work directly with the class itself. 10 00:00:26,590 --> 00:00:31,516 An example of a static class in the .NET framework is the System.Math class. 11 00:00:31,516 --> 00:00:36,080 System.Math is simply a group of math functions that can be called. 12 00:00:36,080 --> 00:00:39,030 We call them directly on the Math class itself. 13 00:00:39,030 --> 00:00:41,720 We don't need to have a math object to use them. 14 00:00:41,720 --> 00:00:44,470 Another example of a static class that we're familiar with 15 00:00:44,470 --> 00:00:46,910 is the system.console class. 16 00:00:46,910 --> 00:00:50,590 It makes sense for the system.console class to be a static class because 17 00:00:50,590 --> 00:00:53,940 a program can interact with only a single console window. 18 00:00:53,940 --> 00:00:57,580 You may have noticed that we can call methods directly on the console class, 19 00:00:57,580 --> 00:01:00,020 without first creating a console object. 20 00:01:00,020 --> 00:01:04,160 Members in a static class are globally accessible inside the application. 21 00:01:04,160 --> 00:01:05,220 Public fields and 22 00:01:05,220 --> 00:01:10,360 properties inside of a static class are known as global variables. 23 00:01:10,360 --> 00:01:14,170 Typically, we want to avoid creating and using global variables because 24 00:01:14,170 --> 00:01:17,300 we have very little control over who can change them. 25 00:01:17,300 --> 00:01:20,820 This can cause bugs that are very difficult to track down and resolve. 26 00:01:20,820 --> 00:01:24,390 And this is something we want to be aware of when creating static classes. 27 00:01:24,390 --> 00:01:28,453 It's best to create static classes where the members of the class are immutable. 28 00:01:28,453 --> 00:01:32,485 An immutable class is a class where the data inside the class can't be changed. 29 00:01:32,485 --> 00:01:36,700 System.Math is an example of an immutable class. 30 00:01:36,700 --> 00:01:40,680 System.Math is simply a collection of related functions. 31 00:01:40,680 --> 00:01:45,380 There are some cases where it is all right to have a mutable static class 32 00:01:45,380 --> 00:01:48,215 if the side effects of changing the data in the class is manageable. 33 00:01:48,215 --> 00:01:51,240 System.console is one example. 34 00:01:51,240 --> 00:01:56,040 We can use a static class to simplify some of the code in the Treehouse Defense game. 35 00:01:56,040 --> 00:01:57,986 Let's take a look at the Tower class. 36 00:02:00,717 --> 00:02:05,470 The Tower class contains a static field named _random. 37 00:02:05,470 --> 00:02:08,928 We also have a static random field in shielded invader. 38 00:02:08,928 --> 00:02:13,600 We can refactor this to use a single static random class. 39 00:02:13,600 --> 00:02:16,892 We'll create our own static random class in random.cs 40 00:02:21,148 --> 00:02:23,440 We'll put it in the TreehouseDefense namespace. 41 00:02:25,800 --> 00:02:28,650 This is a good example of why we need namespaces. 42 00:02:28,650 --> 00:02:32,260 We already have a class named random in the system namespace. 43 00:02:32,260 --> 00:02:34,710 Because these classes are in different namespaces, 44 00:02:34,710 --> 00:02:38,340 we can specify precisely which one we want to use. 45 00:02:38,340 --> 00:02:41,190 Inside the class, we'll have a static random field and 46 00:02:41,190 --> 00:02:44,410 initialize it to an instance of the Random class. 47 00:02:44,410 --> 00:02:49,533 So, it's a private static 48 00:02:49,533 --> 00:02:55,560 Random_ random = new Random. 49 00:02:55,560 --> 00:02:58,760 We need to specify that we want to use System.Random here, 50 00:02:58,760 --> 00:03:00,180 not the random class that we're in. 51 00:03:02,340 --> 00:03:05,210 The method in the random class that both the Tower class and 52 00:03:05,210 --> 00:03:08,680 the shielded invader class use is next double. 53 00:03:08,680 --> 00:03:11,240 Remember the next double method when called, 54 00:03:11,240 --> 00:03:14,630 returns a random double between zero and one. 55 00:03:14,630 --> 00:03:17,832 We'll create our own static next double method that returns the result of 56 00:03:17,832 --> 00:03:19,957 calling the random objects next double method. 57 00:03:24,001 --> 00:03:28,608 Essentially what we've done here is created a global random object. 58 00:03:28,608 --> 00:03:31,660 Now whenever random.next double is called, 59 00:03:31,660 --> 00:03:36,710 it will get the next random number from the global random object we have here. 60 00:03:36,710 --> 00:03:40,650 Now we can go back to all the places that is using System.Random. 61 00:03:40,650 --> 00:03:44,650 And replace them to use our global random class. 62 00:03:44,650 --> 00:03:47,696 So, here in the Tower class, we'll delete this line and 63 00:03:47,696 --> 00:03:50,055 change this to our new static Random class. 64 00:03:54,732 --> 00:03:56,860 We can do the same in shielded invader. 65 00:03:59,030 --> 00:04:05,640 Delete this line and change this, so that it refers to the random class. 66 00:04:06,850 --> 00:04:08,660 Let's compile to make sure we didn't break anything. 67 00:04:11,750 --> 00:04:13,040 I got a compiler error here. 68 00:04:13,040 --> 00:04:15,837 It says, cannot declare instance members in a static class. 69 00:04:17,672 --> 00:04:21,612 Hm, that's because we didn't make the next double a static method. 70 00:04:25,496 --> 00:04:27,030 Try it again. 71 00:04:27,030 --> 00:04:30,050 There we go, so why would we wanna use our static class 72 00:04:30,050 --> 00:04:32,390 instead of the way we were doing it before? 73 00:04:32,390 --> 00:04:36,395 The way we were doing it before here in Tower and shielded invader is fine. 74 00:04:36,395 --> 00:04:38,654 But by creating a static random class, 75 00:04:38,654 --> 00:04:43,190 we've been able to slightly simplify the code in Tower and shielded invader. 76 00:04:43,190 --> 00:04:46,785 Whenever we want a random number between zero and one, we can just call 77 00:04:46,785 --> 00:04:51,650 random.nextdouble instead of first creating an instance of the random class. 78 00:04:51,650 --> 00:04:56,230 Our random class is not immutable because the state of the random object here is 79 00:04:56,230 --> 00:04:59,720 changed every time we ask for a new random number. 80 00:04:59,720 --> 00:05:02,740 That's how it knows to give us the next random number. 81 00:05:02,740 --> 00:05:06,640 But this is all right, since all we care about is getting a random number. 82 00:05:06,640 --> 00:05:10,830 This is one of the rare cases where having a globally mutable object is okay.