【问题标题】:If a method is defined in a super class, how to change outcome depending on the object calling it如果在超类中定义方法,如何根据调用它的对象更改结果
【发布时间】:2017-05-17 17:01:12
【问题描述】:

我有一个名为 BankAccount 的类(定义为抽象类),它是我的超类和两个名为 SavingsAccount 和 CheckingAccount 的子类。

它们都使用 BankAccount 中定义的提款方法,但是 CheckingAccount 可以透支,而 SavingsAccount 则不能。

我的问题是,如果在 BankAccount 构造函数中我们包含以下内容:

public BankAccount(double balanceIn, double withdrawIn)
    {
        balance = balanceIn;
        withdraw = withdrawIn;
    }  

可以通过以下方式从 SavingsAccount 类调用:

public SavingsAccount(double balanceIn, double withdrawIn)
    {
    // initialise instance variables
    super (balanceIn, withdrawIn);

    }

有没有办法根据构造函数是从 CheckingAccount 还是 SavingsAccount 类调用来改变方法的响应方式

例如(这只是为了表达而不是真正的代码,但是在 BankAccount 类中定义的方法基本上可以做到这一点)

public void setWithdraw(double withdrawIn)
{
    withdraw = withdrawIn;


    if (withdrawIn is called from savingsAccount && balance < withdrawIn)
    {
        System.out.print("You have insufficient funds");
    }
    else 
    {
        balance = balance - withdrawIn;
        System.out.print("Funds Withdrawn"); 
    }
}

我问这个是因为经过一些研究后,我发现您无法覆盖子类中超类的参数,所以这让我想知道这是如何完成的。 SavingsAccount 类将有其自己的属性等,为了清楚起见(以防您想知道),我将其省略了。

我知道在 CheckingAccount 和 SavingsAccount 中放置一个withdraw 方法会简单得多,但由于它们都提取资金,我想看看是否可以在超类中使用它。

【问题讨论】:

  • 你在尝试类似this instanceof SavingsAccount 的东西吗?
  • 你的父类不应该知道它的子类。
  • 为什么要在账户的构造函数中取钱?
  • 嗯,这是一些练习,但经过反思,我明白了你的观点,撤回不应该添加到构造函数中,我只是想向构造函数添加尽可能多的“通用东西”可能出于测试目的。

标签: java object if-statement superclass


【解决方案1】:

您可以使用方法的覆盖:

public class BankAccount {
  public BankAccount(double balanceIn, double withdrawIn) {
    balance = balanceIn;
    setWithdrawn(withdrawIn);
  }

  protected void setWithdrawn(double withdrawIn) {
    // do the base stuff like withdraw = withdrawIn;
  }
}

还有二等:

public class SavingsAccount extends BankAccount {
  public BankAccount(double balanceIn, double withdrawIn) {
    super(balanceIn, withdrawIn);
  }

  // overwrite setWithdrawn
  @Override
  protected void setWithdrawn(double withdrawIn) {
    // do the specific stuff like the code of setWithdrawn in your post 
  }
}

【讨论】:

  • 这是我正在寻找的确切答案,谢谢!
【解决方案2】:

是的,但它有点 hacky。而且你不应该无论如何。就像 PM 77 在他的评论中所说的那样,“你的父类不应该知道任何关于它的孩子的事情。”使用真正的 ODD 解决方案会更好。

子类独有的所有行为都应该放在该子类中。子类之间共享的所有行为(如果有的话)都应该放在超类中。如果子类之间没有共享行为(除了方法签名),那么超类应该是interfaceabstract

你需要的是以下之一:

  1. 在超类中声明该方法,但在子类中定义它。您可以通过将超类设为interfaceabstract 来实现这一点(或者甚至只使用一个方法abstract),然后重写子类中的方法以定义它。这种方法的好处是确保每个子类都有方法(这是您的架构的 OOD 契约),但行为对于子类来说是唯一的。如果永远不会直接实例化超类(只有子类会),这种方法是合适的。
  2. 将共享行为放在超类中,将不同行为放在每个子类中。让子类的方法调用超类的方法来获取共享行为,然后直接在子类的方法中执行不同的行为。使用super 访问超类方法(语法与this 相似)。这种方法具有模块化共享功能的好处,但仍然允许每个子类向方法添加独特的行为。这种方法最适合构造函数,但可以与任何方法一起使用。
  3. 覆盖子类中的方法。 换句话说,定义一个在子类中具有完全相同签名但行为不同的方法。因此,子类的方法将“覆盖”超类的方法,允许您为每个子类指定唯一的行为。这种方法的好处是允许超类仍然直接实例化并调用其方法,同时还使每个子类都具有独特的行为。这种方法适用于非构造方法。

【讨论】:

  • 谢谢你,我发现它很有用。
猜你喜欢
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-18
  • 1970-01-01
相关资源
最近更新 更多