Inheritance

T

tshad

I have a project with 2 classes Account and SavingsAccount which has Account
as the base.

I have penalty as a static property in both classes.

Everything else is being done in the base class.

But I have a couple of things that I am unsure of.

I want the SavingsAccount class to act exactly as the Account class except
for the penalty.

But when I call the Withdraw method from either class (a1.Withdraw or
s1.Withdraw), it always uses the penalty from the Account class.

Do I need to override the Withdraw class in my Savings account class to get
it to use the penalty from the Savings account class?

Also, I was doing the following to figure out balances:

balance -= amt - penalty;

I thought this would equate to:

balance = balance - amt - penalty

But it is adding in the penalty so I assume it is equating to:

balance = balance - (amt - penalty)

which would reverse the minus sign before penalty - is this correct?

so I changed it to:
balance -= amt + penalty

And it works fine now.

The code is:
*************************************************
using System;
using System.Collections.Generic;
using System.Text;

namespace TestInheritance2
{
class Account
{
protected double balance;
protected double overDraftLimit;
protected string name;
private static double penalty;

public static double Penalty
{
get { return penalty; }
set { penalty = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public double Balance
{
get { return balance; }
}
public double OverDraftLimit
{
get { return overDraftLimit; }
set { overDraftLimit = value; }
}

static Account()
{
Console.WriteLine("Setting Accounts Penalty = 50");
penalty = 50;
}

public Account()
{
balance = 1.0;
overDraftLimit = 500.0;
}

public Account(double amt, string nm, double overDraftLimit)
{
balance = amt;
name = nm;
this.overDraftLimit = overDraftLimit;
}

public void Deposit(double amt)
{
if (amt < 0.0)
throw new ArgumentOutOfRangeException("Deposit: invalid
argument");

// deposit cash
balance += amt;
}

public void Withdraw(double amt)
{
if (amt < 0.00)
{
throw new ArgumentOutOfRangeException("Withdraw: invalid
withdrawal");
}

if (balance - amt + overDraftLimit < 0.0)
throw new ArgumentOutOfRangeException("Withdraw: not enough
funds");
else
{
Console.WriteLine("in Withdraw Penalty = {0}", penalty);
balance -= amt + penalty;
Console.WriteLine("After Withdraw balance = {0}", balance);
}
}

public void Report()
{
Console.WriteLine("Account Name: {0}", name);
Console.WriteLine("Balance: {0}", balance);
Console.WriteLine("Overdraft Limit: {0}", overDraftLimit);
Console.WriteLine("Penalty: {0} ", penalty);
}
}
class SavingsAccount : Account
{
static double penalty;

static SavingsAccount()
{
Console.WriteLine("Setting Saving Accounts Penalty = 10.5");
penalty = 10.5;
}

public SavingsAccount(double amt, string nm, double overDraftLimit)
{
balance = amt;
name = nm;
this.overDraftLimit = overDraftLimit;
}

public new void Report()
{
Console.WriteLine("Penalty in Savings Account: {0} ", penalty);
base.Report();
}
}
public class program
{
static void Main(string[] args)
{
Console.WriteLine("Account Penalty at start = {0}",
Account.Penalty);
Console.WriteLine("SavingsAccount Penalty at start = {0}",
SavingsAccount.Penalty);
Account a1 = new Account(1000.0, "Count Dracula", 500);
SavingsAccount s1 = new SavingsAccount(100.0, "Franky", 50);
s1.Name = "New Savings Account for Tom";
a1.Report();
Console.WriteLine();
s1.Report();
Console.WriteLine();
a1.Withdraw(10);
Console.WriteLine();
s1.Withdraw(10);
Console.WriteLine("After withdrawing 10 from Savings account and
regular Account");
a1.Report();
Console.WriteLine();
s1.Report();
Console.Read();
}
}
}
**************************************************************

And the result is:
****************************************
Setting Accounts Penalty = 50
Account Penalty at start = 50
SavingsAccount Penalty at start = 50
Setting Saving Accounts Penalty = 10.5
Account Name: Count Dracula
Balance: 1000
Overdraft Limit: 500
Penalty: 50

Penalty in Savings Account: 10.5
Account Name: New Savings Account for Tom
Balance: 100
Overdraft Limit: 50
Penalty: 50

in Withdraw Penalty = 50
After Withdraw balance = 940

in Withdraw Penalty = 50
After Withdraw balance = 40
After withdrawing 10 from Savings account and regular Account
Account Name: Count Dracula
Balance: 940
Overdraft Limit: 500
Penalty: 50

Penalty in Savings Account: 10.5
Account Name: New Savings Account for Tom
Balance: 40
Overdraft Limit: 50
Penalty: 50
****************************************

As you can see $50 is the penalty in both cases. 10.5 is never used.

Thanks,

Tom
 
A

Arne Vajhøj

tshad said:
I have a project with 2 classes Account and SavingsAccount which has Account
as the base.

I have penalty as a static property in both classes.

Everything else is being done in the base class.

But I have a couple of things that I am unsure of.

I want the SavingsAccount class to act exactly as the Account class except
for the penalty.

But when I call the Withdraw method from either class (a1.Withdraw or
s1.Withdraw), it always uses the penalty from the Account class.

static members are not virtual. Make penalty non static.

Arne
 
J

Jesse McGrew

Also, I was doing the following to figure out balances:

balance -= amt - penalty;

I thought this would equate to:

balance = balance - amt - penalty

But it is adding in the penalty so I assume it is equating to:

balance = balance - (amt - penalty)

which would reverse the minus sign before penalty - is this correct?

so I changed it to:
balance -= amt + penalty

And it works fine now.

Correct. The -= operator subtracts the value on the right side from
the location on the left side, so these statements are equivalent:

balance -= amt - penalty;

int x = amt - penalty;
balance -= x;

balance = balance - (amt - penalty);

Jesse
 
T

tshad

Arne Vajhøj said:
static members are not virtual. Make penalty non static.

Ok, I tried that and set the Penalties in the the Constructors.

The problem is that now when I call the s1.Withdraw (SavingsAccount), I get
penalty = 0. I assume that has something to do with calling the Withdraw of
the Base class (Account), since I don't have one in my SavingsAccount class.

I would have thought it would use the Penalty from the SavingsAccount class
which was set to 10.5 when it was initialized:
New code
***************************************************
using System;
using System.Collections.Generic;
using System.Text;

namespace TestingInheritance3
{
class Account
{
protected double balance;
protected double overDraftLimit;
protected string name;
private double penalty;

public double Penalty
{
get { return penalty; }
set { penalty = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public double Balance
{
get { return balance; }
}
public double OverDraftLimit
{
get { return overDraftLimit; }
set { overDraftLimit = value; }
}

public Account()
{
balance = 1.0;
overDraftLimit = 500.0;
}

public Account(double amt, string nm, double overDraftLimit)
{
balance = amt;
name = nm;
this.overDraftLimit = overDraftLimit;
penalty = 50;
}

public void Deposit(double amt)
{
if (amt < 0.0)
throw new ArgumentOutOfRangeException("Deposit: invalid
argument");

// deposit cash
balance += amt;
}

public void Withdraw(double amt)
{
if (amt < 0.00)
{
throw new ArgumentOutOfRangeException("Withdraw: invalid
withdrawal");
}

if (balance - amt + overDraftLimit < 0.0)
throw new ArgumentOutOfRangeException("Withdraw: not enough
funds");
else
{
Console.WriteLine("in Withdraw Penalty = {0}", penalty);
balance -= amt + penalty;
Console.WriteLine("After Withdraw balance = {0}", balance);
}
}

public void Report()
{
Console.WriteLine("Account Name: {0}", name);
Console.WriteLine("Balance: {0}", balance);
Console.WriteLine("Overdraft Limit: {0}", overDraftLimit);
Console.WriteLine("Penalty: {0} ", penalty);
}
}
class SavingsAccount : Account
{
double penalty;

public SavingsAccount(double amt, string nm, double overDraftLimit)
{
balance = amt;
name = nm;
this.overDraftLimit = overDraftLimit;
penalty = 10.5;
}

public new void Report()
{
Console.WriteLine("Penalty in Savings Account: {0} ", penalty);
base.Report();
}
}
public class program
{
static void Main(string[] args)
{
Account a1 = new Account(1000.0, "Count Dracula", 500);
SavingsAccount s1 = new SavingsAccount(100.0, "Franky", 50);
s1.Name = "New Savings Account for Tom";
a1.Report();
Console.WriteLine();
s1.Report();
Console.WriteLine();
a1.Withdraw(10);
Console.WriteLine();
s1.Withdraw(10);
Console.WriteLine("After withdrawing 10 from Savings account and
regular Account");
a1.Report();
Console.WriteLine();
s1.Report();
Console.Read();
}
}
}

***************************************************
Results
***************************************************
Account Name: Count Dracula
Balance: 1000
Overdraft Limit: 500
Penalty: 50

Penalty in Savings Account: 10.5
Account Name: New Savings Account for Tom
Balance: 100
Overdraft Limit: 50
Penalty: 0

in Withdraw Penalty = 50
After Withdraw balance = 940

in Withdraw Penalty = 0
After Withdraw balance = 90
After withdrawing 10 from Savings account and regular Account
Account Name: Count Dracula
Balance: 940
Overdraft Limit: 500
Penalty: 50

Penalty in Savings Account: 10.5
Account Name: New Savings Account for Tom
Balance: 90
Overdraft Limit: 50
Penalty: 0
***************************************************

As you can see in the last s1.Report, it is showing penalty as 0.0, which I
assume is the Base.Penalty and that I am call the Withdraw from the Base.
But I thought that it would use the values from the object where Penalty was
overridden.

Obviously that was not the case.

Do I have to write a Withdraw method for my SavingsAccount class and
overwrite the Base class?

Also, why can't you have a static Penalty in both Account and
SavingsAccount?

Thanks,

Tom
 
T

tshad

Jesse McGrew said:
Correct. The -= operator subtracts the value on the right side from
the location on the left side, so these statements are equivalent:

balance -= amt - penalty;

int x = amt - penalty;
balance -= x;

balance = balance - (amt - penalty);

That was what I thought was happening. I use this all the time but never
noticed this problem before. Not sure why not. So you really have to be
careful with your += or -=.

Thanks,

Tom
 
C

Christof Nordiek

class SavingsAccount : Account
{
double penalty;

public SavingsAccount(double amt, string nm, double overDraftLimit)
{
balance = amt;
name = nm;
this.overDraftLimit = overDraftLimit;
penalty = 10.5;
}

Here you're not changing the penalty field in the base class, but you're
adding a new penalty field wich is not used in the Withdraw method of the
base class.

Instead you could do:

class SavingAccount : Account
{
public SavingsAccount(doulbe amt, string nm, double overDraftLimit)
{
blance = amt;
name = nm;
this.overDraftLimit;
Penalty = 10.5; //Writes via the property to the field in the base
class.
}
}

You also could have a (maybe protected or internal) constructor, with an
extra parameter for the penalty, wich allows you to make the penalty
property readonly.

Christof
 
T

tshad

Christof Nordiek said:
Here you're not changing the penalty field in the base class, but you're
adding a new penalty field wich is not used in the Withdraw method of the
base class.

Instead you could do:

class SavingAccount : Account
{
public SavingsAccount(doulbe amt, string nm, double overDraftLimit)
{
blance = amt;
name = nm;
this.overDraftLimit;
Penalty = 10.5; //Writes via the property to the field in the base
class.
}
}

Not sure what you were doing here.

But the point was that I wanted to have 2 penalties. One for Account and
one for SavingsAccount. Or a default penalty for Account to be used if not
overridden. And another for SavingsAccount and a 3rd for CheckingAccount.

Such that if I called

s1.Withdraw - it would use the SavingsAccount penalty and if not there use
the Base penalty
Same with Checking account.

But a1.Withdraw would always use the base.penalty because it is the base.

Thanks,

Tom
 
J

Jon Skeet [C# MVP]

But the point was that I wanted to have 2 penalties. One for Account and
one for SavingsAccount. Or a default penalty for Account to be used if not
overridden. And another for SavingsAccount and a 3rd for CheckingAccount.

The key here is the word "overridden". Introducing a new field doesn't
override the old one, it just introduces a new one. Overriding doesn't
work on fields, and it doesn't work on static members. You need to
have a virtual instance method/property in Account and then override
it in SavingsAccount/CheckingAccount.

Jon
 
P

Peter Morris

I don't think this is a good candidate for inheritance. Instead it is a
kind of state. The account has a state of either Savings or Current and
should act according to its state.
 
A

Arne Vajhøj

tshad said:
Arne Vajhøj said:
static members are not virtual. Make penalty non static.

Ok, I tried that and set the Penalties in the the Constructors.

The problem is that now when I call the s1.Withdraw (SavingsAccount), I get
penalty = 0. I assume that has something to do with calling the Withdraw of
the Base class (Account), since I don't have one in my SavingsAccount class.

I would have thought it would use the Penalty from the SavingsAccount class
which was set to 10.5 when it was initialized:
New code
***************************************************
using System;
using System.Collections.Generic;
using System.Text;

namespace TestingInheritance3
{
class Account
{
protected double balance;
protected double overDraftLimit;
protected string name;
private double penalty;

public double Penalty
{
get { return penalty; }
set { penalty = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public double Balance
{
get { return balance; }
}
public double OverDraftLimit
{
get { return overDraftLimit; }
set { overDraftLimit = value; }
}

public Account()
{
balance = 1.0;
overDraftLimit = 500.0;
}

public Account(double amt, string nm, double overDraftLimit)
{
balance = amt;
name = nm;
this.overDraftLimit = overDraftLimit;
penalty = 50;
}

public void Deposit(double amt)
{
if (amt < 0.0)
throw new ArgumentOutOfRangeException("Deposit: invalid
argument");

// deposit cash
balance += amt;
}

public void Withdraw(double amt)
{
if (amt < 0.00)
{
throw new ArgumentOutOfRangeException("Withdraw: invalid
withdrawal");
}

if (balance - amt + overDraftLimit < 0.0)
throw new ArgumentOutOfRangeException("Withdraw: not enough
funds");
else
{
Console.WriteLine("in Withdraw Penalty = {0}", penalty);
balance -= amt + penalty;
Console.WriteLine("After Withdraw balance = {0}", balance);
}
}

public void Report()
{
Console.WriteLine("Account Name: {0}", name);
Console.WriteLine("Balance: {0}", balance);
Console.WriteLine("Overdraft Limit: {0}", overDraftLimit);
Console.WriteLine("Penalty: {0} ", penalty);
}
}
class SavingsAccount : Account
{
double penalty;

public SavingsAccount(double amt, string nm, double overDraftLimit)
{
balance = amt;
name = nm;
this.overDraftLimit = overDraftLimit;
penalty = 10.5;
}

public new void Report()
{
Console.WriteLine("Penalty in Savings Account: {0} ", penalty);
base.Report();
}
}
public class program
{
static void Main(string[] args)
{
Account a1 = new Account(1000.0, "Count Dracula", 500);
SavingsAccount s1 = new SavingsAccount(100.0, "Franky", 50);
s1.Name = "New Savings Account for Tom";
a1.Report();
Console.WriteLine();
s1.Report();
Console.WriteLine();
a1.Withdraw(10);
Console.WriteLine();
s1.Withdraw(10);
Console.WriteLine("After withdrawing 10 from Savings account and
regular Account");
a1.Report();
Console.WriteLine();
s1.Report();
Console.Read();
}
}
}

***************************************************
Results
***************************************************
Account Name: Count Dracula
Balance: 1000
Overdraft Limit: 500
Penalty: 50

Penalty in Savings Account: 10.5
Account Name: New Savings Account for Tom
Balance: 100
Overdraft Limit: 50
Penalty: 0

in Withdraw Penalty = 50
After Withdraw balance = 940

in Withdraw Penalty = 0
After Withdraw balance = 90
After withdrawing 10 from Savings account and regular Account
Account Name: Count Dracula
Balance: 940
Overdraft Limit: 500
Penalty: 50

Penalty in Savings Account: 10.5
Account Name: New Savings Account for Tom
Balance: 90
Overdraft Limit: 50
Penalty: 0
***************************************************

As you can see in the last s1.Report, it is showing penalty as 0.0, which I
assume is the Base.Penalty and that I am call the Withdraw from the Base.
But I thought that it would use the values from the object where Penalty was
overridden.

Obviously that was not the case.

Do I have to write a Withdraw method for my SavingsAccount class and
overwrite the Base class?

Also, why can't you have a static Penalty in both Account and
SavingsAccount?

There are so many thing that can and should be done different in your
code.

Try and compare your code with the version below.

Arne

============================================================

using System;
using System.Collections.Generic;
using System.Text;

namespace TestingInheritance3
{
public class Account
{
private string name;
private decimal balance;
private decimal overDraftLimit;
protected decimal penalty;

public string Name
{
get { return name; }
set { name = value; }
}
public decimal Balance
{
get { return balance; }
}
public decimal OverDraftLimit
{
get { return overDraftLimit; }
set { overDraftLimit = value; }
}
public decimal Penalty
{
get { return penalty; }
set { penalty = value; }
}

public Account(string name, decimal balance, decimal
overDraftLimit)
{
this.name = name;
this.balance = balance;
this.overDraftLimit = overDraftLimit;
penalty = 50.00m;
}

public void Deposit(decimal amt)
{
if (amt < 0.00m)
{
throw new ArgumentOutOfRangeException("Deposit: invalid
argument");
}
balance += amt;
}

public void Withdraw(decimal amt)
{
if (amt < 0.00m)
{
throw new ArgumentOutOfRangeException("Withdraw:
invalid withdrawal");
}

if (balance - amt + overDraftLimit < 0.00m)
{
throw new ArgumentOutOfRangeException("Withdraw: not
enough funds");
}
else
{
Console.WriteLine("In Withdraw penalty = {0}", penalty);
balance -= (amt + penalty);
Console.WriteLine("After Withdraw balance = {0}", balance);
}
}

public virtual void Report()
{
Console.WriteLine("Account Name: {0}", name);
Console.WriteLine("Balance: {0}", balance);
Console.WriteLine("Overdraft Limit: {0}", overDraftLimit);
Console.WriteLine("Penalty: {0} ", penalty);
}
}
public class SavingsAccount : Account
{
public SavingsAccount(string name, decimal balance, decimal
overDraftLimit) : base(name, balance, overDraftLimit)
{
penalty = 10.50m;
}

public new void Report()
{
base.Report();
Console.WriteLine("Penalty in Savings Account: {0} ", penalty);
}
}
public class program
{
public static void Main(string[] args)
{
Account a1 = new Account("Count Dracula", 1000.00m, 500.00m);
SavingsAccount s1 = new SavingsAccount("Franky", 100.00m,
50.00m);
s1.Name = "New Savings Account for Tom";
a1.Report();
Console.WriteLine();
s1.Report();
Console.WriteLine();
a1.Withdraw(10);
Console.WriteLine();
s1.Withdraw(10);
Console.WriteLine("After withdrawing 10 from Savings
account and regular Account");
a1.Report();
Console.WriteLine();
s1.Report();
Console.Read();
}
}
}
 
T

tshad

Arne Vajhøj said:
tshad said:
Arne Vajhøj said:
tshad wrote:
I have a project with 2 classes Account and SavingsAccount which has
Account as the base.

I have penalty as a static property in both classes.

Everything else is being done in the base class.

But I have a couple of things that I am unsure of.

I want the SavingsAccount class to act exactly as the Account class
except for the penalty.

But when I call the Withdraw method from either class (a1.Withdraw or
s1.Withdraw), it always uses the penalty from the Account class.
static members are not virtual. Make penalty non static.

Ok, I tried that and set the Penalties in the the Constructors.

The problem is that now when I call the s1.Withdraw (SavingsAccount), I
get penalty = 0. I assume that has something to do with calling the
Withdraw of the Base class (Account), since I don't have one in my
SavingsAccount class.

I would have thought it would use the Penalty from the SavingsAccount
class which was set to 10.5 when it was initialized:
New code
***************************************************
using System;
using System.Collections.Generic;
using System.Text;

namespace TestingInheritance3
{
class Account
{
protected double balance;
protected double overDraftLimit;
protected string name;
private double penalty;

public double Penalty
{
get { return penalty; }
set { penalty = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public double Balance
{
get { return balance; }
}
public double OverDraftLimit
{
get { return overDraftLimit; }
set { overDraftLimit = value; }
}

public Account()
{
balance = 1.0;
overDraftLimit = 500.0;
}

public Account(double amt, string nm, double overDraftLimit)
{
balance = amt;
name = nm;
this.overDraftLimit = overDraftLimit;
penalty = 50;
}

public void Deposit(double amt)
{
if (amt < 0.0)
throw new ArgumentOutOfRangeException("Deposit: invalid
argument");

// deposit cash
balance += amt;
}

public void Withdraw(double amt)
{
if (amt < 0.00)
{
throw new ArgumentOutOfRangeException("Withdraw: invalid
withdrawal");
}

if (balance - amt + overDraftLimit < 0.0)
throw new ArgumentOutOfRangeException("Withdraw: not
enough funds");
else
{
Console.WriteLine("in Withdraw Penalty = {0}", penalty);
balance -= amt + penalty;
Console.WriteLine("After Withdraw balance = {0}",
balance);
}
}

public void Report()
{
Console.WriteLine("Account Name: {0}", name);
Console.WriteLine("Balance: {0}", balance);
Console.WriteLine("Overdraft Limit: {0}", overDraftLimit);
Console.WriteLine("Penalty: {0} ", penalty);
}
}
class SavingsAccount : Account
{
double penalty;

public SavingsAccount(double amt, string nm, double
overDraftLimit)
{
balance = amt;
name = nm;
this.overDraftLimit = overDraftLimit;
penalty = 10.5;
}

public new void Report()
{
Console.WriteLine("Penalty in Savings Account: {0} ",
penalty);
base.Report();
}
}
public class program
{
static void Main(string[] args)
{
Account a1 = new Account(1000.0, "Count Dracula", 500);
SavingsAccount s1 = new SavingsAccount(100.0, "Franky", 50);
s1.Name = "New Savings Account for Tom";
a1.Report();
Console.WriteLine();
s1.Report();
Console.WriteLine();
a1.Withdraw(10);
Console.WriteLine();
s1.Withdraw(10);
Console.WriteLine("After withdrawing 10 from Savings account
and regular Account");
a1.Report();
Console.WriteLine();
s1.Report();
Console.Read();
}
}
}

***************************************************
Results
***************************************************
Account Name: Count Dracula
Balance: 1000
Overdraft Limit: 500
Penalty: 50

Penalty in Savings Account: 10.5
Account Name: New Savings Account for Tom
Balance: 100
Overdraft Limit: 50
Penalty: 0

in Withdraw Penalty = 50
After Withdraw balance = 940

in Withdraw Penalty = 0
After Withdraw balance = 90
After withdrawing 10 from Savings account and regular Account
Account Name: Count Dracula
Balance: 940
Overdraft Limit: 500
Penalty: 50

Penalty in Savings Account: 10.5
Account Name: New Savings Account for Tom
Balance: 90
Overdraft Limit: 50
Penalty: 0
***************************************************

As you can see in the last s1.Report, it is showing penalty as 0.0, which
I assume is the Base.Penalty and that I am call the Withdraw from the
Base. But I thought that it would use the values from the object where
Penalty was overridden.

Obviously that was not the case.

Do I have to write a Withdraw method for my SavingsAccount class and
overwrite the Base class?

Also, why can't you have a static Penalty in both Account and
SavingsAccount?

There are so many thing that can and should be done different in your
code.

Try and compare your code with the version below.

Arne

============================================================

using System;
using System.Collections.Generic;
using System.Text;

namespace TestingInheritance3
{
public class Account
{
private string name;
private decimal balance;
private decimal overDraftLimit;
protected decimal penalty;

public string Name
{
get { return name; }
set { name = value; }
}
public decimal Balance
{
get { return balance; }
}
public decimal OverDraftLimit
{
get { return overDraftLimit; }
set { overDraftLimit = value; }
}
public decimal Penalty
{
get { return penalty; }
set { penalty = value; }
}

public Account(string name, decimal balance, decimal
overDraftLimit)
{
this.name = name;
this.balance = balance;
this.overDraftLimit = overDraftLimit;
penalty = 50.00m;
}

public void Deposit(decimal amt)
{
if (amt < 0.00m)
{
throw new ArgumentOutOfRangeException("Deposit: invalid
argument");
}
balance += amt;
}

public void Withdraw(decimal amt)
{
if (amt < 0.00m)
{
throw new ArgumentOutOfRangeException("Withdraw: invalid
withdrawal");
}

if (balance - amt + overDraftLimit < 0.00m)
{
throw new ArgumentOutOfRangeException("Withdraw: not
enough funds");
}
else
{
Console.WriteLine("In Withdraw penalty = {0}", penalty);
balance -= (amt + penalty);
Console.WriteLine("After Withdraw balance = {0}",
balance);
}
}

public virtual void Report()
{
Console.WriteLine("Account Name: {0}", name);
Console.WriteLine("Balance: {0}", balance);
Console.WriteLine("Overdraft Limit: {0}", overDraftLimit);
Console.WriteLine("Penalty: {0} ", penalty);
}
}
public class SavingsAccount : Account
{
public SavingsAccount(string name, decimal balance, decimal
overDraftLimit) : base(name, balance, overDraftLimit)
{
penalty = 10.50m;
}

public new void Report()
{
base.Report();
Console.WriteLine("Penalty in Savings Account: {0} ",
penalty);
}
}
public class program
{
public static void Main(string[] args)
{
Account a1 = new Account("Count Dracula", 1000.00m, 500.00m);
SavingsAccount s1 = new SavingsAccount("Franky", 100.00m,
50.00m);
s1.Name = "New Savings Account for Tom";
a1.Report();
Console.WriteLine();
s1.Report();
Console.WriteLine();
a1.Withdraw(10);
Console.WriteLine();
s1.Withdraw(10);
Console.WriteLine("After withdrawing 10 from Savings account
and regular Account");
a1.Report();
Console.WriteLine();
s1.Report();
Console.Read();
}
}
}

I understand why you changed the doubles to decimals, but why were you
reversing the base.Report() and Console.WriteLine?

public new void Report()
{
Console.WriteLine("Penalty in Savings Account: {0} ", penalty);
base.Report();
}

Tom
 
A

Arne Vajhøj

tshad said:
Arne Vajhøj said:
using System;
using System.Collections.Generic;
using System.Text;

namespace TestingInheritance3
{
public class Account
{
private string name;
private decimal balance;
private decimal overDraftLimit;
protected decimal penalty;

public string Name
{
get { return name; }
set { name = value; }
}
public decimal Balance
{
get { return balance; }
}
public decimal OverDraftLimit
{
get { return overDraftLimit; }
set { overDraftLimit = value; }
}
public decimal Penalty
{
get { return penalty; }
set { penalty = value; }
}

public Account(string name, decimal balance, decimal
overDraftLimit)
{
this.name = name;
this.balance = balance;
this.overDraftLimit = overDraftLimit;
penalty = 50.00m;
}

public void Deposit(decimal amt)
{
if (amt < 0.00m)
{
throw new ArgumentOutOfRangeException("Deposit: invalid
argument");
}
balance += amt;
}

public void Withdraw(decimal amt)
{
if (amt < 0.00m)
{
throw new ArgumentOutOfRangeException("Withdraw: invalid
withdrawal");
}

if (balance - amt + overDraftLimit < 0.00m)
{
throw new ArgumentOutOfRangeException("Withdraw: not
enough funds");
}
else
{
Console.WriteLine("In Withdraw penalty = {0}", penalty);
balance -= (amt + penalty);
Console.WriteLine("After Withdraw balance = {0}",
balance);
}
}

public virtual void Report()
{
Console.WriteLine("Account Name: {0}", name);
Console.WriteLine("Balance: {0}", balance);
Console.WriteLine("Overdraft Limit: {0}", overDraftLimit);
Console.WriteLine("Penalty: {0} ", penalty);
}
}
public class SavingsAccount : Account
{
public SavingsAccount(string name, decimal balance, decimal
overDraftLimit) : base(name, balance, overDraftLimit)
{
penalty = 10.50m;
}

public new void Report()
{
base.Report();
Console.WriteLine("Penalty in Savings Account: {0} ",
penalty);
}
}
public class program
{
public static void Main(string[] args)
{
Account a1 = new Account("Count Dracula", 1000.00m, 500.00m);
SavingsAccount s1 = new SavingsAccount("Franky", 100.00m,
50.00m);
s1.Name = "New Savings Account for Tom";
a1.Report();
Console.WriteLine();
s1.Report();
Console.WriteLine();
a1.Withdraw(10);
Console.WriteLine();
s1.Withdraw(10);
Console.WriteLine("After withdrawing 10 from Savings account
and regular Account");
a1.Report();
Console.WriteLine();
s1.Report();
Console.Read();
}
}
}

I understand why you changed the doubles to decimals, but why were you
reversing the base.Report() and Console.WriteLine?

public new void Report()
{
Console.WriteLine("Penalty in Savings Account: {0} ", penalty);
base.Report();
}

The main change was that I sure that each object only had one penalty
field.

The switch in Report was not strictly necessary. But in some cases
it is important to call the base method first. It felt "natural"
for me to do it in that order.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top