Problems with interfaces

I'm having a lot of trouble with interfaces and abstract classes. No matter how I seem to approach the particular problem I need to solve, I end up with heaps of replicated code and extra classes or interfaces.

What I have is an abstract class called Subsystem, which contains information allowing my application to store and retrieve configuration data in a generalised way, and methods for the implementing class to call to get and set configuration settings at runtime. Please don't reply suggesting I use the built in configuration functionality in Visual Studio, that is not what this is about.

One of the subsystems of my application is the main window, which of course extends System.Windows.Forms.Form, and of course this is where everything goes wrong. I can't inherit from both Form and Subsystem, so I have to have a wrapper that inherits from Subsystem but contains a Form. To further complicate things there has to exist a base class for my GUI so that things other than Windows Forms windows can be plugged in later, but that doesn't really change the basic situation, it just means now I'm calling through three classes in order to do a simple job.

Why oh why couldn't they give us multiple inheritance "Interfaces" they chant mystically. OK, interfaces...

1) Can't contain fields

2) Can't contain code

3) Can't inherit from an abstract class (obviously because of 1 and 2)

... so I can't make Subsystem an interface, nor obviously Form. I can't make an interface that combines the signatures of both or even one that contains information that could be used to make some workaround. I must have missed something obvious about interfaces - I'll admit I never use them when I can use a base class.

So surely there's some way to avoid having classes full of:

/// <summary>

/// Invokes the close event on the window.

/// </summary>

public override void invokeClose() { gui.invokeClose(); }

Can anyone help me




Answer this question

Problems with interfaces

  • cliffie

    Well, this does not eleminate the wrapper, but interfaces could help you in so far that you can more easily implement the wrappers and access the components, e.g.

    class Subsystem : ISubsystem { ... }
    class GuiComponent : IGuiComponent { ... }
    actually I do not see the need for the base GUI class, as if you have a IGuiComponent interface and you require all your GuiComponents to implement it, you can keep the references to the objects by that interface.

    The combined class
    class MainWindowSubsytem : IGuiComponent, ISubsystem ...
    wraps all of it together...

    But if your application becomes more complex like this, then the provider architecture might also be more suitable for you, e.g.
    class SubsystemConfiguration : Subsystem, ISubsystemConfigurationProvider ...
    class MainWindow : System.Windows.Forms.Form, IGuiComponent ...
    class PluginManager : IPluginManager ...

    and a main class that helps you structure the stuff

    class MainComponent : IServiceContainer
    {
    ... implement IServiceContainer and register the class instances above as services
    }

    Now each class instance needs a reference to the IServiceContainer/IServiceProvider and can request any needed service. You spare yourself the wrappers and let everybody request and communicate with each other through the interfaces of the service, e.g.

    ISubsystemConfigurationProvider configurationProvider = serviceProvider.GetService(typeof(ISubsystemConfigurationProvider)) as ISubsystemConfigurationProvider;
    configurationProvider.Load("myconfiguration");

    I do not know in how for an archtecture like that suits your needs, but it is pretty flexible...


  • JasonFx

    Hi and thanks for replying.

    Well, this does not eleminate the wrapper, but interfaces could help you in so far that you can more easily implement the wrappers and access the components, e.g.

    class Subsystem : ISubsystem { ... }
    class GuiComponent : IGuiComponent { ... }
    actually I do not see the need for the base GUI class, as if you have a IGuiComponent interface and you require all your GuiComponents to implement it, you can keep the references to the objects by that interface.

    The base class of the GUI is System.Windows.Form, and there isn't much I can do about that. :-)

    The combined class
    class MainWindowSubsytem : IGuiComponent, ISubsystem ...
    wraps all of it together...

    Yeah, the problem is that there is functionality on the Subsystem class that needs to be provided to all implementers. With an interface, I can't even provide a field that all implementers can access. What you seem to be getting at though is that I can move all the functionality off the subsystem interface into some globally accessible class, right  Is there some accepted standard way of doing this What about the loss of context Suddenly I'm seeing pages of static methods into which my objects need to be passed...

    But if your application becomes more complex like this, then the provider architecture might also be more suitable for you, e.g.
    class SubsystemConfiguration : Subsystem, ISubsystemConfigurationProvider ...
    class MainWindow : System.Windows.Forms.Form, IGuiComponent ...
    class PluginManager : IPluginManager ...

    and a main class that helps you structure the stuff

    class MainComponent : IServiceContainer
    {
       ... implement IServiceContainer and register the class instances above as services
    }

    Now each class instance needs a reference to the IServiceContainer/IServiceProvider and can request any needed service. You spare yourself the wrappers and let everybody request and communicate with each other through the interfaces of the service, e.g.

    ISubsystemConfigurationProvider configurationProvider = serviceProvider.GetService(typeof(ISubsystemConfigurationProvider)) as ISubsystemConfigurationProvider;
    configurationProvider.Load("myconfiguration");

    I do not know in how for an archtecture like that suits your needs, but it is pretty flexible...

    That's interesting, but not really doable for me right now. I've never seen a program architectured quite like that, except maybe some realtime embedded systems I dealt with at uni.

    So one more question: What happens when two interfaces define the same signature Is the method implemented once or twice Can you access both with casting It's problems like this that make we wonder how multiple inheritance would have been any harder to do than multiple interfaces.

    Thanks again for your help.



  • yjacket2006

    Thanks, you've been very helpful.

  • scruber

    See this page for information about disambiguating inherited interface methods with the same names.

    It's pretty simple though. Suppose you are implementing two interfaces (call them Inf1 and Inf2), each of which defines a method called "Paint()".

    In your implementation, you can implement Paint() for both interfaces simultaneously by defining a single method called Paint().

    Or to implement them separately, prefix the Paint() method with the name of the interface for which you are implementing it, i.e. Inf1.Paint() and Inf2.Paint().



  • Problems with interfaces