2010-09-12 6 views
2

У меня есть вопрос относительно интерфейса. Есть два интерфейса, которые содержат один и тот же метод Test(). Теперь я наследую оба интерфейса в классе Sample.I хочу знать, какой метод интерфейса будет вызываться? Мой пример кода ниже:Какой интерфейс будет реализован?

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(); 
    } 
} 

Благодаря Vijendra Singh

+0

Посмотрите здесь: http://stackoverflow.com/questions/143405/c-interfaces-implicit-and-explicit-implementation –

+0

Вы всегда будете называть Sample.Test(). При использовании интерфейса или более, это означает, что вы вызываете метод в конкретном классе, как описано в контракте, который предоставляет интерфейс. Таким образом, не имеет значения, обеспечивают ли оба интерфейса один и тот же контракт. –

ответ

12

Результат будет таким же для обоих. Если вы хотите другое поведение на интерфейс, вы должны явно их реализации:

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(); 
    } 
} 

Если вы хотите по умолчанию поведения, создать метод с той же подписью (таким образом неявные реализациями интерфейса) и добавить код для этого случая. Как правило, вам просто нужна явная реализация.

+0

Спасибо. Теперь, когда есть * три * версии 'Test', на самом деле имеет значение, ссылаетесь ли вы на ссылку« Образец », ссылку« IA »или ссылку« IB ». Ключевым моментом здесь является понимание того, что вы вызываете * через * ссылку. –

+0

В качестве предложения: здесь может быть яснее, если метод без интерфейса не вызывал ничего другого. Таким образом, все три вызова различны. –

+0

Чтобы доказать точку, вы должны изменить последний вызов как «Привет из образца», а затем сделать «Main()», который показывает, что результат изменится в зависимости от типа литья/компиляции. –

2

Вы непосредственно вызова метода Sample.Test(), так как переменная "т" объявлен как "образец Т"

9

Оба.

Если у вас есть код

IA a = new Sample(); 

или

IB b = new Sample(); 

выход то же самое.

EDIT

Какой интерфейс называется?

Выполнены какОтсутствует.

Интерфейсы существуют для того, чтобы программист выбрал какой метод (какой интерфейс) для класса.

Вам необходимо использовать конкретную реализацию интерфейса. Методы, составляющие конкретный класс, - это методы, которые называются.

+0

@Famp: Я хочу знать, какой интерфейс вызывается в моей ситуации. – Vijjendra

+4

Интерфейс не может быть вызван, он не содержит реализацию. – wRAR

+1

Я бы сказал «не», а не «оба». Прецедент остается в праве IIRC, поэтому, если вы настаиваете, что это будет IA. – Mchl

3

Вы считаете, что интерфейс неправильный. Интерфейс не является реализацией, это абстракция.

Сообщая компилятору, что образец является как IA, так и IB, вы просто сказали, что он может быть применен к любому из этих типов и имеет все функции, необходимые для выполнения того, что вызывающий код ожидает от него. ,

ie. в следующем коде

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

Он не называет три отдельные методы, называемые испытания, он звонит метод испытаний от образца каждый раз. Это не соответствует

object obj = sample; 
obj.Test(); 

, который не смог бы скомпилировать, даже если obj имеет метод. Испытание по характеру типа образца.

Это особенно эффективно, когда вы смотрите на передачу объекта в качестве аргумента другому методу.

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

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

В этом случае компилятор знает только, что что-либо с договором IA имеет метод тестирования. Ему все равно, какой тип это, это бизнес вызывающего кода.

+0

Вы правы, чтобы различать интерфейсы и реализации. Однако при явной реализации становится возможным, чтобы 'IA.Test' делал что-то совершенно отличное от' IB.Test' или даже 'Sample.Test'. –

+0

@Steven - это правда, но это тоже осложнение, которое я считал ненужным. Сначала ознакомьтесь с концепцией интерфейсов для 99% случаев, а затем подумайте о 1% случаев, когда вам понадобится сделать что-то умное. – pdr

+0

Я нахожу, что я довольно часто реализую 'IDisposable.Dispose' явно, так что это просто теоретический вариант. –

Смежные вопросы