Dlaczego powinienem przejść do interfejsów w C# skoro mogę zaimplementować metody bezpośrednio

Wiem, że to bardzo podstawowe pytanie, ale rozmówca zadał mi bardzo podstępny sposób i byłem bezradny: (

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

Nie rozumiem też jednej rzeczy w interfejsie. np. używamy

conn.Dispose(); W końcu blok. Ale nie widzę, żeby Klasa implementowała lub dziedziczyła IDisposable interface (SqlConnection) class I mean. Zastanawiam się, jak mogę po prostu nazwać nazwę metody. Również w tej samej rzeczy, nie rozumiem, jak metody Dispose działa ponieważ, musimy zaimplementować ciało funkcji z naszej własnej implementacji dla wszystkich metod interfejsu. W jaki sposób interfejsy są akceptowane lub nazywane umowami? Te pytania ciągle toczyły się w mojej głowie do tej pory i szczerze mówiąc nigdy nie widziałem żadnego dobrego wątku, który wyjaśniałby moje pytania w sposób, który mogę zrozumieć.

MSDN jak zwykle wygląda bardzo przerażająco i żadna pojedyncza linia nie jest tam wyraźna (ludzie, uprzejmie przepraszam, którzy są w rozwoju wysokiego poziomu, mocno czuję, że każdy kod lub artykuł powinien dotrzeć do umysłu każdego, kto go widzi, stąd jak wiele innych mówi, MSDN nie jest użyte ).

Rozmówca powiedział:

MA 5 metod i chętnie implementuje je bezpośrednio w klasie, ale jeśli musisz wybrać klasę abstrakcyjną lub interfejs, którą wybierzesz i dlaczego ? Odpowiedziałam mu na wszystkie rzeczy, które czytaj w różnych blogach mówiąc zalety i wady zarówno klasy abstrakcyjnej i interfejsu, ale nie jest przekonany, stara się zrozumieć" dlaczego interfejs " w ogóle. "Why abstract class" w ogóle, nawet jeśli Mogę zaimplementować te same metody tylko raz i nie będzie go zmieniać.

Nie widzę gdzie w necie, mógłbym dostać artykuł, który wyjaśniłby mi jasno o interfejsach i ich funkcjonowaniu. Jestem jednym z tych wielu programistów, którzy nadal nie wiedzą o interfejsach (wiem teoretyczne i metody stosowane), ale nie zadowolony, że zrozumiałam to wyraźnie.

 83
Author: Failed Scientist, 2012-06-06

13 answers

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, mogą tworzyć swoje klasy, a kiedy chcą się zalogować, implementują interfejs IMyLogInterface. To tak, jak pytali mnie, co muszą zaimplementować, aby użyć metody WriteLog() w MyLogClass. Odpowiedź znajdą w interfejsie.

 72
Author: Guilherme de Jesus Santos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-20 05:48:44

Interfejsy są umowami, których implementatorzy muszą przestrzegać. klasy abstrakcyjne pozwalają na kontrakty oraz współdzielone implementacje - coś, czego Interfejsy nie mogą mieć. Klasy mogą implementować i dziedziczyć wiele interfejsów. Klasy mogą rozszerzać tylko jedną klasę abstrakcyjną.

Dlaczego Interfejs

  • nie masz domyślnej lub współdzielonej implementacji kodu
  • Chcesz udostępnić dane umowy (web services, SOA)
  • masz różne implementacje dla każdego implementatora interfejsu(IDbCommand mA SqlCommand i OracleCommand które implementują interfejs w określony sposób )
  • chcesz wspierać dziedziczenie wielokrotne.

Dlaczego Abstrakcja

 38
Author: SliverNinja - MSFT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-06 13:28:54

Używam interfejsów, ponieważ zwiększa to elastyczność kodu. Załóżmy, że mamy metodę, która jako parametr przyjmuje obiekt typu class Account, np.:

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

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

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

Rozwiązanie to nie jest stałe w kierunku implementacja, co oznacza, że mogę przekazać ją SuperSavingsAccount lub ExclusiveAccount (zarówno implementując interfejs IAccount) i uzyskać inne zachowanie dla każdego zaimplementowanego konta.

 30
Author: user2211290,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-08 12:45:07

Jednym słowem-z powodu polimorfizmu !

Jeśli "programujesz do interfejsu, a nie do implementacji", możesz wprowadzić do metody różne obiekty, które mają ten sam interfejs(typ) jako argument. W ten sposób Kod metody nie jest połączony z żadną implementacją innej klasy, co oznacza, że jest zawsze otwarty do pracy z nowo utworzonymi obiektami tego samego interfejsu. (Zasada Otwierania/Zamykania)

  • zajrzyj do Dependency Injection i koniecznie przeczytaj wzorce projektowe-elementy oprogramowania Obiektowego Wielokrotnego Użytku autorstwa GOF.
 15
Author: Gabriel C. Troia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-27 23:09:08

Tutaj wpisz opis obrazka

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

Interfejsy są użyteczne, ponieważ zapewniają Kontrakty, których obiekty mogą używać do współpracy bez potrzeby wiedzy o sobie nawzajem.

 9
Author: Brijesh Rana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-25 12:18:08

C# nie ma typowania kaczek - to, że wiesz, że pewna metoda jest zaimplementowana w zestawie konkretnych klas, nie oznacza, że możesz traktować je wszystkie tak samo, jeśli chodzi o wywołanie tej metody. Implementacja interfejsu pozwala traktować wszystkie klasy implementujące go jako ten sam typ rzeczy, w odniesieniu do tego, co ten interfejs definiuje.

 4
Author: Erix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-06 13:12:17

Możesz dziedziczyć tylko z jednej klasy abstrakcyjnej. Można dziedziczyć z wielu interfejsów. To określa, czego używam w większości przypadków.

Zaletą klasy abstrakcyjnej byłoby to, że można mieć implementację bazową. Jednak w przypadku IDisposable, Domyślna implementacja jest bezużyteczna, ponieważ klasa bazowa nie wie, jak prawidłowo wyczyścić rzeczy. W ten sposób interfejs byłby bardziej odpowiedni.

 1
Author: Jeow Li Huan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-06 13:14:20

Za pomocą interfejsu możesz wykonać następujące czynności:

1) twórz oddzielne interfejsy, które oferują różne cięcia implementacji, co pozwala na bardziej spójny interfejs.

2) Zezwalaj na stosowanie wielu metod o tej samej nazwie między interfejsami, ponieważ nie masz sprzecznej implementacji, tylko podpis.

3) możesz wersja i hive off swój interfejs niezależnie od wdrożenia, upewniając się, że kontrakt jest spełniony.

4) Twój kod może polegać na abstrakcja zamiast konkrecji, pozwalająca na inteligentne wstrzykiwanie zależności, w tym wstrzykiwanie próbnych Moków itp.

Jest o wiele więcej powodów, jestem pewien, to tylko kilka.

Klasa abstrakcyjna pozwala mieć częściowo konkretną podstawę do pracy, nie jest to to samo co interfejs, ale ma swoje własne cechy, takie jak możliwość tworzenia częściowej implementacji za pomocą wzorca metody szablonowej.

 1
Author: Jeff Watkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-06 13:15:20

Zarówno klasa abstrakcyjna, jak i interfejs są umowami.

Idea umowy polega na określeniu jakiegoś zachowania. Jeśli twierdzisz, że wdrożyłeś, zgodziłeś się na umowę.

Wybór abstrakcji nad interrface jest.

Każdy nieabstraktowy potomek klasy abstrakcyjnej zaimplementuje umowę.

Kontra

Każda klasa, która implementuje interfejs, zaimplementuje kontrakt.

Więc używasz abstract, gdy chcesz określić jakieś zachowanie potomkowie muszą zaimplementować i oszczędzić sobie definiowania odrębnego interfejsu, ale teraz wszystko, co spełnia tę skutecznie zagregowaną umowę, musi być potomkiem.

 1
Author: Tony Hopkinson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-06 13:28:03

[6]}wierzę, że wiele krwi zostało już przelanych podczas zadawania tych pytań i wielu próbuje rozwiązać te problemy, wyjaśniając pojęcia podobne do robotów, których żaden normalny człowiek nie może zrozumieć.

Więc Najpierw. aby dowiedzieć się, dlaczego interfejs i dlaczego abstract musisz dowiedzieć się, do czego są one przeznaczone. Osobiście nauczyłem się tego podczas stosowania klasy Fabrycznej. znajdziesz dobry tuturial pod tym linkiem

Teraz kopmy w bazie na link, który już dałem.

Masz pojazd Klasa to może się zmienić w zależności od wymagań użytkownika (np. dodanie Truck, Tank, samolot , itp. I biorąc pod uwagę, że mamy

public class clsBike:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Bike");
    }
    #endregion
}

I

public class clsCar:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Car");
    }
    #endregion
}

I oba mają kontrakt iChoice, który po prostu mówi, że moja klasa powinna mieć metodę kupna

public interface IChoice
{
    string Buy();
}

Teraz widzisz, ten interfejs tylko wymusza metodę Buy() ale niech dziedziczona Klasa zdecyduje, co zrobi, gdy ją zaimplementuje. Jest to ograniczenie interfejsu, używając czysto interfejsu, możesz skończyć powtarzając jakieś zadanie które możemy wdrożyć automatycznie za pomocą abstact. Na naszym przykładzie powiedzmy, że zakup każdego pojazdu ma zniżkę.

public abstract class Choice
{
    public abstract string Discount { get; }
    public abstract string Type { get; }
    public string Buy()
    {
       return "You buy" + Type + " with " + Discount;
}
public class clsBike: Choice
{
    public abstract string Discount { get { return "10% Discount Off"; } }
    public abstract string Type { get { return "Bike"; } }
}

public class clsCar:Choice
{
    public abstract string Discount { get { return " $15K Less"; } }
    public abstract string Type { get { return "Car"; } }
}

Teraz używając klasy Factory, możesz osiągnąć to samo, ale używając abstrakcji, pozwalasz klasie bazowej wykonać metodę Buy().

In Summary: Interface contracts let the inherit class do the implementation while klasa abstrakcyjna Kontrakty mogą zainicjować implementację (która może nadpisać przez Inherit class)

 1
Author: dr.Crow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-11 12:51:34

Interfejsy pozwalają projektantowi klasy uczynić dostępne metody bardzo przejrzystymi dla użytkownika końcowego. Stanowią również integralną część polimorfizmu.

 0
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-06 13:10:40

Nie będę zamieszczał definicji interfejsu przeciwko klasie abstrakcyjnej, ponieważ myślę, że znasz bardzo dobrze teorię i zakładam, że znasz solidne zasady, więc przejdźmy do praktycznych.

Jak wiesz, interfejsy nie mogą mieć żadnego kodu, więc dis-vantage jest dość prosty do zrozumienia.

Jeśli potrzebujesz zainicjalizować właściwość swojej klasy dostarczającej konstruktor lub chcesz podać część implementacji, klasa abstrakcyjna będzie dobrze pasować do interfejsu, który nie pozwoliłby ci na to.

Więc w bardzo ogólnym ujęciu powinieneś preferować klasę abstrakcyjną niż interfejsy, gdy musisz dostarczyć klientowi konstruktor lub dowolny kod, który odziedziczy/rozszerzy Twoją klasę

 0
Author: Massimiliano Peluso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-06 13:14:13

Klasy abstrakcyjne są przeznaczone dla jednostek powiązanych, gdzie Interfejsy as mogą być używane dla jednostek niepowiązanych.

Na przykład, jeśli mam dwa byty powiedzmy zwierzę i człowiek, to pójdę do interfejsu, gdzie jakbym musiał przejść w szczegółach powiedzmy Tygrys, Lew i chcę odnosić się do zwierzęcia, to wybierze Animal Abstract class..

Będzie wyglądać jak poniżej

   Interface             
   ____|____
  |        |
Animal   Human



  Animal (Abstract class)
   __|___
  |      |
Tiger   Lion
 -1
Author: Manoj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-25 17:54:24