Welcome back, I hope you enjoyed the section 15 challenge.
I'm going to give you my solution here, and we'll walk through it.
As always, there's a lot of different ways to do this.
So if your solution is different from mine, it's probably just fine.
So I'm in the section 15 workspace in the ChallengeSolution project.
So I didn't change the account or the savings account classes at all.
So why don't we start with the checking account class.
This is one of the new classes that we added.
So let me open up the checking account header file, and let's
go through this real quickly.
Now in this case, the checking account doesn't add any new attributes, right.
So a checking account is an account.
I chose to derive this from account because the checking account has
the name and it's got a balance.
The only difference here is that when we withdraw, we're doing
a $1.50 flat fee, check fee.
Okay, so other than that it's really, really very similar.
We've got our const expressions here, which are just our
compile time constants.
Here we've got our constructor that expects a name.
And if it's not supplied, we'll use our default here, a balance.
And that's it, right.
The per check fee is not a per object thing.
This is a class thing.
So this is why it's a static cost expression.
If it was on a per account basis and obviously you'd want that to
be an attribute and you'd want to pass it into a constructor.
So we've got that.
We've got our withdraw method because we need to override
the behavior for withdraw to deal with the per check fee.
The deposit method is fine.
We don't need to change that at all because the way we do
deposits is the same way that an account does a deposit.
Hopefully, one of the things that you notice when you derive these classes
from existing classes is the amount of code you have to write is really
minimal in many cases, right, because all you're doing is specializing.
The other thing we did here was we created that overloaded
insertion operator that works with a checking account that just makes
it really easy to display those.
Okay, so that's it.
Let�s take a look at the implementation.
And as you can see, there's really very little code here.
First of all, let's look at the constructor.
So there's my checking account constructor.
It expects the name and the balance.
And I need to initialize the account part of me, right
because I'm derived from account.
So here I'm invoking my base classes constructor and it's the
one that takes care of name and balance I'm just passing it over.
And when this comes back, we're initialized, right.
At that point, that's all.
That's all we need for a constructor here.
Now what about the withdraw method.
Well, here we're definitely overriding the withdraw method.
So here's the withdraw method for the new class my checking account class.
It still expects an amount to withdraw.
And all we're doing is we're saying okay whatever that amount is I'm
just adding the per check fee to it, which is a 1.50 dollar in this case.
So whatever, I want to withdraw I'm just adding the 1.50 dollar.
And then I'm letting the account class do the withdrawal,
just like we've done before.
And again, I'm returning what it returns.
So if it fails, I'll return false.
If it succeeds, I'll return true.
And then the last thing we'll do is our output operator
here, our insertion operator.
This time it expects a checking account.
And actually we could have used used a regular account here,
right because we're not really adding anything in this class.
So even if it got sliced, it's okay because we're
not adding anything at all.
So that's it.
That's a pretty simple implementation of that checking account.
Now let's take a look at the trust account.
So here we have our trust account.
And you can see that the trust account is derived publicly
from a savings account.
And that's because a trust account has a name, a
balance and an interest rate.
So a lot of the savings account behavior will be perfect for that.
I'm overloading the insertion operator here for a trust account as usual.
And now this code looks a little lengthier.
And the reason for that is all these constants here.
They're handy, right.
Here's our default balance, here's a default interest rate.
You probably could make that 2 or 3% or something just
to get some more interesting results, but I'll leave it at 0.
There's the bonus amount for a deposit that's over 5000 dollars.
There's the threshold that's 5000.
The maximum withdrawals is 3, and the most we can withdraw
is 20% of the accounts value.
So all that information is right in here in these constants.
And the only thing that the trust account really adds is
besides the business logic, of course, is this attribute right
here the number of withdrawals.
So it will set that to 0 when we create a trust account object.
And then every time we do a withdrawal, that's successful,
we'll bump it up by 1.
And then when we do a withdrawal and it's greater than 3, we'll just
fail right there, pretty simple.
Okay, so here's my constructor.
It expects as usual, a name, a balance and an interest rate.
You can see that right there.
And it's got these defaults right up here that it defaults to.
Here's my deposit, which I obviously need to override
because I've get a 50 dollar whenever I deposit 5000 or more.
And here's my withdrawal which again I need to override because our
business logic says I'm only allowed maximum of 3 withdrawals per year,
and each one is up to a maximum of 20% of the accounts value or balance.
Okay, so that's it.
Let's take a look at the implementation file now.
And here's the implementation file for the trust account.
You can see our constructor is up here.
Again, we're receiving the name, the balance and the interest rate.
And all of those guys are really in my savings account part, right.
So I'm invoking my base class constructor right here,
and I'm passing in name, balance and interest rate.
Let it take care of initializing itself.
When I come back, I do need to take care of my attribute,
which is number of withdrawals.
So this is my responsibility, and I'm setting that to 0 right here.
Okay, so now let's take a look at the deposit.
So here's the trust account deposit method.
Again, it expects an amount.
And all I'm looking for is that bonus threshold which is 5000 dollars.
So if the amount deposited is greater than or equal to that bonus threshold,
which in again in this case is 5000, then we're just incrementing
the amount to deposit by the bonus amount which is the 50 dollars.
Simple as that, I invoke my base classes deposit method because the
savings account knows how to deal with the interest rate and the deposit.
And I'm returning right here what it returns to me.
And then the last thing we'll do is our withdraw method.
Again, the withdraw method's important because it's got
some business logic here.
So I want to check -- and again, here's the amount
that I want to withdraw.
So if the number of withdrawals is greater than or equal to the
max withdrawals, which was that constant, which was 3 or the amount
to withdraw is greater than the balance times the threshold, right,
so that's the 20% right here.
If either one of those guys is true, we don't do the
withdrawal, we return false.
Otherwise, we increment the number of withdrawals, and we call our
savings account withdraw method and pass in the account -- and
pass in the amount to withdraw.
So that's it.
You can see that we really aren't writing a lot of new code.
We're specializing, we're tweaking, we're refining if you will our
behavior based on our business logic.
And then the last thing is this overloaded insertion
operator for trust account.
In this case, I'm also displaying the number of withdrawals just
so that we have that information.
Okay, so that's the trust account.
So we've got our two new accounts in the hierarchy now.
So the next thing I want to show you is that account util file and the
functions that I modified in there.
So let's look at the changes I made to the account util files.
And you can see that right here I've added the function prototypes
for the checking account class and the trust account class.
You can see that all this code is really, really, really similar.
And you're going to love what's going to happen in the next section.
We're going to be able to get rid of all of this and just
create one version that works for all of the accounts once
we use polymorphic functions.
But for now, let's just do it this way so that we really
understand what's going on.
Again, remember, we're doing static binding right now.
So the compiler is binding the method calls to the actual
types of the objects that it sees in at compile time.
So there are the function prototypes for these guys.
It's very similar to what we did before.
And the implementation file right here, same idea.
I'll just scroll down just a little bit.
And you can see here are the helper functions for the checking account
class right here on line 64.
And if we scroll down a little bit further, we've got the helper
functions for the trust account class.
And as I said, they're all exactly the same except what's inside that vector.
Okay, so now let's look at the main.
Finally, here's the main and the beginning is exactly the
same as it was before, right.
You remember we had the accounts tests right here, so we put in some account objects
into a vector of accounts and then we call display,
deposit and withdraw for those accounts.
We did that both for a regular account and a savings account here.
And now we're just going to do the same thing again
for a checking account.
So you can see here I'm creating a vector of checking
account objects, right.
That's my template argument right here, checking account,
and it's check accounts.
And I'm creating an empty checking account, one for Kirk, one for
Spock and, one for Bones, let's say.
I don't want to give Spock two accounts.
And that's it.
Then we're going to call display for check accounts, deposit a 1000
into each one of those accounts and withdraw from those accounts 2000.
And then finally, we're going to do the trust account.
And the trust account, same idea.
I'm going to have a vector of trust account objects.
And I'm going to create four of them again.
I'm going to construct this one with no initialization,
just like I've done before.
And then we'll create Athos, Porthos and Aramis, the three musketeers.
And we'll create some accounts for them.
We'll display them, deposit into them and withdraw from
them, just like we did before.
And then the last thing I'm doing is I'm simply calling
withdrawal five times.
So I'm looping five times, and I'm calling withdraw
on those trust accounts.
So I expect those to fail, right because I'm only allowed
to withdraw 3 times maximum.
And I can only withdraw 20% of the balance.
So I should see a lot of failures here.
So let's run this.
And there's going to be a lot of output to go through.
And you can see we have a clean compile, no errors, no warnings.
And I'll scroll up here because there's a lot of output to go through.
And this is what we had earlier, right.
When we created just the regular accounts here, we created four
of them: Larry, Moe Curly and an unnamed account right up top.
We're going to display them.
That's what you're seeing right here.
Then we're going to deposit a 1000 into them.
And that's this piece you see right here, depositing two accounts.
And then we're withdrawing 2000 from them that's the
piece you see right here.
The first two fail because there's insufficient funds.
So that's pretty straightforward.
That's exactly what the default code was in the challenge.
So is this.
Here's my savings accounts.
Let me just scroll up to so we can see that right here.
So we're creating those four savings accounts for superman,
batman and wonderwoman.
There they are.
When we display them, we're depositing a 1000 dollars into them here,
and then we're withdrawing 2000.
So of course, the first two will fail because there's insufficient
funds, just like before.
Now here's the checking.
The checking is a little different now because our withdraw methods
add a $1.50 service fee or a per check fee, right.
So here we've got a checking account for an unnamed checking account.
We've got Kirk, Spock and Bones.
And you can see them right here.
Right here is our display, right.
There's our unnamed checking account with 0 balance.
There's Kirk, 0 balance, Spock and Bones 2000 5000, respectively.
I'm depositing a $1000 into each account.
And then I'm going to withdraw 2000 from each account, exactly the
same we've - as we've done before.
So the first two are going to fail.
And you can see that the numbers now are a little different right
because we are subtracting the $1.50 per check fee here.
And these two don't because the withdrawal failed.
But in this case, we did withdraw so we're assessing the $1.50 fee.
So you can see that indeed the specialized withdraw
method is being called.
Now finally, we've got the trust accounts.
So there's our code for the trust account, and I'll scroll
that up right about there.
So here I'm creating Athos Porthos and Aramis and an unnamed trust
account, right here at the beginning.
And we're creating some different balances as well as interest rates.
And then we're just displaying the accounts and that's what
you're seeing here, right.
The unnamed trust account with 0 balance 0% interest rate.
It has no withdrawals yet.
Here's Athos Porthos and Aramis.
And you can see their information right here.
Notice how all of them have 0 withdrawals because we
set that in our constructor.
Now we're going to call deposit on each one of them
and deposit a 1000 dollars.
You can see that that's successful all the way through.
You can also see that we've got the bonus coming in here.
So finally, we withdraw 3000 dollars from each account.
The first two will fail the first one because we
don't have sufficient funds.
The second one because we are exceeding our 20% limit.
But the third and fourth one are no problem at all.
You notice the withdrawals here are now one whereas the withdrawals
on the failed ones are 0.
And then what I'm doing is I'm just calling that same
withdraw function 5 times.
So there's 1's right here.
You can see the number of withdrawals increasing and increasing and
finally, everything fails as we expect right here
because we've exceeded the 3 withdrawals.
Okay, so that's it.
I'm sure your solution is different from mine, and that's okay.
Take a look at my solution, maybe yours is better.
If it's better, post it.
If you find a bug in mine, let me know please, and I'll be glad to fix it.
So I hope you enjoyed this challenge.
I hope you understand a lot about inheritance.
In the next section, we're going to crank up the level in inheritance, and
we're going to talk about polymorphic functions with inheritance and that's
going to make all of this even easier.
So stay tuned for that.