【问题标题】:How could I call an abstract class method who is common between subclasses without instanciating any subclass如何在不实例化子类的情况下调用子类之间通用的抽象类方法
【发布时间】:2021-10-22 15:21:59
【问题描述】:

我有这样的代码:

interface Contract {
  createSomething(); //not common
  updateSomething(); //not common
  getSomething(); //method who is supposed to be common between all strategies
}
interface Strategy {
  createSomething();
  updateSomething();
  getSomething();
}
Abstract class AbstractStrategy implements Strategy {

  @Override
  getSomething() {
    // the common code
  }
}
class strategyA extends AbstractStrategy {

  @Override
  createSomething() {...}

  @Override
  updateSomething() {...}
}
class ContractImpl implements Contract {

  @Override
  createSomething() {
    //get the good strategy 
    //call the strategy.createSomething();
  }

  @Override
  updateSomething() {
    //get the good strategy 
    //call the strategy.updateSomething();
  }

  @Override
  getSomething() {
     **Here is the question**
  }
}

问题:

  • 我怎样才能重写这段代码,这样我就可以调用 getSomething() 方法,而不必实例化一个随机子类,只是用 super 关键字调用它?

【问题讨论】:

  • 我很确定你不能,因为这是抽象类的重点。或者您正在寻找一种静态方法,但这是不同的。

标签: java design-patterns abstract-class


【解决方案1】:

你不能。相反,您可以将代码提取到静态方法中,然后从getSomething() 调用它。这将允许您在需要时静态调用它, 在需要时也可以从实例中调用。 换句话说,你的 AbstractStrategy 类应该是这样的:

Abstract class AbstractStrategy implements Strategy {
    public static void sharedCode(parameters needed) {
        // the common code
    }


    @Override
    (signature) getSomething() {
        sharedCode(this.parametersNeeded);
    }
}

【讨论】:

  • 感谢您的回答,但我不能使用静态方法,因为 getSomething 方法使用非静态对象
  • 如果您有该方法需要的对象(如果您没有子对象但仍希望调用该方法,则应该这样做),您可以将参数添加到静态方法并传递它们在这两个地方。
  • 如果我理解,方法 sharedCode 有 getSomething 方法的内容?问题是 sharedCode 方法中的公共代码使数据库访问,因此它使用我在抽象类中注入的类变量。
  • 那么您需要为静态方法提供相同的变量。问题似乎是,如果您确实有一个实例,那么就没有数据库连接。因此,您无法完成您想做的事情。但是,您可以将变量传递给静态方法并在那里创建连接。然后,您将能够在静态和实例中执行您尝试执行的操作。如果这不是一个选项,您可能必须复制代码,一个在静态方法中,一个在实例中。静态方法是唯一可以在没有实例的情况下运行的方法。
【解决方案2】:

你基本上不能。无法实例化抽象类,因此如果没有具体实现的对象(在您的情况下是AbstractStrategy 的任何具体子类),您就无法调用实例方法。

您可以选择创建一个匿名类,这样您就可以在不实例化AbstractStrategy 的任何子类的情况下调用该方法:

AbstractStrategy strategy = new AbstractStrategy() {
  @Override
  createSomething() {...}

  @Override
  updateSomething() {...}
}
strategy.getSomething();

但这感觉很老套。

【讨论】:

  • 感谢您的回答,我知道无法实例化抽象类。问题是如何构建我的代码,以便我可以在子类中处理 createSomething() 和 updateSomething,并且对于每个策略只在一个地方处理 getSomething()
  • 但这正是您的AbstractStrategy 提供的,一个实现getSomething() 的地方。它不能为您提供的是能够在没有AbstractStrategy 类型的对象的情况下调用这样的方法。为了拥有这样一个对象,你必须有一个具体实现它的对象,没有办法解决这个问题(除非你想使用静态方法,但在我看来你不这样做)。如果您不想在这种情况下使用您的子类之一,您可以使用匿名类。
  • 如果您担心AbstractStrategy 的子类可能会覆盖其getSomething() 实现,那么在AbstractStrategy 中将其标记为final:final void getSomething() { // the common code }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
相关资源
最近更新 更多