I am having trouble with the concept of interfaces interacting with polymorphic types (or even polymorphic interfaces). I\'m developing in C# and would appreciate answers st
The problem is really that you have defined a vague interface, a contract is a more proper term. It's like you go into McDonalds and just order a burger:
interface Resturant
{
Burger BuyBurger();
}
The person taking your order will look a bit confused for a while, but eventually he/she will serve you any burger since you don't specify what you want.
Same thing here. Do you really just want to define that something is paintable? If you ask me, it's like asking for trouble. Always try to make interfaces as specific as possible. It's always better to have several small specific interfaces than a large general one.
But let's go back to your example. In your case, all classes only have to be able to paint something. Therefore I would add another more specific interface:
interface IPainter
{
void Paint(IPaintable paintable);
}
interface IDecalPainter : IPainter
{
void Paint(IDecalPaintable paintable);
}
interface IPaintable
{
void ApplyBaseLayer(Color c);
}
interface IDecalPaintable : IPaintable
{
void ApplyDecal(HatchBrush b);
}
class AwesomeDecalPainter : IDecalPainter
{
public void Paint(IPaintable paintable)
{
IDecalPaintable decalPaintable = paintable as IDecalPaintable;
if (decalPaintable != null)
Paint(decalPaintable);
else
paintable.ApplyBaseLayer(Color.Red);
}
public void Paint(IDecalPaintable paintable)
{
paintable.ApplyBaseLayer(Color.Red);
paintable.ApplyDecal(new HatchBrush(HatchStyle.Plaid, Color.Green));
}
}
I would recommend that you read about the SOLID principles.
A more sound interface implementation
interface IPaintingContext
{
//Should not be object. But my System.Drawing knowledge is limited
object DrawingSurface { get; set; }
}
interface IPaintable
{
void Draw(IPaintingContext context);
}
class AwesomeDecal : IPaintable
{
public void Draw(IPaintingContext paintable)
{
// draw decal
}
}
class ComplexPaintableObject : IPaintable
{
public ComplexPaintableObject(IEnumerable paintable)
{
// add background, border
}
}
Here you can create as complex painting items as possible. They are now aware what they paint on, or what other paintables are used on the same surface.