使用派生类中的方法和基类类型的对象

时间:2011-11-20 20:36:48

标签: inheritance polymorphism

我的派生类里面有一个方法,我在基类中没有这个方法,有没有办法在基类类型的对象上使用派生类方法?我知道我可以将方法移动到我的基类,但我不认为我应该这样做..

以下是代码:

我想在我的循环中对我的帐户使用CalculateInterest(),但帐户都是Account类型,而不是SavingsAccount。

SavingsAccount类中的方法:

 public decimal CalculateInterest()
        {
            return AcctBalance * interestRate;
        }

在Main中循环:

List<Account> accounts = new List<Account>();

            Account sAcct1 = new SavingsAccount(200, 0.10M);
            Account sAcct2 = new SavingsAccount(300, 0.12M);
            Account cAcct1 = new CheckingAccount(500, 2.00M);
            Account cAcct2 = new CheckingAccount(400, 1.50M);

            accounts.Add(sAcct1);
            accounts.Add(sAcct2);
            accounts.Add(cAcct1);
            accounts.Add(cAcct2);
foreach (Account account in accounts)
            {
                account.Debit(decimal.Parse(Console.ReadLine()));
                account.Credit(decimal.Parse(Console.ReadLine()));
                if (account.GetType().ToString().Contains("SavingsAccount"))
                {
                    //calculate interest if object is a savings account
                }
            }

4 个答案:

答案 0 :(得分:0)

在这种情况下,最好在基类中使用calculateInterest()的默认实现,但不执行任何操作。

子类将覆盖以提供特定于帐户类型的利息计算。

答案 1 :(得分:0)

这似乎是一种语言特定的东西,而不是面向对象。特别是Java,虽然代码不完全是Java。

在任何情况下,如果你想拥有一种类型的结构并调用子类的方法,那么只需在对象上执行强制转换,之前使用instanceof运算符来检查类。

这可能不是最优雅的解决方案,它取决于您的问题,因此很难说出哪种模式或方式来组织您可以使用手头信息的代码。

您的代码提供的一个线索是您正在处理所有帐户,并且其中一些帐户计算兴趣。看起来您的方法可能同时执行两个或更多操作,并且可能需要拆分为两个或更多方法以提高可读性(可能)。无论你想要完成什么,都要更加努力地思考正确的设计,最终可能会为你解决问题。

答案 2 :(得分:0)

好吧,您可以尝试将每个帐户转换为SavingsAccount

if (account as SavingsAccount != null) { //calculate interest }

但是我想说在基类中实现calculateInterest没有任何问题,然后在必要时覆盖它(例如,SavingsAccount会覆盖它,CheckingAccount不会),如Dave Newton所述。

也许最好的方法是将帐户处理封装到一个新方法(也称为“流程”?)中并在每种情况下适当地实现它。例如。在帐户

public void process()
{
                this.Debit(decimal.Parse(Console.ReadLine()));
                this.Credit(decimal.Parse(Console.ReadLine()));
}

然后在SavingsAccount

中覆盖它
public override void process()
{
                base.process();
                //now calculate interest
}

这样可以避免在基类中实现的方法没有做任何事情。

答案 3 :(得分:0)

我几乎会从其他答案的部分内容中得到答案:)

我将Debit()Credit()作为Account上的方法,而不是将其隐藏在黑框Process()方法中,作为现实生活{{1}可以借记和贷记,所以这对我来说似乎是一个更合适的模型。我建议使用两种方法之一来包含Accounts方法。

第一个选项:正如@Dave Newton所提到的,定义一个CalculateInterest()接口,其上有IInterestBearingAccount方法,然后在CalculateInterest()中实现。你在main中的循环可以说:

SavingsAccount

这可以为您提供所需的内容,而不会将var interestBearingAccount = account as IInterestBearingAccount; if (interestBearingAccount != null) { interestBearingAccount.CalculateInterest(); } 计算兴趣的知识放在其他SavingsAccounts不属于Accounts方法的情况下。

第二个选项 - 在来自@Dave Newton答案的切线上 - 在名为Main的{​​{1}}上有一个空的virtual方法(或类似的东西),并Account打电话给那个。 CalculateSupplementals可以实现它来计算兴趣,Main无能为力。基类上的方法是通用命名的,因此实现类可以使用它作为钩子来进行额外的计算,如果适用于它们所代表的帐户类型;它不会将有关派生类的详细信息放入基类中,并为其他类提供特定于它们的工作。

我的个人偏好可能是第一个选项,因为它不会向层次结构中添加任何内容,只是为了满足不需要的派生类。