Java继承问题:确定适当的子类

时间:2010-09-18 16:19:33

标签: java oop

我有一个名为account的抽象类,如下所示 -

abstract class Account
{
    private int number;
    private String owner;

    public Account(int accountNumber, String  accountOwner)
    {
        number = accountNumber;
        owner = accountOwner;
    }

    public int getAccountNumber(){ return number; }
    public String getAccountOwner(){ return owner; }
    public abstract double getBalance();
    public abstract double  makeDeposit(double  amount);
    public abstract double  makeWithdrawal(double  amount);
}

此类定义帐户的基本框架。将通过继承此类来创建多个专业帐户类,例如MarketSavingsAccountRegularSavingsAccount等。

现在我有一个声明如下的数组 -

Account[] accounts

其中包含一个帐户列表。在此阵列中,可以使用不同类型的帐户。现在,我如何确定这些数组成员中的哪一个是MarketSavingsAccount的实例?

5 个答案:

答案 0 :(得分:5)

从纯粹的OOP角度来看,你不应该关心;你应该避免向下转发,并将所有的Account实例都视为一样。

但足够的理论 - 你可能正在寻找instanceof,如

Account a = accounts[0];
if (a instanceof MarketSavingsAccount)
{
    ...
}

答案 1 :(得分:3)

您可以遍历数组并使用instanceof运算符来确定当前元素是否为MarketSavingsClass的实例。

像这样(未经测试):

for (Account anAccount : accounts) {
    boolean isInstance = anAccount instanceof MarketSavingsClass;
}

那说你需要再看一下你的设计。除非在极少数情况下,否则您不必键入支票。

答案 2 :(得分:2)

accounts[0] instanceof MarketSavingsClass

或动态版

MarketSavingsClass.class.isInstance(accounts[0])

More on the topic(向下滚动到“类型比较运算符instanceof”)

答案 3 :(得分:1)

考虑工厂设计模式。这是为了完成任务。

  • 创建一个名为Account的界面,用于定义帐户需要的所有方法。

  • 创建一个Factory类,如下所示:

public class AccountFactory {
   public static Account make([arguments]) {
      Account specificInstance = null;
      // Do whatever logic is necessary to determine the type of account you need.
      return specificInstance;
   }
}

您必须提供make()足够的信息来决定哪种类型的帐户实施是合适的。

  • 创建您的MarketSavingAccount, 所有的RegularSavingsAccount等等 实施帐户。

  • 让AccountFactory.make()确定正确的帐户 实现使用和返回 你是一个实例。

您的代码主线代码不应该关注正在处理的帐户类型。

答案 4 :(得分:1)

而不是使用instanceof,这不是面向对象的原因 - 具体来说,你应该在面向对象的设计中使用多态,你可以在Account类中指定帐户类型,不使用instanceof进行检查,而是使用getAccountType()

abstract class Account
{
    public enum Type { MARKET_SAVING, REGULAR_SAVING, CHECKING };

    private final Type type;
    private int number;
    private String owner;

    public Account(Type accountType, int accountNumber, String accountOwner)
    {
        type = accountType;
        number = accountNumber;
        owner = accountOwner;
    }

    public Type getAccountType(){ return type; }
    ...
}

必须要求子类指定Type,如果所有帐户构造函数都有Type参数,编译器将强制执行此操作。对于instanceof,没有编译时检查是否处理了Account的所有子类。您必须确保代码处理所有枚举值,但这通常比尝试了解和处理Account的所有子类更受限制,因为Type枚举被指定为帐户的一部分数据类型。

现在,如果某些行为对于每个帐户都应该是不同的,那么应该通过Account的子类,或者至少通过检查类型和执行特定操作的代码,多态地处理该行为,但是如果您只想查找特定类型的帐户,将该类型设置为Account对象的属性将允许您避免依赖于知道实现每个特定帐户类型的类。

public class MarketSavingsAccount extends Account
{
    MarketSavingsAccount(int accountNumber, String accountOwner)
    {
        super(Type.MARKET_SAVING, accountNumber, accountOwner);
    }
    ...
}

也许MarketSavingsAccount的其他一些实现需要被视为市场储蓄类型的帐户:

public class OtherMarketSavingsAccount extends Account
{
    OtherMarketSavingsAccount(int accountNumber, String accountOwner)
    {
        super(Type.MARKET_SAVING, accountNumber, accountOwner);
    }
    ...
}

如果您的代码只想查找市场保存帐户,您只需遍历数组并对Type.MARKET_SAVING进行操作,其中包括MarketSavingsAccount和OtherMarketSavingsAccount以及您可能拥有的任何其他实现。

for (Account account : accounts) {
    if (account.getAccountType() == Type.MARKET_SAVING) {
        addToDirectMailAccountsList(account); // Or whatever
    }
}