I am working on a mini-framework for "runnable" things. (They are experiments, tests, tasks, etc.)
// Something that "runs" (in some coordinated way) multiple "runnable" things.
interface IRunnableOf<T> where : IRunnable
// Provide base-class functionality for a "runner"
abstract class RunnerBase<T> : IRunnableOf<T>
class SequentialRunner<T> : RunnerBase<T> // Same interface, different behavior.
class ConcurrentRunner<T> : RunnerBase<T>
// other types of runners.
class ConcurrentBlockRunner : SequentialRunner<Block>
class SequentialBlockRunner : ConcurrentRunner<Block>
Now, how can I reconcile ConcurrentBlockRunner and SequentialBlockRunner? By this I mean:
Refer to them by a common ancestor, for use in a collection. (IEnuerable<T> where T = ??)
Provide additional base class functionality. (Add a property, for example).
I remedied #1 by adding another interface that just specified a type parameter to IA<T>:
interface IBlockRunner : IRunnableOf<Block> { }
And modified my ConcurrentBlockRunner and SequentialBlockRunner definitions to be:
class ConcurrentBlockRunner : SequentialRunner<Block>, IBlockRunner
class SequentialBlockRunner : ConcurrentRunner<Block>, IBlockRunner
Since ConcurrentBlockRunner and SequentialBlockRunner both use Block for their type parameter, this seems to be a correct solution. However, I can't help but feel "weird" about it, because well, I just tacked that interface on.
For #2, I want to add a couple pieces of common data to ConcurrentBlockRunner and SequentialBlockRunner. There are several properties that apply to them, but not to their only common base class, which is all the way up at RunnerBase<T>.
This is the first time while using C# that I've felt multiple inheritance would help. If I could do:
abstract class BlockRunnerBase {
int Prop1 { get; set; }
int Prop2 { get; set; }
class ConcurrentBlockRunner : SequentialRunner<Block>, BlockRunnerBase
class SequentialBlockRunner : ConcurrentRunner<Block>, BlockRunnerBase
Then I could simply add these extra properties to BlockRunnerBase, and everything would just work. Is there a better way?
I know I will be recommended immediately to consider composition, which I began to work with:
class BlockRunner : IBlockRunner {
IBlockRunner _member;
int Prop1 { get; set; } // Wish I could put these in some base class
int Prop2 { get; set; }
// Lots of proxy calls, and proxy events into _member
void Method() { _member.Method(); }
event SomeEvent
{
add { _member.SomeEvent += value; }
remove { _member.SomeEvent -= value; }
}
}
The problem I encountered (driving me to write this question) was that once you compose, you lose type compatibility. In my case, _member was firing an event, so the sender parameter was of type SequentialBlockRunner. However, the event handler was trying to cast it to type BlockRunner, which of course failed. The solution there is not use add/remove to proxy the events, but actually handle them, and raise an event of my own. So much work just to add a couple properties...
Composition over Inheritance, FTW!
To be more explicit:
class SequentialRunner<T> : RunnerBase<T>
should implement IRunnableOf<T> and proxy the RunnerBase<T> without inheriting it.
class SequentialRunner<T> : IRunnableOf<T>
{
private readonly RunnerBase<T> _runnerBase;
...
}
You can use extension methods to create mixin-like constructs, even with property-like elements.
I've also created an experiment with trait-like constructs in C#, NRoles.
But, all of these require non-standard coding, and will not be ideal for APIs that are meant to be exposed to third parties. I think you should try to rearrange your classes and use composition with delegation using interfaces if possible.
Related
When working with generics if I have for example a class:
class Foo<T> where T:Cheese
{
}
and then 2 derived classes
class FooDerivedBlue:Foo<BlueCheese>
{
}
class FooDerivedWhite:Foo<WhiteCheese>
{
}
where BlueChesse and WhiteCheese inherit from chesse.
Now there is another class, that will conditionally use FooDerivedBlue or FooDerivedWhite.
The class should have a property like
public Foo<Cheese> Foo {get;set;}
so I can set it to the FooDerivedXXX I need at runtime.
When doing this an trying to set Foo=new FooDerivedWhite() the compiler will complain, since FooDerivedWhite cant be converted to Foo<cheese>.
A more practical example:
If I have a
ArticleRepository<T>
AssemblyArticleRepository:ArticleRepository<AssemblyArticle>
ProductionArticleRepository:ArticleRepository<ProductionArticle>.
ProductionArticle and AssemblyArticle inherit from Article.
Both specific repositories inherit from ArticleRepository and have a lot of common logic. There are certain parts I need only access to the logic they shared (for example adding a new item or deleting it) and in order to avoid duplicate code, I want to instantiate the proper repo and pass it.
For example, I could have an ArticleService, which I pass a type and it instantiates the right repository. Instead, I would need to have a service for each Article type. (??- with my actual knowledge)
Which is the way to solve it in .NET? Or maybe I am facing the problem/writing my code in a wrong way?
Update Here a gist with the concrete problem:
https://gist.github.com/rgomez90/17ec21a1a371be6d78a53a4072938f7f
There are a few ways to deal with this, but the most straightforward is probably to make your "other class" also have a generic type parameter that describes what kind of cheese it operates on. Then all the types can be statically correct.
public abstract class Cheese { }
public class BlueCheese : Cheese { }
public abstract class CheeseTool<T> where T:Cheese { }
public class BlueCheeseTool : CheeseTool<BlueCheese> { }
public class CheeseEater<T> where T : Cheese {
public T Cheese;
public CheeseTool<T> Tool;
}
Then all typing is statically correct:
CheeseEater<BlueCheese> eater = new CheeseEater<BlueCheese>();
eater.Cheese = new BlueCheese();
eater.Tool = new BlueCheeseTool();
More complicated solutions might involve explicit casts and type factories, but simplest is best if it does the job.
I have two data entities, which are almost similar, design is something like:
public Class Entity1 : Base
{
public int layerId;
public List<int> Groups;
}
Difference is Entity1 has an extra collection of integer Groups
public Class Entity2 : Base
{
public int layerId;
}
These entities are filled as an input from UI using Json, I need to pass them to a processing method, which gives the same Output entity. Method has a logic to handle if List<int> Groups is null, I need to create a method which is capable of handling each of the input in an elegant manner. I cannot just use only Entity1, since they are two different functional inputs for different business process, so using Entity1 as direct replacement would be a mis-representation
Instead of creating overload of the function, I can think of following options:
Use object type as input and typecast in the function internally
I think we can similarly use dynamic types, but solution will be similar as above, it will not be a clean solution in either case, along with the switch-case mess.
What I am currently doing is processing method is like this:
public OuputEntity ProcessMethod(Entity 1)
{
// Data Processing
}
I have created a constructor of Entity1, that takes Entity2 as Input.
Any suggestion to create an elegant solution, which can have multiple such entities. May be using generic, where we use a Func delegate to create a common type out of two or more entities, which is almost similar to what I have currently done. Something like:
Func<T,Entity1>
Thus use Entity1 output for further processing in the logic.
I need to create a method which is capable of handling each of the input in an elegant manner
Create an Interface, or a contract so to speak, where each entity adheres to the particular design. That way common functionality can be processed in a similar manner. Subsequently each difference is expressed in other interfaces and testing for that interface sis done and the differences handled as such.
May be using generic,
Generic types can be tested against interfaces and a clean method of operations hence follows suit.
For example say we have two entities that both have Name properties as string, but one has an Order property. So we define the common interface
public interface IName
{
string Name { get; set; }
string FullName { get; }
}
public interface IOrder
{
decimal Amount { get; set; }
}
So once we have our two entities of EntityName and EntityOrder we can add the interfaces to them, usually using the Partial class definition such as when EF creates them on the fly:
public partial class EntityName : IName
{
// Nothing to do EntityName already defines public string Name { get; set; }
public string FullName { get { return "Person: " + Name; }}
}
public partial class EntityOrder : IName, IOrder
{
// Nothing to do Entity Order already defines public string Name { get; set; }
// and Amount.
public string FullName { get { return "Order: " + Name; } }
}
Then we can process each of them together in the same method
public void Process(IName entity)
{
LogOperation( entity.FullName );
// If we have an order process it uniquely
var order = entity as IOrder;
if (order != null)
{
LogOperation( "Order: " + order.Amount.ToString() );
}
}
Generic methods can enforce an interface(s) such as:
public void Process<T>(T entity) where T : IName
{
// Same as before but we are ensured that only elements of IName
// are used as enforced by the compiler.
}
Just create generic method that will do this work for you:
List<OuputEntity> MyMethod<T>(T value) where T : Base
// adding this constraint ensures that T is of type that is derived from Base type
{
List<OutputEntity> result = new List<OutputEntity>();
// some processing logic here like ...
return result;
}
var resultForEntity1 = MyMethod<Entity1>();
var resultForEntity2 = MyMethod<Entity2>();
P.S. check my answer for this question as you may find it useful too:
map string to entity for using with generic method
You probably want to implement an interface or an abstract class.
From MSDN
If you anticipate creating multiple versions of your component, create
an abstract class. Abstract classes provide a simple and easy way to
version your components. By updating the base class, all inheriting
classes are automatically updated with the change. Interfaces, on the
other hand, cannot be changed once created. If a new version of an
interface is required, you must create a whole new interface.
If the functionality you are creating will be useful across a wide range of
disparate objects, use an interface. Abstract classes should be used
primarily for objects that are closely related, whereas interfaces are
best suited for providing common functionality to unrelated classes.
If you are designing small, concise bits of functionality, use
interfaces. If you are designing large functional units, use an
abstract class.
If you want to provide common, implemented
functionality among all implementations of your component, use an
abstract class. Abstract classes allow you to partially implement your
class, whereas interfaces contain no implementation for any members.
Abstract Class Example
Cat and Dog can both inherit from abstract class Animal, and this abstract base class will implement a method void Breathe() which all animals will thus do in exactly the same fashion. (You might make this method virtual so that you can override it for certain animals, like Fish, which does not breath the same as most animals).
Interface Example
All animals can be fed, so you'll create an interface called IFeedable and have Animal implement that. Only Dog and Horse are nice enough though to implement ILikeable - You'll not implement this on the base class, since this does not apply to Cat.
In my interface, I have declared a property with setter and getter.
public interface ITestInterface
{
string AProperty { get; set; }
}
When I code my class which inherit that interface, why I need to define these two properties again?
public sealed class MyClass: ITestInterface
{
public string AProperty { get; set; }
}
Because you are not inheriting from an interface, you are implementing the interface. (although they both share same syntax :)
public class MyClass : IMyInterface { ... } //interface implementing
public class MyClass : MyBaseClass { ... } //inheriting from a class
Assume you are inheriting a candy box (not from your ancestors, in programming manner), it is something (not exactly) like you put the candy box in another box, now the outer box (the derived class, the inherited one) is inherited from candy box and have all the things candy box have, but if you want to implement (make) a candy box yourself you must build a box and put some candy in it. This is the way interfaces work.
Your interface definition only tells there is a property with a getter and setter, not how it is implemented. You could use auto-implemented properties, but you are not required to.
Following the interface, this would be a valid implementation:
public sealed class MyClass: ITestInterface
{
public string APROPERTY
{
get { return someField + " hello"; }
set { someOtherField = value; }
}
}
In an interface definition, string AProperty { get; set; } is the declaration of the property, while in a class, it means that the property is auto-implemented.
Short answer
Because interfaces contain no more than a definition of a class, and cannot contain the actual implementation of any member functions. It's by design.
Long answer
First you have to realize that properties are basically get and set member functions with some simplified syntax. The question here is therefore: why can't an interface definition contain an implementation of a member function?
Well, in some languages (most notably: C++) you can.
If you have an inheritance chain, that's basically solved through lookup tables. Say that you have member function 1, then in all the classes in the inheritance chain, there's a table which contains a pointer to function 1. Once you call a member function, the call basically grabs the first entry from the table belonging to the type of your object, and calls that. This thing is called a vtable (and for more details, see here).
Now, in C++, VTables are very transparent to the developer: each class basically has a vtable and there's no such thing as a real 'interface'. This also means that all classes can have implementations and members such as fields. If you have a class with only pure virtual members (e.g. functions without an implementation), you have the C++ equivalent of an 'interface'.
In software engineering, these classes were often called 'interface' classes, because they contain only a definition of what's going on, not the actual implementation. Interfaces have the nice property that they describe functionality without actually going into the details, thereby giving the possibility to put 'boundaries' in your code. There are a lot of use cases for this, including (RPC) communication, a lot of design patterns, and so on.
In C++, a class can derive from multiple classes (multiple inheritance) with and without an implementation. Also, because interfaces are in fact more like 'abstract' classes than like 'interfaces' in C#, this means you can also add functionality there. The vtable that was previously described therefore contains pointers to functions in all the base classes.
The problems with this start when you're starting to add functionality to interface classes. For starters, let's say you have something like this (I'll do this in sort-of C#):
interface A { Foo(); } // basically an interface.
interface B : A { Foo(); } // another interface
class B : A { void Foo() {...} } // implementation of Foo, inherits A
class D : B,C { } // inherits both B, C (and A via both B and C).
What we're interested in here is what happens if you call Foo in class D. For that, we have to construct a vtable for class D. Basically this vtable would look like this:
Foo() -> C::Foo()
This means that if you construct an object of D, and call Foo, you'll end up calling the implementation of Foo in type C:
var tmp = new D();
tmp.Foo(); // calls C::Foo()
It becomes more difficult when we're changing the definition of B into something like this:
class B : A { void Foo() {...} } // changed into an implementation
Again, we try to construct the vtable for class D and we end up with a problem:
Foo() -> C::Foo() or B::Foo()???
The problem we're facing here is: what implementation of Foo are we going to use when calling that member? Also, what constructor are we going to call? And what about destruction order? In C++ there are workarounds for this called virtual inheritance.
While designing .NET and the C# language, they thought about past experiences with multiple inheritance and the implications of virtual inheritance and decided that it's not only a difficult thing to implement, but also very confusing for developers at best. As you've seen, these problems don't exist when you just add interfaces.
So, that's why you cannot have a property (or a method) in your interface.
I think the problem here is, that the same syntax has two different meanings for interfaces and classes. AProperty { get; set; } is in an interface is the declaration-only, in a class it's an automatically implemented interface.
So that term is dependent on the context.
public interface ITestInterface
{
string AProperty { get; set; }
}
Declares the Property, but cannot implement it.
public sealed class MyClass: ITestInterface
{
public string AProperty { get; set; }
}
Implements the interface, where the property is automatically implemented (which only works for classes).
Interface contain property signatures not the actual definitions. You are actually requesting for any class implementing ITestInterface to implement get and set for AProperty. See this and this for more details.
As others say interface is just a container for your methods and properties signatures. It needs implementation but this implementation signature will be perfectly match with one that is used in interface. Also it guarantees that all of this members can be accessed in a class instance as they are by default public properties and without implementation program will not compile at all.
Let's say you have interface:
public interface ITestInterface
{
string AProperty { get; }
}
and class that implements it:
class MyClass : ITestInterface
{
public string AProperty { get { if (DateTime.Today.Day > 7) return "First week of month has past"; return "First week of month is on"; } }
}
It's not possible to use auto-implemented properties and not possible to add setter in this class because interface property lacks set accessor and auto-implemented properties requires that interface contains auto-implemented properties signature ({ get; set;}). So in your example interface just declares properties and that's it.
Just by knowing what interfaces class has inherited you know what members are there and if you just want to use (or allow user to use) some of this methods (not allowing to change anything though) you can always upcast your class instance to one of these interface types and pass it as a parameter.
I think the confusion here comes from the fact that auto properties (just the get and or set declarations) look the same in the interface and the implementation. The interface is merely a declaration (contract) of what a class must provide in order to be deemed an implementer of the interface. It is much clearer if you consider a method declaration in an interface vs its implementation in a class.
Interface = requirements;
Class = how those requirements are fulfilled
public interface ITestInterface
{
string GetAProperty();
}
public class MyClass : ITestInterface
{
public string GetAProperty()
{
// Do work...
return "Value";
}
}
thanks in advance for reading this. I don’t fully understand how/when to use abstracts so I am trying to think about it each project I work on to see if it will all click some day Smile | :)
Also, the mix of accessibility levels (private, protected, internal) with keywords static, abstract, and override tend to leave me a little confused. How do I define this method/property/class....
It's not all a big mystery to me but some projects have me coding in circles when dealing with these topics.
With that said,
I have an application that reads an XML document and outputs text and image files. I’m also storing all of the information in a database. I have it working nicely.
The XML has a standard implementation with required fields and is used by multiple organizations to submit data to my app. All organizations should use (at least) the required nodes/elements that are outlined in the XML implementation guide.
So, I want to have a default data object type to be able to derive a specific organization’s data type for required elements. (If this object is going to be used, these are the fields that must be implemented).
If the org. just uses the default requirements, I can use the default object. If they use additional (optional) fields, I’ll have to create a new type inheriting the default type.
My first thought was to use and abstract class that had protected properties for my bare minimum requirements:
public abstract partial class AbstractDataObject
{
protected string DataObjectName;
protected DateTime? DataObjectDate;
etc...
}
Then, if the organization just uses the required elements of the node and no optional elements, I can use a “default” object.
internal partial class DefaultDataObject : AbstractDataObject
{
public new string DataObjectName { get; set; }
public new DateTime? DataObjectDate { get; set; }
etc...
}
But, if an organization uses optional fields of the required node, I can use a derived organization data object.
internal sealed partial class OranizationDataObject : AbstractDataObject
{
public new string DataObjectName { get; set; }
public new DateTime? DataObjectDate { get; set; }
etc...
//Optional fields used by this organization
public string DataObjectCode { get; set; }
etc...
}
Do I need the abstract class? It seems to me I can just have a DefaultDataObject (something like):
internal partial class DefaultDataObject
{
public virtual string DataObjectName { get; set; }
public virtual DateTime? DataObjectDate { get; set; }
etc...
}
And then:
internal sealed partial class OranizationDataObject : DefaultDataObject
{
public override string DataObjectName { get; set; }
public override DateTime? DataObjectDate { get; set; }
etc...
//Optional fields used by this organization
public string DataObjectCode { get; set; }
etc...
}
I’m just really trying to understand how to define these objects so I can reuse them per organization. Both ways seem to work, but I am hoping to understand how to define them properly.
Getting the XML into above objects:
public DefaultDataObject ExtractXmlData(XContainer root)
{
var myObject = (from t in root.
Elements("ElementA").Elements("ElementB")
select new DefaultDataObject()
{
DataObjectName = (String)t.Element("ChildElement1"),
DataObjectDate =
Program.TryParseDateTime((String)
t.Elements("ChildElement2")
.ElementAtOrDefault(0)
),
etc....
OR
public OranizationDataObject ExtractXmlData(XContainer root)
{
var myObject = (from t in root.
Elements("ElementA").Elements("ElementB")
select new OranizationDataObject()
{
DataObjectName = (String)t.Element("ChildElement1"),
DataObjectDate = Program.TryParseDateTime(
(String)t.Elements("ChildElement2")
.ElementAtOrDefault(0)),
DataObjectCode = (String)t.Element("ChildElement3"),
etc....
Again, thanks for reading. Don't forget to tip your wait staff....
Joe
First of all, your base class doesn't need to be abstract if it's a plain DTO class. If you don't have any functionality that needs to be implemented differently by derived classes, you can simply make it a plain base class which will hold common properties.
Next, there is no point in declaring properties in the base class (abstract in your case), if you are going to hide them (using the new keyword). You first code snippet of DefaultDataObject unnecessarily creates a bunch of new properties with the same name. Remove them completely - they are already defined in the base class.
[Edit] I didn't notice this initially, and #svick warned me, that your base class actually contained fields instead of properties, which makes me wonder why you needed to add the new keyword at all. I went over your code quickly and saw them as properties. In any case, you should never expose public fields - at least change them to auto-implemented properties by adding the { get; set; } block.
In other words, this would simply work:
// this doesn't need to be abstract.
// just put all the common stuff inside.
public class BaseDO
{
// as svick pointed out, these should also be properties.
// you should *never* expose public fields in your classes.
public string Name { get; set; }
public DateTime? Date { get; set; }
}
// don't use the new keyword to hide stuff.
// in most cases, you won't need that's behavior
public class DerivedDO : BaseDO
{
// no need to repeat those properties from above,
// only add **different ones**
public string Code { get; set; }
}
As a side note, but nevertheless important IMHO, you should simplify naming (and make it more clearer what your code does). There is no need to repeat "DataObject" in every property name, for example. But since your code is probably only a simplified version, it doesn't matter.
Lastly, have you heard of XmlSerializer? You don't need to traverse the XML elements manually. It is enough to call XmlSerializer to both serialize and deserialize your data.
Everything I need to know I learned from Sesame Street
Scrub your class design hard to make sure you've identified everything that is the same and different. Play computer, so to speak, with your classes and see how they do the same, different, or the same thing but in different ways.
What is the same, different, same but differently will likely change as you play computer.
Think in general terms of the two pillars of OO Classes. Polymorphism and Inheritance
As you do the above that is. Not so much in terms of C# implementation per se.
How things clump into same vs. different will help drive implementation
And it's all relative.
More of same default behavior? Perhaps a concrete base class instead of abstract.
More of same thing, but differently? Perhaps an abstract class instead of concrete base class.
A default way of doing x? Perhaps a virtual method.
Everyone does the same thing, but no two the same way? A delegate perhaps.
Implementation Suggestions
Make methods and fields protected as a default. Private does not get inherited. Designs change, stay flexible. If something just has to be private, fine.
virtual means you can change implementation in a sub class. It does not mean you must.
Folks seem to under-utilize delegates. They're super for polymorphic methods.
There is nothing wrong with public fields. What's the practical difference between a public field and a public auto-implemented property? Nothing. They both directly return (or set) the underlying value. So what's the point of even bothering with properties? If you want to publicly expose an underlying value differently than it's "natural" state. For example, returning a number in a specific format. And of course you can have different properties for the same field.
A Property can have a get without a set. Or vice versa. Also get and set can have different access levels. Often you'll see this as a public get and a protected (or private) set.
It depends on what the derived types will want to do. If they are going to use the default implementation and only expand on it somehow, then having the default class as the non-abstract base class is fine.
On the other hand, if they are most likely going to re-implement the functionality, you should have an abstract base class (or an interface) and a separate default class.
If you for some reason don't know which one is it, you can let the inheritors choose by having an abstract base class and leaving the default class unsealed.
Also, looking at your code, it seems you misunderstand what the various keywords do. Most of the time, you do not want to use new like this. What it does is to define another member with the same name, unrelated to the original one. Also, there's no reason to override something if you don't want to change it. So, if you expect that the derived classes won't have to reimplement the properties, you don't have to make them virtual at all.
An abstract class can already implement things that can be inherited
public abstract class DataObjectBase
{
public string DataObjectName { get; set; }
public DateTime? DataObjectDate { get; set; }
}
A concrete class can add new properties and methods
public class DerivedDataObject : DataObjectBase
{
public int NewProperty { get; set; }
}
The properties DataObjectName and DataObjectDate are already available in the new class, because they are automatically inherited from the base class.
If the abstract class defined an abstract member, however, you would have to implement it in the derived class.
Say the base class defines
public abstract void SomeMethod(string name);
The the derived class has to do this
public override void SomeMethod(string name)
{
...
}
If your base class does not have abstract members, it does not need to be abstract and can play the role of your default data object directly.
The keyword 'partial` is not needed here. It is only useful if you want to split one class into several pieces over several files.
The keyword new is wrong here. It is used to shadow an inherited member. This means that the inherited member will be hidden "behind" the new declaration. What you need, is to override. This does not hide a member, but provide an alternative implementation of the same member in the derived class.
I'm looking to learn how to use interfaces and base classes effectively. I'm not exactly sure where to put common properties? Do only behaviors belong in an interface? If properties such as: Color and MinSpeed shouldn't go in the interface, where should they live? In an abstract class?
public interface IVehicle
{
void Speed();
void Clean();
void Stop();
}
public class Bmw : IVehicle
{
// Because these pertain to every vehicle no matter of maker,
// should these propertes go in the interface? Or in an abstract class?
public string Color { get; set; }
public int MinSpeed { get; set; }
#region IVehicle Members
public void Speed()
{
}
public void Clean()
{
}
public void Stop()
{
}
#endregion
}
Interfaces can be thought of as a contract that must be satisfied by any implementing class. Use it if you want to guarentee that all classes do the same thing—satisfy the same API—but you don't care how they do it. If properties are a part of that API, then by all means include them in your interface.
From your example above, if you want all cars to be guaranteed to have a color and minSpeed, then those properties belong in the interface. If those properties are specific to BMWs alone, then they belong in the BMW class. If those properties belong to some classes but not others, you could create a new interface extending the original one:
public interface IVehicleWithColorAndMinSpeed : IVehicle
{
string Color { get; set; }
int MinSpeed { get; set; }
}
(just don't get carried away with this)
Abstract classes are similar, but allow you to provide a default implementation for your sub classes.
Abstract classes tend to be easier to version, since you can add something new to your API, and provide a default implementation that your existing subclasses will automatically pick up; adding something to an interface immediately breaks all existing classes which implement that interface.
The 'right' answer is entirely dependent on your domain model. What is the problem you're trying to solve? There is no 'right' answer other than the one which solves the particular problem at hand with the greatest:
understandability
maintainability
brevity
isolation
performance
You can probably consider most of those properties to be in order of importance, but they mean different things to different people and there's probably a lot of debate implied there too.
Can you tell us any more about the particular application you imagine these classes to serve?