2013-05-30 11 views
43

Widziałem wielokrotnie instancję Interface generowaną z klasy. Dlaczego korzysta się z interfejsu w tym mądrym? Instancie interfejsu utworzonego tylko z pomocą pochodnej klasy i możemy uzyskać dostęp tylko do tych członków interfejsu za pośrednictwem tej instancji. ma to dawać przewagę? Jestem tak zdezorientowany ..Dlaczego tworzymy instancję obiektu z interfejsu zamiast z klasy?

interface IPrint 
{ 
    void Print(); 
} 

class Sample : IPrint 
{ 
    public void Print() 
    { 
     Console.WriteLine("Print..."); 
    } 

    public void Sample() 
    { 
     Console.WriteLine("Sample..."); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     IPrint print = new Sample(); 
     print.Print(); 
    } 
} 
+0

Zaznacz to: http://dotnet.dzone.com/articles/c-interfaces-what-are-they-and –

+0

To błędne nazwać instancja interfejsu. Jest to instancja klasy, ale przypisana do odwołania do typu interfejsu. –

Odpowiedz

75

Interfejsy definiują, że klasa MUSI być w stanie coś zrobić. Oznacza to, że wiesz, że obiekt, nad którym pracujesz, zrobi to, co chcesz. Pozwala na większą swobodę i zalety OOP. To jest głęboki temat, ale bardzo prosty przykład:

public interface IAnimal 
{ 
    string Speak(); 
} 

public class Dog : IAnimal 
{ 
    public string Speak() 
    { 
     return "Woof, woof"; 
    } 
} 

public class Cat : IAnimal 
{ 
    public string Speak() 
    { 
     return "Meow"; 
    } 
} 

public class Parrot : IAnimal 
{ 
    public string Speak() 
    { 
     return "Sqwark!"; 
    } 
} 

Następnie można użyć dowolnego zwierzęcia, które lubisz!

class Program 
{ 
    static void Main(string[] args) 
    { 
     // Writes Woof, Woof 
     IAnimal animal = new Dog(); 
     Console.WriteLine(animal.Speak());   

     // Now writes Meow 
     animal = new Cat(); 
     Console.WriteLine(animal.Speak()); 

     // Now writes Sqwark etc 
     animal = new Parrot(); 
     Console.WriteLine(animal.Speak()); 
    } 
} 

ta pozwala również wtedy dostać się do rzeczy jak odwrócenie sterowania gdzie zabrałbyś element tak i można przechodzić do psa, kota lub papugi i metoda zawsze pracują, nie wiedząc, lub opiekuńczego, które zwierzę było:

public void ShoutLoud(IAnimal animal) 
{ 
    MessageBox.Show("Shout " + animal.Speak()); 
} 

to wtedy sprawia ShoutLoud jednostka sprawdzalne ponieważ można użyć atrapa obiektu zamiast prawdziwego zwierzęcia. Zasadniczo sprawia, że ​​twój kod jest elastyczny i dynamiczny, a nie sztywny i ściśle powiązany.

Ponadto, rozszerzenie na pytanie Matthew. W języku C# można dziedziczyć tylko z jednej klasy bazowej, ale można mieć wiele interfejsów. Tak, można mieć:

public class Dog : IAnimal, IMammal, ICarnivor 

To pozwala mieć interfejsy małe (zalecane), które następnie pozwalają budować tak daje maksymalną kontrolę nad tym, co przedmiot może/musi zrobić.

+2

Zadaję to samo pytanie, które zadaję KillerCam: z tego przykładu, jaką korzyść uzyskuje się z używania interfejsu zamiast klasy bazowej za pomocą metod wirtualnych? Na przykład, jeśli zmienisz IAnimal na 'public abstract class Animal {public abstract string Speak(); } ' –

+2

@MatthewWatson - Dobre pytanie i zaktualizowałem swoją odpowiedź (patrz na dole) tylko z jednego powodu, dla którego interfejs jest korzystny. – Belogix

+1

Świetna odpowiedź od @Belogix w szczególności ten komentarz: "Inversion Of Control, gdzie można wziąć przedmiot w ten sposób i można przekazać psa, kota lub papugi i metoda zawsze działa". Więc możesz mieć metodę o nazwie FeedAnimals, która karmi wszystkie zwierzęta należące do interfejsu typu IAnimal –

7

Korzystanie interfejs ten sposób daje możliwość tworzenia metod, które używają standardowego szablonu interfejsu. Więc może masz wiele klas drukarce, że wszystkie dziedziczą z IPrinter

class SamsungPrinter : IPrinter 
{ 
    // Stuff and interface members. 
} 

class SonyPrinter : IPrinter 
{ 
    // Stuff and interface members. 
} 

interface IPrinter 
{ 
    void Print(); 
} 

więc dla każdego rodzaju SamsungPrinter, SonyPrinter, itd. Można wstępnie procesowej przy użyciu coś jak

public static void PreProcessAndPrint(IPrinter printer) 
{ 
    // Do pre-processing or something. 
    printer.Print(); 
} 

Wiesz dziedziczeniu od IPrinter i używając tego typu w parametrach metody, zawsze możesz bezpiecznie używać metody Print na jakimkolwiek obiekcie.

Oczywiście istnieje wiele innych sposobów korzystania z interfejsów. Jednym z przykładów ich wykorzystania są wzorce projektowe, w szczególności wzorce Fabryki i Strategii. Opis którego i przykłady można znaleźć here.

Mam nadzieję, że to pomoże.

+0

Ale jak to się różni, na przykład przy użyciu klasy bazowej z metodami wirtualnymi? –

1

Ale jak to się różni, na przykład przy użyciu klasy bazowej z metodami wirtualnymi?

Wszyscy zakładamy, że jeden programista lub jeden program pisze interfejs i klasy, ale nie zawsze musi tak być.

Może masz kompletny gotowy program, który pracuje ze zwierzętami i masz to działało przy użyciu:

public abstract class Animal { public abstract string Speak(); } 

A potem pewnego dnia pobrać niektóre niesamowite DLL z Nuget który pokazuje zdjęcia zwierząt. Biblioteka klasa zawiera umowę - interfejs - 'IAnimal':

namespace AwesomeAnimalLibrary 
{ 
public interface IAnimal 
{ 
string AnimalName; 
} 
} 

Biblioteka może również klasa zawiera:

namespace AwesomeAnimalLibrary 
{ 
public class AnimalPhotos 
{ 
[Byte] GetPhotos(IAnimal animal); 
} 
} 

Co można zrobić teraz? Twoja podstawowa klasa Animal może zaimplementować interfejs IAnimal interfejsu AwesomeAnimalLibrary i to wszystko.

Nie zakładaj, że inne osoby będą używać abstrakcyjnych klas bazowych, ale pracują razem, korzystając z umów z interfejsem.

0

Interfejs nie może mieć instancji, ponieważ interfejs implementuje tylko podpisy właściwości lub metod. Interfejs jest tylko wskaźnik do instancji pewnej klasy:

interface IExample 
{ 
    // method signature 
    void MyMethod(); 
} 
public class MyClass : IExample 
{ 
    // method implementation 
    public void MyMethod() 
    { 
     ConsoleWriteline("This is my method"); 
    } 
} 

// interface pointing to instance of class 
IExample ie = new MyClass(); 
ie.MyMethod(); 
Powiązane problemy