user1928158
user1928158

Reputation: 173

Refactoring a concrete method in abstract class which contains an abstract method

Considering the below code,

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

Now I wish to move ConcreteMethodB() to separate class and make a call to this from the method ConcreteMethodA() in abstract class. But since ConcreteMethodB() uses an abstract method AbstractMethodA() implemented in DerivedClass, I am unable to access the method AbstractMethodA() from the new class? Any idea on how to resolve this?

Upvotes: 3

Views: 166

Answers (2)

Przemysław Ładyński
Przemysław Ładyński

Reputation: 1076

Why don't you make it like this

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

and then in AbstractClass

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

Edit including interface based decoupling suggestion from David Arno:

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

and then in AbstractClass

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

That gives you better layers isolation. Of course the solution suggested by David in his post mentioning usage of "Action" and passing method as argument is also worth consideration.

Upvotes: 7

David Arno
David Arno

Reputation: 43254

To completely decouple to the two, you could take the "functional" route:

static class Helper 
{
    public static void ConcreteMethodB(Action caller)
    {
        //Huge code unrelated to this class
        caller();
    }
}

The change AbstractClass to:

abstract class AbstractClass
{
    public abstract void AbstractMethodA();
    public void ConcreteMethodA()
    {
        Helper.ConcreteMethodB(AbstractMethodA);
    }
}

Upvotes: 4

Related Questions