views:

166

answers:

4

Hi I have a question regarding Interface. There are 2 interface both contain the same Method Test(). Now I'm inheriting both the interface in Sample class.I want to konw wjhic Interface's method will be called? My code sample is below:

interface IA 
{
    void Test();
}
interface IB
{
    void Test();
}
class Sample: IA, IB
{
    public void Test()
    {
      Console.WriteLine("Which interface will be implemented IA or IB???!");
    }
}
class Program
{
    public static void Main(string[] args)
    {
        Sample t = new Sample();
        t.Test();//Which Interface's Method will called.
        Console.ReadLine();
    }
}

Thanks Vijendra Singh

+2  A: 

You're directly calling Sample.Test() method, since the "t" variable is declared as "Sample t"

Notoriousxl
+9  A: 

Both.

If you have the code

IA a = new Sample();

or

IB b = new Sample();

the output is the same.

EDIT

What interface is called?

Both are implemented None is called.

Interfaces exist to make the programmer awere of what method (what interface) the class as.

You need to use a concrete implementation of the interface. The methods form the concrete class are the methods that are called.

fampinheiro
@Famp: I want to know which Interface will called in my situation.
Vijjendra
Interface can't be called, it doesn't contain an implementation.
wRAR
I'd say 'neither' rather than 'both'. The precedence is left to right IIRC, so if you insist it will be IA.
Mchl
In this case, `Test` implements the corresponding method in `IA` and `IB`, so "both" is right. (It's also part of `Sample`'s interface, since it wasn't made explicit.)
Steven Sudit
@Mchl: so, if sequence will change then it will call the IB?Thanks
Vijjendra
@Mchl: Precedence has no effect here. `Sample` is *equally* an implementation of `IA` and `IB`.
Steven Sudit
@Vijjendra: You're missing the point here: there's just a single `Test` method, and it's not exclusively part of `IA` *or* `IB`.
Steven Sudit
This was something of a trick question. :-)
Steven Sudit
@Steven:So the Test() method is not the part of any Interface IA or IB?, what about the Interface's Test() method which I have declared in the Interface IA and IB.
Vijjendra
In the code above, the method is equally part of `IA`, `IB` *and* `Sample`. In Femaref's example, there are three distinct methods.
Steven Sudit
Thanks Steven :)
Vijjendra
+11  A: 

The result will be the same for both. If you want different behaviour per interface, you have to explicitly implement them:

interface IA 
{
    void Test();
}
interface IB
{
    void Test();
}
class Sample: IA, IB
{
    void IA.Test()
    {
      Console.WriteLine("Hi from IA");
    }
    void IB.Test()
    {
      Console.WriteLine("Hi from IB");
    }
    public void Test() //default implementation
    {
      Console.WriteLine("Hi from Sample");
    }
}

class Program
{
    public static void Main(string[] args)
    {
        Sample t = new Sample();
        t.Test(); // "Hi from Sample"
        ((IA)t).Test(); // "Hi from IA"
        ((IB)t).Test(); // "Hi from IB"
        Console.ReadLine();
    }
}

If you want default behaviour, create a method with the same signature (thus an implicit interface implementation) and add code for that case. Usually, you just want the explicit implementation though.

Femaref
Thank you. Now that there are *three* versions of `Test`, it actually matters whether you call through a `Sample` reference, `IA` reference or `IB` reference. The key here is the understanding that you are calling *through* a reference.
Steven Sudit
As a suggestion: It might be clearer here if the non-interface method didn't call anything else. This way, all three calls are distinct.
Steven Sudit
To prove a point you should change the last call to be "Hi from Sample" and then make a `Main()` that shows shows the result will change depending on cast/compilter type.
Matthew Whited
there you go, that should do it.
Femaref
Ok, now it's a very clear example. If I could upvote it a second time, I would, but SO doesn't operate Chicago-style.
Steven Sudit
We should probably mention that it's possible to explicitly implement `Test` for `IA` and `IB` but not make it callable through `Sample`.
Steven Sudit
+2  A: 

You're thinking of an interface the wrong way. An interface isn't an implementation, it's an abstraction.

In telling the compiler that Sample is both IA and IB, you have simply said that it can be cast to either of these types and has all of the functionality required to do whatever the calling code expects it to be able to do.

ie. in the following code

Sample sample = new Sample();
sample.Test();
IA a = sample;
a.Test();
IB b = sample;
b.Test();

It is not calling three separate methods called Test, it is calling the Test method from Sample each time. This is as opposed to

object obj = sample;
obj.Test();

which would fail to compile even though obj has a method Test by nature of being type Sample.

This is particularly powerful when you're looking at passing an object as an argument to another method.

public void DoTest(IA a)
{
    a.Test();
}

Sample sample = new Sample();
DoTest(sample);

In this case, the compiler only knows that anything with a contract of IA has a Test method. It doesn't care what Type it is, that's the business of the calling code.

pdr
You're right to distinguish between interfaces and implementations. However, with explicit implementation, it becomes possible for `IA.Test` to do something entirely different from `IB.Test`, or even `Sample.Test`.
Steven Sudit
@Steven - that is true, but it's also a complication I felt unnecessary. Understand the concept of interfaces for 99% of cases first, then worry about the 1% of occasions when you're going to need to do something clever.
pdr
I find that I quite often implement `IDisposable.Dispose` explicitly, so it's just a theoretical option.
Steven Sudit