Pytanie Dlaczego powinienem wybrać interfejsy w C #, kiedy mogę implementować metody bezpośrednio


Mam świadomość, że to bardzo podstawowe pytanie, ale ankieter zapytał mnie w bardzo podstępny sposób i byłem bezradny :(

Znam tylko materialną lub teoretyczną definicję interfejsu, a także wdrożyłem go w wielu projektach, nad którymi pracowałem. Ale naprawdę nie rozumiem, dlaczego i jak to jest przydatne.

Ja też nie rozumiem jednej rzeczy w interfejsie. np. używamy

conn.Dispose(); w końcu bloku. Ale nie widzę, aby ta klasa implementowała lub dziedziczyła IDisposable interfejs (SqlConnection) To znaczy. Zastanawiam się, jak mogę nazwać nazwę metody. Również w tym samym nie rozumiem, jak działa metoda Dispose, ponieważ musimy implementować treść funkcji we własnej implementacji dla wszystkich metod interfejsu. W jaki sposób interfejsy są akceptowane lub określane jako umowy? Te pytania wciąż mi krążą w głowie i szczerze mówiąc, nigdy nie widziałem nic dobrego, co wyjaśniłoby moje pytania w sposób, który rozumiem.

MSDN jak zwykle wygląda bardzo przerażająco i żadna linia nie jest tam jasna (Ludzie, uprzejmie przepraszam, którzy są w rozwoju na wysokim poziomie, uważam, że jakikolwiek kod lub artykuł powinien dotrzeć do umysłu każdego, kto to widzi, stąd, jak wielu innych twierdzi, MSDN nie jest użyteczny).

Ankieter powiedział:

Ma 5 metod i jest szczęśliwy, że może go zaimplementować bezpośrednio w klasie, ale jeśli musisz wybrać klasę lub interfejs abstrakcyjny, który wybierzesz i dlaczego? Odpowiedziałem mu na wszystkie artykuły, które czytałem na różnych blogach, mówiąc o przewadze i wadzie zarówno abstrakcyjnej klasy, jak i interfejsu, ale on nie jest przekonany, że próbuje zrozumieć "Dlaczego interfejs" w ogóle. "Dlaczego klasa abstrakcyjna" w ogóle, nawet jeśli mogę zaimplementować te same metody tylko jeden raz i nie zmieniać go.

Nie widzę gdzie w sieci, mógłbym dostać artykuł, który wyjaśniłby mi wyraźnie o interfejsach i ich funkcjonowaniu. Jestem jednym z wielu programistów, którzy wciąż nie wiedzą o interfejsach (znam teorię i metody, których używałem), ale nie jestem przekonany, że zrozumiałem to jasno.


76
2018-06-06 13:05


pochodzenie


Interfejsy są jednym z tych, które usiłowałem zrozumieć. Dobre pytanie. - Brian
programowanie do abstrakcyjnej umowy, a nie konkretna implementacja ... Krótko mówiąc, oznacza to, że można zastąpić dowolny obiekt implementujący interfejs, gdy wymagany jest interfejs. - Mitch Wheat
SqlConnection dziedziczy System.ComponentModel.Componentktóry implementuje IDisposable. - Lee
@MitchWheat - To nie jest przykład, pytanie zadaje pytanie SqlConnection przybory IDisposable. - Lee
Oh Lee, dzięki temu zrozumiałem, dziękuję. Nadal nie wiem, jak i gdzie zdefiniowana jest funkcja metody "Utylizuj". - Learner


Odpowiedzi:


Interfejsy są doskonałe, gdy chcesz stworzyć coś takiego:

 using System;

namespace MyInterfaceExample
{
    public interface IMyLogInterface
    {
        //I want to have a especific method that I'll use in MyLogClass
        void WriteLog();       
    }

    public class MyClass:IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyClass was Logged");
        }
    }

    public class MyOtherClass :IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyOtherClass was Logged");
            Console.Write("And I Logged it different, than MyClass");
        }
    }

    public class MyLogClass
    {
        //I created a WriteLog method where I can pass as parameter any object that implement IMyLogInterface.
        public static void WriteLog(IMyLogInterface myLogObject)
        {
            myLogObject.WriteLog(); //So I can use WriteLog here.
        }
    }

    public class MyMainClass
    {
        public void DoSomething()
        {
            MyClass aClass = new MyClass();
            MyOtherClass otherClass = new MyOtherClass();

            MyLogClass.WriteLog(aClass);//MyClass can log, and have his own implementation
            MyLogClass.WriteLog(otherClass); //As MyOtherClass also have his own implementation on how to log.
        }
    }
}

W moim przykładzie mogę być programistą, który pisze MyLogClass, a inni programiści mogli tworzyć klasy, a kiedy chcieli się zalogować, implementowali interfejs IMyLogInterface. To tak, jak oni pytali mnie, czego potrzebują do wdrożenia WriteLog() metoda w MyLogClass. Odpowiedź, którą znajdą w interfejsie.


68
2018-06-06 13:30



Hej, który wygląda mi na bardzo dobry składnik do zrozumienia, naprawdę to doceniam, bardzo dziękuję :) :) - Learner
Moje pytanie brzmi, czy tworzysz instancję MyClass i MyOtherClass dlaczego po prostu nie zadzwonisz aClass.WriteLog() dlaczego dodać ten dodatkowy krok. Implementacja WriteLog() pozostałyby inne dla każdej z klas, ale już masz obiekt, więc po co przekazywać go do klasy obsługi? - Zach M.
Hm może to być tak, że jeśli wstawisz swój przykład logowania na samorodku, łatwiej będzie innym użyć twojego loggera, bez znajomości szczegółów ... ale z drugiej strony, wciąż nie jest to jakaś uniwersalna klasa, (ea mógłbym napisać interfejs z rejestrowaniem i poziomami alerty) interfejsy są nadal tylko w twoim zasięgu. więc oprócz siebie, dla tego, kto z niej korzysta? - user3800527
Czy nie jest to przykład dla wzorca strategii? - SHRI
@ZachM. Jeśli mam rację, odpowiedź oznacza, że ​​nie będzie tworzyć instancji klas, ale inni programiści będą tworzyć instancje klas i przekazywać je jako parametr do MyLogClass  WriteLog metoda. Tak więc jego metoda może obsłużyć dowolny obiekt, który implementuje IMyLogInterface . Tutaj to kolejny ciekawy post. - stom


Interfejsy są to kontrakty, których muszą przestrzegać realizatorzy. Klasy abstrakcyjne zezwalaj na kontrakty plus wspólne implementacje - coś, czego interfejsy nie mogą mieć. Klasy mogą implementować i dziedziczyć wiele interfejsów. Klasy mogą rozszerzać tylko jedną klasę abstrakcji.

Dlaczego interfejs

  • Nie masz domyślnej lub udostępnionej implementacji kodu
  • Chcesz udostępniać umowy danych (usługi sieciowe, SOA)
  • Masz różne implementacje dla każdego implementatora interfejsu (IDbCommandma SqlCommand i OracleCommand które implementują interfejs w określony sposób)
  • Chcesz obsługuje dziedziczenie wielokrotne.

Dlaczego Streszczenie

  • Masz domyślną lub wspólną implementację kodu
  • Chcesz zminimalizować duplikację kodu
  • Chcesz łatwa obsługa wersji

37
2018-06-06 13:14



@Silver Czytam większość tego, co napisałeś na blogach, ale próbuję zrozumieć praktycznie. Robiłem usługi WCF, odsłonięte interfejsy (Ale to była tylko pojedyncza autonomiczna aplikacja bez wcześniejszego lub niższego poziomu). Dlatego nie mogłem go właściwie zrozumieć, chociaż bardzo dobrze zaprojektowałem i zaimplementowałem interfejsy. Moje pytanie brzmi, praktycznie, po prostu udostępniasz nazwy metod, co oznacza prawo kontraktowe? W JAKI SPOSÓB JEST TO PRZYDATNE :( Wiem, że to zmusza do wdrożenia wszystkich metod, ale w jaki sposób? W swoim poście powyżej na interfejsie, drugi punkt mówi udział, oznacza, że ​​możesz podać praktyczny przykład tego w czasie rzeczywistym. - Learner
Dla praktycznego przykładu dotyczącego interfejsów i SOA, my udostępnij nasze interfejsy WCF (DataContracts) w zestawie .NET (na przykład Contracts.Shared.dll), tak aby klienci klienta .NET mogli z łatwością współdziałać przy użyciu ChannelFactory (unikanie generowania kodu poprzez Add Service Reference itp.) lub używając Dodaj odniesienie do usługi ze współużytkowanymi typami - SliverNinja - MSFT


Jednym z powodów, dla których używam interfejsów, jest zwiększenie elastyczności kodu. Powiedzmy, że mamy metodę, która pobiera obiekt typu Konto jako parametr, taki jak:

  public void DoSomething(Account account) {
  // Do awesome stuff here.
}

Problem polega na tym, że parametr metody jest ustalony w kierunku implementacji konta. Jest to w porządku, jeśli nie potrzebujesz żadnego innego konta. Weź ten przykład, który zamiast tego używa interfejsu konta jako parametru.

public void DoSomething(IAccount account) {
  // Do awesome stuff here.
}

To rozwiązanie nie jest ustalone w kierunku implementacji, co oznacza, że ​​mogę przekazać mu konto SuperSavingsAccount lub ExclusiveAccount (oba implementujące interfejs IAccount) i uzyskać inne zachowanie dla każdego zaimplementowanego konta.


29
2018-03-08 12:45



Miłe wyjaśnienie - Hari


Jednym słowem - z powodu Wielopostaciowość!

Jeśli "Programujesz interfejs, a nie implementację", możesz wtryśnąć różne metody, które mają ten sam interfejs (typ) do metody jako argument. W ten sposób kod metody nie jest powiązany z żadną implementacją innej klasy, co oznacza, że ​​zawsze jest otwarty na pracę z nowo utworzonymi obiektami tego samego interfejsu. (Zasada otwarcia / zamknięcia)

  • Zajrzyj do Dependency Injection i zdecydowanie czytaj Wzorce projektowe - elementy oprogramowania wielokrotnego użytku przez GOF.

15
2017-11-27 23:09





enter image description here

W tym przykładzie PowerSocket nie wie nic więcej o innych obiektach. Wszystkie obiekty zależą od zasilania dostarczonego przez PowerSocket, więc implementują IPowerPlug i dzięki temu mogą się z nim połączyć.

Interfejsy są użyteczne, ponieważ zapewniają umowy, z którymi obiekty mogą współpracować, bez potrzeby wzajemnego poznania się.


4
2017-08-25 12:18





C # nie ma pisania kaczego - tylko dlatego, że wiesz, że pewna metoda jest zaimplementowana w zestawie konkretnych klas, nie oznacza, że ​​możesz traktować je tak samo w odniesieniu do wywoływania tej metody. Implementacja interfejsu pozwala traktować wszystkie klasy implementujące go jako ten sam typ, w odniesieniu do tego, co definiuje ten interfejs.


3
2018-06-06 13:12



Możesz uzyskać rodzaj ducktyping w .net4 z dynamicznego typu. - Tony Hopkinson


Możesz odziedziczyć tylko po jednej klasie abstrakcyjnej. Możesz dziedziczyć z wielu interfejsów. Określa to, czego używam w większości przypadków.

Zaletą klasy abstrakcyjnej byłoby to, że możesz mieć podstawową implementację. Jednak w przypadku IDisposable domyślna implementacja jest bezużyteczna, ponieważ klasa podstawowa nie wie, jak poprawnie wyczyścić rzeczy. W związku z tym interfejs byłby bardziej odpowiedni.


1
2018-06-06 13:14