下面这段代码是这样的,ATM是主类,BankCard是基类,存款方法Deposit是非虚方法,取款方法Withdraw是虚方法,ForeignBankCard是派生类,用new和override分别重写这两个方法
card[1].Deposit(),调用了基类的方法,调用完之后,card[1]的money字段,为什么没有改?在调用card[1].Withdraw()方法的时候,money的初始值还是0,这是为什么,大侠们给讲一下内部原理吧!我才学C#两个星期,请尽量详细,谢谢了!namespace 银行卡
{
class ATM
{
static void Main(string[] args)
{
BankCard[] cards = new BankCard[2];
cards[0] = new BankCard();
cards[1] = new ForeignBankCard();
foreach (BankCard card in cards)
{
card.Deposit(5000);
card.Withdraw(200);
}
ForeignBankCard a = new ForeignBankCard();
a.Deposit(500);
a.Withdraw(100);
Console.ReadLine();
}
} public class BankCard
{
private decimal money; public BankCard()
{
money = 0m;
}
public void Deposit(decimal d)
{
money += d;
Display(d, money);
}
public virtual void Withdraw(decimal d)
{
money -= d;
Display(d, money);
}
public void Display(decimal a,decimal b)
{
Console.WriteLine("{0}卡存{1}元,当前余额{2}元", this.GetType().ToString(),a, b);
}
} public class ForeignBankCard:BankCard
{
private decimal money = 0m;
decimal rate = 0.01m;
public ForeignBankCard()
{
}
public new void Deposit(decimal d)
{
this.money = money + d;
Display(d, money);
}
public override void Withdraw(decimal d)
{
d *= (1 + rate);
this.money -= d;
Display(-d, money);
}
}
}
card[1].Deposit(),调用了基类的方法,调用完之后,card[1]的money字段,为什么没有改?在调用card[1].Withdraw()方法的时候,money的初始值还是0,这是为什么,大侠们给讲一下内部原理吧!我才学C#两个星期,请尽量详细,谢谢了!namespace 银行卡
{
class ATM
{
static void Main(string[] args)
{
BankCard[] cards = new BankCard[2];
cards[0] = new BankCard();
cards[1] = new ForeignBankCard();
foreach (BankCard card in cards)
{
card.Deposit(5000);
card.Withdraw(200);
}
ForeignBankCard a = new ForeignBankCard();
a.Deposit(500);
a.Withdraw(100);
Console.ReadLine();
}
} public class BankCard
{
private decimal money; public BankCard()
{
money = 0m;
}
public void Deposit(decimal d)
{
money += d;
Display(d, money);
}
public virtual void Withdraw(decimal d)
{
money -= d;
Display(d, money);
}
public void Display(decimal a,decimal b)
{
Console.WriteLine("{0}卡存{1}元,当前余额{2}元", this.GetType().ToString(),a, b);
}
} public class ForeignBankCard:BankCard
{
private decimal money = 0m;
decimal rate = 0.01m;
public ForeignBankCard()
{
}
public new void Deposit(decimal d)
{
this.money = money + d;
Display(d, money);
}
public override void Withdraw(decimal d)
{
d *= (1 + rate);
this.money -= d;
Display(-d, money);
}
}
}
{
card.Deposit(5000);
card.Withdraw(200);
} 改成这样 foreach (BankCard card in cards)
{
if (card is ForeignBankCard)
{
ForeignBankCard fCard = (ForeignBankCard)card;
fCard.Deposit(5000);
fCard.Withdraw(200);
}
else
{
card.Deposit(5000);
card.Withdraw(200);
}
}
运行成功,大至上可以明白问题所在。因为cards[1]的类型是BankCard,所以引用的是BankCard的Deposit而不是ForeignBankCard的Deposit,所以才会导致money的丢失。new关键字可以在派生类中隐藏基类的方法,但是,cards[1]的类型是基类BankCard,所以没办法起到隐藏作用,大至应该是这样。在某种说法上来说使用new是无奈之举,即是在作类升级时无法改动基类但又必须在派生类里重写某个方法时才用到的,一般正常情况下最好用虚方法来代替可能需要重写的方法。
这类new语法是c#(也是.net整个框架)这锅粥中的一粒老鼠屎,如果有人在跟我协作的工程使用它,我会觉得很恶心。
也不能这么说,new本身只是一个应急措施,就象大楼的安全通道一样。没事从二十楼走安全通道到一楼着实恶心,但在电梯不能用的情况下,安全通道还是非常必要的。
嗯,大至上是如此,我对BankCard foreignBankCard = new ForeignBankCard(); 这种方式的声明不太会描述才会这么说的。
new 也不是没用处,当你继承一个框架内置的类时,某些方法需要重写就用得着了
特别是GUI类库中,很多方法需要用NEW重写
而不应该new