2016-03-27 26 views
0

我有一个父类“bankAccount”与两个子类,然后这些子类派生到其他子类。我想创建一个孙子对象并将它保存在一个List中,然后能够与孙子们的方法进行交互。但是我似乎无法访问这些类的方法。我所能做的只是与祖父母班的方法互动。如何访问列表中的子类的方法?

这就是我向列表添加子类的方法。

List<bankAccount> accounts = new List<bankAccount>(); 
accounts.Add(new VistaAccount(nAccount,pass,nameClient,balance,interest)); 
+0

发布类声明的代码。方法是公开的吗? –

+0

是的,每个类的构造函数和方法都是公共的。 –

回答

2

首先,明白为什么C#不会让您在银行账户列表中执行此操作。

如果您有各种银行账户,那么无论你做的列表中的任何人需要适用于他们中的每一个。你不能在一个对象上调用一个方法,除非该对象保证有该方法。静态类型系统是尽可能早地提醒你的。

话虽这么说,如果你真的知道你只有银行账户种类屈指可数,你也许可以单独列举出来:

foreach(var account in accounts.OfType<VistaAccount>()) 
{ 
    // call methods specific to "Vista" accounts 
} 

foreach(var account in accounts.OfType<OtherAccount>()) 
{ 
    // call methods specific to "Other" accounts 
} 

现在记住,这种方法并不能很好地扩展在长期。如果将来引入更多亚型,您可能需要回到那个位置并添加更多特殊情况。

如果您想要在每个帐户上执行特定的操作,并且该操作的详细信息因每种帐户类型而异,则有更好的方法来执行此操作。只需用你的基地的银行帐户类型声明一个抽象方法:

public abstract void Operation(); 

然后实现(override)这种方法在每个帐户的种类,具体到那种指令。

  • 从长远来看,这可以很好地扩展,因为您不必在每次引入更多账户类型时都引入特殊情况。还有一件事是为未来的自己或代码的未来维护者记录。
  • 它更方便,因为如果你忘记指定子类型的操作,你会在编译时得到一个好消息。所以如果你忘记这么做的话,那就有一个很好的安全网。
  • 因为现在每种银行账户都支持该操作,所以编译器会很乐意让您在银行账户列表中拨打电话。您不需要我最初提出的手动类型检查。
+1

我故意没有解释投射或反射,因为它的问题非常像尝试做错误的事情,因为错误的原因,但我想这样做的方式不存在,现在没有理由,所以... +1 – Kris

1

您无法通过父级的api访问子级的成员。你需要引用一个暴露成员的类型,或者通过强制转换(这通常是坏/丑),或者通过定义一个引用来作为子类型的开始。

如果你确实需要一个子对象列表,为什么你要使用父母列表?如果不是更多,您需要重新考虑当前方法的设计。

2

简单地说:你想要的东西不能完成,实际上是错误的。

高级:你想要什么都可以用反射或者铸造完成但是仍然是很不对错误。

您只能使用list<BankAccount>中的项目中声明的方法(BankAccount)。如果你需要你的孙子对象行为不同,你应该在孙子类中覆盖方法(你的BankAccount类中必须是虚拟的)。

1

这涉及到Liskov Substitution Principle。你有一堆对象 - 有些可能是VistaAccount,其他类型的,但它们都从bankAccount继承。通过将它们放在List<bankAccount>中,您将它们全部作为基类bankAccount进行投射。

在这种情况下,重点是您将它们全部视为bankAccount,根本不管它们是否为VistaAccount或其他某种类型。唯一重要的类型是bankAccount,而子类不重要。

如果您正在检查这些单个实例以查看它们的真实类型,那么可能是因为某些错误。如果您必须检查每个对象以查看其类型,那么目的就会被击败。根据其逻辑结论,它可能只是一个List<object>

你想要什么(如果可能的话)是一个设计,你在每个类上调用的方法是相同的,只有这些方法的行为是不同的。例如,Circle,SquareTriangle可以各自从Shape继承,并且每一个覆盖Draw()方法。该方法对于每个班级都是不同的。但是,如果你把它们全部放在List<Shape>中,那么你可以在每个方法上调用Draw()方法,而不知道每个方法是哪个子类。

相关问题