In this lecture, we'll implement another small class hierarchy in as C-Sharp console app. Here's the class diagram for the hierarchy we're going to implement. We have a general bank account class as the root of the class hierarchy, the parent class in this example, and we have two specialized bank accounts. We have a Checking Account that has a checking account specific fields, properties and methods, and we also have a savings account which has specialized fields and methods. Let's go see how to implement this class hierarchy in a C-Sharp console app. For this example, bank account is the top of our class hierarchy, so we'll start with bank account. We have a set of fields, we have the balance in the bank account, we have a list of deposits, and we have a list of withdrawals for the bank account. We have a constructor where we pass in an initial deposit, we set our balance to that initial deposit because this is a new account, our current balance will be whatever we started with to open the account, and we add that initial deposit to our list of deposits. That's our first deposit for this particular bank account. We have a property that lets us get the balance in the bank account, we have a property that lets us get the list of deposits, and a property that lets us get the list of withdrawals, and then we have some methods. The first method is make a deposit. We pass in an amount of the deposit and we do some error checking here to make sure that the amount is greater than 0, it doesn't make any sense to add a deposit of zero dollars, nor does it make any sense to add a negative deposit, so we don't allow that. We do error checking, and if the amount is valid, we add it to the balance and add it to the list of deposits, otherwise, we print a message that say deposits have to be larger than zero. Similarly, we can make withdrawals from our account, so we make sure that the amount is less than or equal to the balance, so we can't take out more money than we have in our account, and that the amount is valid, and if both those things are true, that's why we have an int here, we deduct the amount from the balance and we add this withdrawal to the list of withdrawals, otherwise, it's an invalid withdrawal. Then this last method is interesting, because the ToString method returns a string that is balanced colon space concatenated with the current balance in the account. But the interesting thing here, is that we say override. We know that when we say override, we're overriding a method in our parent class. But if we look at the top of this class, we never said we inherit from anything here, there's no space colon space, parent class name here, so how can we possibly override something? In C-Sharp, the root of any class hierarchy we ever build is actually a class called the object. So even though syntactically we don't explicitly say we inherit from the object class anytime we define a new class, we actually are inheriting from the object class, and that's why down here, we can override the ToString method in our parent class. Because we actually do have a parent, even though it doesn't say that when we define the class, we do have a parent. It's the object class. Our checking account explicitly says it has bank account as its parent, it has an additional field, a list of the checks that have been cashed for the checking account. As we saw it in the previous lecture, we implement a constructor for checking account, and we immediately call the constructor in bank account, and that's all we need to do for our checking account. We want an additional property that we don't need in a generic bank account. But we do want to let a consumer of the class get a list of the checks that have been cashed. This is an example. Both the field here and the property here are examples of adding stuff to the child class. We still inherit the make deposit and make withdrawal methods and the fields and so on. But we can add some additional in this particular instance, state. Fields and properties are state. We can also add behavior, and we do. We have a cache check method that checks for valid check amount and if it's valid, we reduce the balance and add to the list of checks. Otherwise we print this invalid check message. This is a child class that inherits all of the state and behavior from its parent class, but also adds some state and behavior. The final class in our class hierarchy is the savings account, which we specify as being a child class of the bank account. We have an additional field called interest rate. The constructor here is different from the constructors we've seen in child classes so far. Because this constructor, we need two pieces of information when we create a savings account object. We need the initial deposit, but we also need the interest rate that the savings account pays. When we call this constructor. As always, we call the constructor in our parent class first, which sets the balance and adds this initial deposit to the list of deposits. However, here in the body of the constructor, we want to set the interest rate field that we added for this child class to the second parameter, that interest rate parameter right there. This is the first time we've seen a child class that actually does something in the body of the constructor, rather than just calling the parent constructor and saying, everything's fine. We also have some additional behavior in this child to class where we accrue interest. The way we accrue interest is we take our current balance and multiply it by the interest rate and add it to our previous balance. One of the things I blasted right by and bank account is that this field called balance has the protected keyword in front of it. I'm going to delete that keyword for a moment and we'll come back to savings account. We can see we now have red squigglies on the balance. If I hover over this, it says, BankAccount.balance is inaccessible due to its protection level. Remember, fields in our classes are private by default, if we haven't put an access modifier in front of a field, it's private by default. That means that even our children can't see our private fields. The way we resolve that, if we only want our children to be able to access them, is to put the protected access modifier in front of the field. We could certainly do this, which would get rid of our red squigglies. But that would actually make this field available to any consumer of a bank account class. That's not at all what we want. We don't want anybody to be able to directly affect the balance field. We want to make them go through the methods that affect the balance. We don't want to make the field public. But if we want our child classes to know about the field, we can make it protected. Then our child class, savings account, can now access that field. In our main method, we create two accounts and we're doing this the same way that we did with gamer and geek being stored in family member variables. Here we're creating a new checking account object and putting it into a checking account variable that is declared to be of type bank account. Because, remember, a checkingAccount is a BankAccount. We do a similar thing with the savingsAccount, passing in two arguments this time, so we start our checkingAccount with $100, and we start our savingsAccount with $50, and an interest rate of two percent. By the way, we've seen lots of decimal data types in this particular example, we're not really using the decimal data type in our game development, but it's actually a good way to accurately store floating point numbers, especially when we're working with currency. Decimal is a way to essentially store decimal numbers, and we have to put the m after our decimal literals, because otherwise the compiler interprets them to be doubles. Don't get confused by the decimal thing, it's just another way to store numbers with decimal points. We created two objects. We call MakeDeposit on both objects, so we put $20 into both accounts. Remember, neither the checkingAaccount class nor the savingsAccount class actually implemented and make deposit method, they just inherit them from the BankAccount class. Twenty dollars into each account, and then we output each account. Then we do something really interesting here. We have a checkingAccount object stored in our CheckingAccount variable, and we'd like to cash a check. But we can't just say checkingAccount.CashCheck because checkingAccount is a BankAccount, and the BankAccount class doesn't have a CashCheck method. The way we can do this is we can say, take the checkingAccount variable, treat it as a CheckingAccount object, which we know it is because that's the object we instantiated to store in that variable. Now we're holding a CheckingAccount object, and we can call the CashCheck method on it. As a caution, if the checkingAccount variable doesn't actually hold the CheckingAccount object, if it just holds a generic bank account or a savings account or something like that, this will evaluate to null, and we'll try to call a method on a null object and we'll get a null reference exception. You can certainly think of this as a type cast, but it's a type cast that could fail if this variable doesn't hold this data type. We do something similar with the savingsAccount so that we can accrue interest on our SavingsAccount object, and then we output each account again. If I run this code, the first line of output is the checkingAccount that started at $100 and then we added $20 to it. The second line of output is for the savingsAccount where we started at $50 and added $20 to it. The third line of output is the balance in the checkingAccount after we cashed a $20 check, and the fourth line is the balance in the savingsAccount after we've accrued interest. You can convince yourself that $1.40 is in fact two percent of 70 if you need to, but trust me it is. After accruing interest in the savingsAccount, we have 71.40 in the savingsAccount. For this code that we looked at here, we got some more practice with inheritance. We learned about the protected keyword for fields, but we can make other things protected too. We can make properties protected, we can make set accessors for properties or get accessors for properties protected, we can make methods protected. We learned here though, how to make balance protected so the savingsAccount could get to it. We observed some of the standard inheritance stuff, and we also saw how to do some class-specific operations by essentially typecasting objects to the appropriate class, so we can call class-specific methods on those objects. To recap, in this lecture, we got some more practice implementing inheritance in C-Sharp, and we also learned about the protected access modifier.