Interface or abstract class?

For my new Pet-Project I have a question for design, that is decided already, but I want some other opinions on that too.

I have two classes (simplified):

class MyObject
{
  string name {get;set;}
  enum relation {get;set;}
  int value {get;set;}
}

class MyObjectGroup
{
  string name {get;set;}
  enum relation {get;set;}
  int value {get;set;}
  List<MyObject> myobjects {get;set;}
}

Later in the Project MyObjectGroup and MyObject should be used equally. For this I could go two ways:

  • Create an interface: IObject
  • Create an abstract class: ObjectBase

I decided to go the way of the interface, that I later in code must not write ObjectBase every time but IObject just for ease - but what are other positives for this way?

And second, what about adding IXmlSerializable to the whole story? Let the interface inherit from IXmlSerializable or does it have more positives to implement IXmlSerializable in abstract base class?


Solution 1:

Generally speaking, the approach I use in this kind of situation is to have both an interface and an abstract class. The interfaces defines, well, the interface. The abstract class is merely a helper.

You really can't go wrong with this approach. Interfaces give you the flexibility to change implementation. Abstract classes give you boilerplate and helper code that you aren't forced to use, which you otherwise would be if your methods were defined in terms of an abstract class explicitly.

Solution 2:

These are some of the differences between Interfaces and Abstract classes.

1A. A class may inherit (Implement) one or more interfaces. So in C#, interfaces are used to achieve multiple inheritance.
1B. A class may inherit only one abstract class.

2A. An interface cannot provide any code, just the signature.
2B. An abstract class can provide complete, default code and/or just the details that have to be overridden.

3A. An interface cannot have access modifiers for the subs, functions, properties etc everything is assumed as public.
3B. An abstract class can contain access modifiers for the subs, functions, properties.

4A. Interfaces are used to define the peripheral abilities of a class. For eg. A Ship and a Car can implement a IMovable interface.
4B. An abstract class defines the core identity of a class and there it is used for objects.

5A. If various implementations only share method signatures then it is better to use Interfaces.
5B. If various implementations are of the same kind and use common behaviour or status then abstract class is better to use.

6A. If we add a new method to an Interface then we have to track down all the implementations of the interface and define implementation for the new method.
6B. If we add a new method to an abstract class then we have the option of providing default implementation and therefore all the existing code might work properly.

7A. An interface can not have fields defined.
7B. An abstract class can have fields and constants defined.

8A. An interface can not have constructor.
8B. An abstract class can have default constructors implemented.

9A. An interface can only inherit from other interfaces.
9B. An abstract class can inherit from interfaces, abstract class, or even class.

Solution 3:

The interface would be my default until there is a reason to use a base class, as it makes fewer decisions for us.

I wouldn't involve IXmlSerializable unless I had to though; it is a messy, tricky interface that is often a cause of woe.

What exactly are your serialization requirements? There may be better options... however, for many serializers a base-class would be easier than an interface. For example, for XmlSerializer you could have:

[XmlInclude(typeof(MyObject))] // : ObjectBase 
[XmlInclude(typeof(MyObjectGroup))] // : ObjectBase 
public abstract class ObjectBase { /*  */ }

(the exact approach depends on the serializer)