【问题标题】:How to use interface method implemented by a class which also extends another class?如何使用由一个类实现的接口方法,该类也扩展了另一个类?
【发布时间】:2021-11-19 01:46:02
【问题描述】:

我有一些名为“Account”、“CurrentAccount”、“SavingsAccount”的类。 “CurrentAccount”和“SavingsAccount”扩展了“Account”,“CurrentAccount”也实现了“TaxDeduction”接口。 "TaxDeduction" 具有名称为 "deductTax()" 的方法,其主体在 "CurrentAccount" 中定义。

public class CurrentAccount extends Account implements TaxDeduction {
  public void deductTax() {
   double tax = (super.getBalance() * taxRate) / 100;
    super.setBalance(super.getBalance() - tax);
    }
}
public interface TaxDeduction {
    static double taxRate=8.5;
    void deductTax();
}

现在我创建了一个 Account[] 数组,其中存储了“CurrentAccount”和“SavingsAccount”的对象。当我在主类中检索“CurrentAccount”对象并尝试使用“deductTax()”方法时,我得到错误“deductTax()”方法未在“Account”中解析,而我可以在“CurrentAccount”中使用所有其他正常方法“ 班级。我该如何解决这个问题?

【问题讨论】:

  • 使用 instanceof 和 cast。或者保留一个单独的扣除清单。
  • @daniu 我是java新手,刚开始学,没看懂你说的什么意思,能否详细说明一下?
  • @MarkRotteveel 我可以调用所有其他子类和超类方法,但问题仅在于实现接口中的抽象方法“deductTax()”。

标签: java inheritance methods interface


【解决方案1】:

Java 是一种静态类型语言。如果你有一个Account 类型的变量,你只能调用Account 中定义的方法(及其超类和实现的接口)。尝试调用未在Account 中定义的方法将导致编译时错误,因为就编译器而言,变量中保存的值只是Account

所以,编译器不允许你调用TaxDeduction的方法,那么Account(或其超类之一)必须实现它,或者你必须检查变量持有的实例是否是TaxDeduction(使用instanceof),然后转换为TaxDeduction并调用该方法。

当您使用instanceof 时,您会在运行时检查实际类型,并且转换告诉编译器您确定它实际上是TaxDeduction,因此您可以调用TaxDeduction 中定义的方法。如果您对转换中的类型有误,您会得到一个运行时异常,ClassCastException(这就是为什么建议在转换之前使用instanceof)。

换句话说,类似于:

Account[] accounts = ...;
for (Account account : accounts) {
    if (account instanceof TaxDeduction) {
        ((TaxDeduction) account).deductTax();
    }
}

或在 Java 16 及更高版本中 (JEP 394):

Account[] accounts = ...;
for (Account account : accounts) {
    if (account instanceof TaxDeduction td) {
        td.deductTax();
    }
}

【讨论】:

  • 我检查了它确实是 TaxDeduction 的实例,通过转换为 TaxDeduction 我也可以按照您上面所说的调用该方法,但我仍然很困惑为什么我需要转换为 TaxDeduction 而不能直接使用 deductTax() ?
  • @MohsinZubair Java 是一种静态类型语言。如果你有一个Account 类型的变量,那么即使你有一个CurrentAccount 类型的对象分配给该变量,你也只能访问Account 类型中定义的方法。尝试调用未在Account 中定义的方法将导致编译时错误,因为就编译器而言,变量 中保存的值 只是Account。当您使用 instanceof 时,您会在运行时检查实际类型,并且强制转换告诉编译器您确定它实际上是 TaxDeduction
  • @MohsinZubair 如果你对转换中的类型有误,你会得到一个运行时异常,ClassCastException(这就是为什么建议在转换之前使用instanceof)。跨度>
  • 感谢澄清,现在我完全理解了。
猜你喜欢
  • 2016-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-30
  • 2012-12-07
  • 2010-10-13
  • 2013-05-24
相关资源
最近更新 更多