我有一个名为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);
}
此类定义帐户的基本框架。将通过继承此类来创建多个专业帐户类,例如MarketSavingsAccount
,RegularSavingsAccount
等。
现在我有一个声明如下的数组 -
Account[] accounts
其中包含一个帐户列表。在此阵列中,可以使用不同类型的帐户。现在,我如何确定这些数组成员中的哪一个是MarketSavingsAccount
的实例?
答案 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
}
}