在含有抽象方法的抽象类中重构具体方法

3

考虑以下代码:

abstract class AbstractClass
{
 public abstract void AbstractMethodA();
 public void ConcreteMethodA()
 {
  //Some operation
  ConcreteMethodB();
 }
}

 public void ConcreteMethodB()
 {
  //Huge code unrelated to this class
  AbstractMethodA();
 }
}

class DerivedClass : AbstractClass
{
public void AbstractMethodA()
{
//Some operation
}
}

现在我想将ConcreteMethodB()移至单独的类,并从抽象类中的方法ConcreteMethodA()调用它。但由于ConcreteMethodB()使用了在DerivedClass中实现的抽象方法AbstractMethodA(),我无法从新类中访问该方法AbstractMethodA()。有什么解决办法吗?

2个回答

7
为什么不这样做?
static class Helper {
 public static void ConcreteMethodB(AbstractClass caller)
 {
      //Huge code unrelated to this class
      caller.AbstractMethodA();
 }
}

在AbstractClass中。
abstract class AbstractClass
{
 public abstract void AbstractMethodA();
 public void ConcreteMethodA()
 {
  //Some operation
  Helper.ConcreteMethodB(this);
 }
}

从David Arno的接口解耦建议开始编辑:

static class Helper {
 public static void ConcreteMethodB(IAbstractClass caller)
 {
      //Huge code unrelated to this class
      caller.AbstractMethodA();
 }
}
interface IAbstractClass {
     void AbstractMethodA();
}

然后在抽象类中实现

abstract class AbstractClass
{
 public abstract void AbstractMethodA();
 public void ConcreteMethodA()
 {
  //Some operation
  Helper.ConcreteMethodB(this);
 }
}

这样可以更好地隔离层。当然,David在他的帖子中提到使用“Action”并将方法作为参数传递的解决方案也值得考虑。


1
我会进一步提出 ConcreteMethodB(IAbstractClass caller),并创建一个接口来实现 AbstractClass,以降低耦合度。 - David Arno
@DavidArno 当然,我同意。 - Przemysław Ładyński
哦,你需要将 public void ConcreteMethodB... 更改为 public static void ConcreteMethodB。当我检查我的答案(我从你的答案中复制/粘贴/编辑)是否编译时,我发现了这一点 :) - David Arno
@user1928158 不,我刚在我的编译器中检查了一下,它可以正常工作。请确保您在ConcreteMethodB的定义中添加了“static”关键字,“public static void”应该是这样的。我在发布几分钟后就修复了这个问题。 - Przemysław Ładyński
抱歉,我的错。请忽略我之前的评论。我发表后几乎立即将其删除了。 - user1928158
@user1928158,谢谢你提供的信息 :) 很高兴知道它能够正常工作 :) 如果你最终解决了问题并且喜欢我的答案,请将其标记为答案。 - Przemysław Ładyński

4
为了完全解耦两者,您可以采用“函数式”方法:
static class Helper 
{
    public static void ConcreteMethodB(Action caller)
    {
        //Huge code unrelated to this class
        caller();
    }
}

将AbstractClass更改为:
abstract class AbstractClass
{
    public abstract void AbstractMethodA();
    public void ConcreteMethodA()
    {
        Helper.ConcreteMethodB(AbstractMethodA);
    }
}

太棒了。非常感谢你的所有帮助。我不得不尝试使用自定义委托而不是Action,因为实时方法还有一个参数。除了我尝试过的方法,还有更好的方法吗? - user1928158
@user1928158,Action<T> 可能会对你有所帮助。它是一个用于方法 void f(T param) 的内置委托。显然,在这种情况下,将 T 替换为你的参数类型。 - David Arno
我认为那是一种更加优雅的解决方案。谢谢 @David Arno。 - user1928158

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接