Interface, Abstract, or just virtual methods?
Asked Answered
N

6

8

I have a bunch of systems, lets call them A, B, C, D, E, F, G, H, I, J.

They all have similar methods and properties. Some contain the exact same method and properties, some may vary slightly and some may vary a lot. Right now, I have a lot of duplicated code for each system. For example, I have a method called GetPropertyInformation() that is defined for each system. I am trying to figure out which method would be the best approach to reduce duplicate code or maybe one of the methods below is not the way to go:

Interface

public Interface ISystem
{
    public void GetPropertyInformation();
    //Other methods to implement
}

public class A : ISystem
{
    public void GetPropertyInformation()
    {
       //Code here
    }
}

Abstract

public abstract class System
{
    public virtual void GetPropertyInformation()
    {
        //Standard Code here
    }
}

public class B : System
{
   public override void GetPropertyInformation()
   {
      //B specific code here
    }
}

Virtual Methods in a Super Base class

public class System
{
   public virtual void GetPropertyInformation()
    {
     //System Code
    }
}

public class C : System
{
  public override void GetPropertyInformation()
  {
      //C Code
  }
}

One question, although it may be stupid, is let's assume I went with the abstract approach and I wanted to override the GetPropertyInformation, but I needed to pass it an extra parameter, is this possible or would I have to create another method in the abstract class? For example, GetPropertyInformation(x)

Naamann answered 28/9, 2011 at 20:24 Comment(0)
U
6

Your abstract and 'super base class' approaches are not too different. You should always make the base class abstract, and you can provide a default implementation (virtual methods) or not (abstract methods). The deciding factor is whether you ever want to have instances of the base class, I think not.

So it's between base class and interface. If there is a strong coupling between your A, B C classes then you can use a base class and probably a common implementation.

If the A, B, C classes do not naturally belong to a single 'family' then use an interface.

And System is not such a good name.

And you cannot change the parameterlist when overriding. Maybe default parameters can help, otherwise you just need 2 overloads for GetPropertyInformation().

Unsophisticated answered 28/9, 2011 at 20:31 Comment(1)
I had a feeling the abstract and super base classes were similar. The A, B, C systems do have a strong coupling. There is an industry standard, but it does not have to be followed, so each one can either adopt the standard or alter the standard to their fitting. In haste, I picked System :)Naamann
C
3

Generally you choose object inheritance when you want to share implementation and reduce what would otherwise be duplication. Otherwise interfaces win because they are more flexible since there is no need for a common base class.

As for overriding a method and modifying the parameter list that's just not possible. Imagine how you would call that method on a base class or an interface reference?

Calabrese answered 28/9, 2011 at 20:30 Comment(3)
It is "possible" – you should be able to declare such a method, it's just no longer an override of the original method.Krissykrista
@Sii It certainly is not possible. The question asked to override the method and add a parameter. That cannot be done.Calabrese
"choose inheritance when you want to share implementation" can be troublesome. I would say: when you can share implementation. The type-relation should be solid first.Unsophisticated
S
3

I'd go with something like what I've added below. You still get the benefit of the interface contract and shared implementation.

public Interface ISystem
{
    public void GetPropertyInformation();
    //Other methods to implement
}

public abstract class System : ISystem
{
    public virtual void GetPropertyInformation()
    {
        //Standard Code here
    }
}

public class B : System
{  
   public string ExtendedSystemProp {get;set;}

   public override void GetPropertyInformation()
   {
      base.GetPropertyInformation();

      var prop = "some extra calculating";

      GetExtraPropertyInformation(prop);
    }

    public void GetExtraPropertyInformation(string prop)
    {
         ExtendedSystemProp = prop;
    }
}

ISystem genericSystem = new B();
genericSystem.GetPropertyInformation();

(genericSystem as B).ExtendedSystemProp = "value";
Snaggy answered 28/9, 2011 at 20:32 Comment(2)
Can you elaborate on why you would do this approach?Naamann
This way, you still get all of your properties even when you are only programming with the ISystem interface (which you should do when you have them). However, if you are coding in a context where only B exists: B bSystem = new B(); you also expose the B specific method for explicit use.Snaggy
P
2

You cannot pass the extra parameter in the override. When you are overriding, you are overriding the method with the exact signature. I would suggest you pass in an interface parameter like IPropertyInformation that can change per implementation.

The decision to go with a base class or an interface for your implementation really depends upon your use. Do A-I have enough in common with each other that they should really all derive from the same base class? If so, then use a base class. Is it really that just GetPropertyInformation is shared and otherwise the systems are totally functionally different? Then you really just want them to share an interface.

Perceval answered 28/9, 2011 at 20:32 Comment(0)
K
2

Others have covered what was originally in my answer, but about the "adding a parameter" point: Don't forget that the latest C# also lets you have optional parameters in methods.

Krissykrista answered 28/9, 2011 at 20:34 Comment(1)
But I would have to declare optional parameters in the very beginning. I may not know that I need a parameter until 1 year down the road, so optional parameters do me no good in that case.Naamann
K
2

Unless you have a compelling reason otherwise, I'd go with the interface. Public virtual methods, though done a lot, is not ideal.

Kelvin answered 28/9, 2011 at 20:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.