Search code examples
c#oopdiamond-problem

How do interfaces solve the diamond problem?


I need to discuss one thing with you. I have been reading about the interface that it is a contract between the class the interface that the class will provide implementation of all the methods of the interface. To solve the famous diamond problem, we have interfaces. Like (I am using C#)

public interface IAInterface
{
     void aMethod();
}

public interface IBInterface
{
     void aMethod();
}

Now

public class aClass : IAInterface, IBInterface
{
     public void aMethod()
     {

     }
}    

By above code, it is said that aClass has provided the implementation of both the methods of the interfaces. My confusion is: If it is a contract between the class and the interface then how can we say that contract with both the interfaces is fulfilled?

A real world example, Like I have contract with Jack that I will give him 5 dollars at the same time I also have contract with Ben that I will give him 5 dollars, now by providing 5 dollars to one of them (either Jack or Ben) how can I say I have fulfilled the contract with both of them?

My question may seem childish but that is confusing me a lot.


Solution

  • Interfaces guarantee that a given set of methods will be implemented. The interface does not concern itself on how will the code be implemented. As opposed to extending classes, when you extend a class you are using some predefined code.

    If you extend two classes with the same method, say, methodA, and call this method, then, the compiler will not know which one will it need to run. On the other hand, when you implement two interfaces with the same method, since the implementation is written within your own code, the compiler will know where it needs to go to find the implementation.

    So basically, when you implement something you are guaranteeing you will be offering some service.

    EDIT: I'll try and take your example and turn it in some Object Oriented way, this will hopefully, make things clearer.

    Jack and Ben will guarantee that they will lend you the money, you, on the other hand, guarantee that will pay it back, so, from an OO point of view you can see it like this:

    public interface IPay
    {
        public void Pay(Individual i);
    }
    
    public class MySelf : IPay
    {
        public void Pay(Individual i)
        {
            ...
        }
    }
    
    public interface ILend
    {
        public void Lend(Individual i);
    }
    
    public class Jack : ILend //Same applies for Ben
    {
        public void Lend(Individual i)
        {
            ...
        }
    }
    

    This is how I would go about the problem you have specified.

    As for the other trash example, this is how you can go about it:

    public interface ITakeTrash
    {
        public void TakeTrash(Trash t);
    }
    
    public Son : ITakeTrash
    {
        public void TakeTrash(Trash t);
    }
    
    public class Mum  //Same applies for dad
    {
        Son mySon = ...
    
        mySon.TakeTrash(t);
    }
    

    Both your mother and father do not know what to do with the trash, but, they know that you know how to deal with it, and that is what they care about (just like above, you only care that Ben and Jack can give you money and the other parties just care that you can pay it back, none of the involved really care how you do it.

    I do understand where you are trying to go, basically saying what if I implement two different interfaces with methods having the same name that do different things. If you ever end up in such a scenario, I think that that would be due to bad design. I would not recommend building a single class which does a myriad of different things, this being one of the reasons.

    On the other hand, you might ask, what if I have 2 interfaces that do similar things with methods having the same name? Then, I think that the answer would be that since the interfaces do similar things and you have methods with the same name then, it is most likely that you are doing the same thing, hence, you need not confuse yourself.

    I hope this edit helped shed some light on the issue.