6

Consider following interfaces:

public interface IComponent    {    }

public interface ISwitch : IComponent
{
    bool IsOn    { get; }
    event EventHandler SwitchedOff;
    event EventHandler SwitchedOn;
}

public interface ISwitchable : ISwitch, IComponent
{
    void SwitchOff();
    void SwitchOn();
}

public interface IPowerSwitch : ISwitchable, ISwitch, IComponent   {    }

public interface IHeatingElement : ISwitchable, ISwitch, IComponent   {    }

I have implemented IPowerSwitch in a class like this:

public class Kettle : IPowerSwitch
{
    event EventHandler PowerOnEvent;
    event EventHandler PowerOffEvent;

    object objectLock = new Object();

    public bool IsPowerOn;

    public Kettle()
    {
            IPowerSwitch p = (IPowerSwitch)this;
            p.SwitchedOn += new EventHandler(On_PowerOn_Press);
            p.SwitchedOff += new EventHandler(On_PowerOff_Press);
    }


    void ISwitchable.SwitchOff()
    {
        EventHandler handler = PowerOffEvent;
        if (handler != null)
        {
           handler(this, new EventArgs());
        }          
    }

    void ISwitchable.SwitchOn()
    {
        EventHandler handler = PowerOnEvent;
        if (handler != null)
        {
            handler(this, new EventArgs());
        }
    }

    bool ISwitch.IsOn
    {
        get { return IsPowerOn ; }
    }

    event EventHandler ISwitch.SwitchedOff
    {
        add
        {
            lock (objectLock)
            {
                PowerOffEvent += value;
            }
        }
        remove 
        {
            lock (objectLock)
            {
                PowerOffEvent -= value;
            }
        }
    }

    event EventHandler ISwitch.SwitchedOn
    {
        add
        {
            lock (objectLock)
            {
                PowerOnEvent += value;                    
            }
        }
        remove
        {
            lock (objectLock)
            {
                PowerOnEvent -= value;                   
            }
        }
    }

    protected void On_PowerOn_Press(object sender, EventArgs e)
    {
        if (!((IPowerSwitch)sender).IsOn)
        {
            Console.WriteLine("Power Is ON");
            ((Kettle)sender).IsPowerOn = true;
            ((IPowerLamp)this).SwitchOn();
        }
        else
        {
            Console.WriteLine("Already ON");

        }

    }

    protected void On_PowerOff_Press(object sender, EventArgs e)
    {
        if (((IPowerSwitch)sender).IsOn)
        {
            Console.WriteLine("Power Is OFF");
            ((Kettle)sender).IsPowerOn = false;
            ((IPowerLamp)this).SwitchOff();
        }
        else
        {
            Console.WriteLine("Already OFF");
        }

    }

}

Now I want to implement IHeatingElement interface in this class. IHeatingElement has the same methods as IPowerSwitch. So how I can implement the SwitchOn and SwitchOff of IHeatingElement. If I try to implement something like IPowerSwitch.SwitchOff(), I get error

'IPowerSwitch.SwitchOff' in explicit interface declaration is not a member of interface.

What I want to do is that, when Power switch on event is raised Heating On event should be raised after that. And when heating is switched off, Power switch Off event should be raised.

This is my first question here, so please guide me if something is wrong in the question. Thanks for your help in advance.

2
  • 4
    Not everything needs to be implemented with inheritance. Commented Feb 21, 2014 at 14:50
  • You don't need to re-declare the interfaces ISwitchable inherits ISwitch/IComponent so your IPowerSwitch/IHeatingElement can just inherit ISwitchable Commented Feb 21, 2014 at 14:53

4 Answers 4

8

As @Peter-ritchie said in comments, "not everything needs to be implemented with inheritance". In your current code, you're trying to say that a Kettle is a type of both a power switch and a heating element. What I think you want to say is that a Kettle has both a power switch and a heating element. This is called composition.

Instead, you'd structure the Kettle object something like this:

public class Kettle : ISwitchable
{
     private IPowerSwitch Power;
     private IHeatingElement Heat;

     public Kettle()
     {
        Power = new PowerSwitch();
        Heat = new HeatingElement();
     }

     public void SwitchOn()
     {
         Power.SwitchOn();
         Heat.SwitchOn();
     }

     // And so on.
}
public class PowerSwitch : IPowerSwitch {}
public class HeatingElement : IHeatingElement {}
Sign up to request clarification or add additional context in comments.

2 Comments

+1 This should be the accepted answer. Questioner is conflating the issue because he's treating interfaces like he would abstract classes.
Agreed, this is a problem in design.
1

A class cannot implement an interface more than once. This includes any inherited interfaces as well I'm afraid.

You will have to move your methods to the desired interface implementation for this to work the way you want.

1 Comment

Crono, Thanks for you quick response. I can not change any thing in the interfaces. I must implement them as they are.
1

IPowerSwitch.SwitchOff does not compile because SwitchOff is a member of ISwitchable and you're using explicit interface implementation.

Either get rid of the explicit interface implementation (and just implement SwitchOff in your class instead of IPowerSwitch.SwitchOff) or implement ISwitchable.SwitchOff

Comments

1

What you want is essentially multiple inheritance. It is not supported by .NET.

But you can replace inheritance with aggregation.

class KettlePowerSwitch : IPowerSwitch { }

class KettleHeatingElement : IHeatingElement { }

class Kettle {
    public IPowerSwitch PowerSwitch = new KettlePowerSwitch();
    public IHeatingElement HeatingElement = new KettleHeatingElement();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.