如果一个方法定义在一个超级 class 中,如何根据调用它的 object 改变结果

If a method is defined in a super class, how to change outcome depending on the object calling it

我有一个名为 BankAccount(定义为抽象)的 class,它是我的超级 class 和两个 children classes 称为 SavingsAccount 和 CheckingAccount。

它们都使用 BankAccount 中定义的 withdraw 方法,但是 CheckingAccount 可以透支 where-as SavingsAccount 不能。

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

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

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

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

    }

有没有一种方法可以根据是从 CheckingAccount 还是 SavingsAccount 调用构造函数来更改方法的响应方式 class

例如(这只是为了表达而不是真正的代码,而是 BankAccount class 中定义的一种方法,它本质上是这样做的)

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"); 
    }
}

我问这个是因为经过一些研究我发现你不能覆盖 child classes 中的超级 class 的参数所以这让我想知道这是怎么回事已完成。 SavingsAccount class 会有自己的属性等,为了清楚起见,我将它们省略了(in-case 你想知道)。

我知道在 CheckingAccount 中放置一个 withdraw 方法,在 SavingsAccount 中放置另一个方法会简单得多,但由于它们都提取资金,我想看看是否有可能将它放在 super class .

您可以使用方法的覆盖:

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;
  }
}

第二个class:

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 
  }
}

是的,但这有点老套。无论如何你都不应该。正如 PM 77 在他的评论中所说,"Your parent class should not know anything about its children." 你最好使用真正的 ODD 解决方案。

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

您需要的是以下其中一项:

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