Ten artykuł jest lustrzanym artykułem tłumaczenia maszynowego, kliknij tutaj, aby przejść do oryginalnego artykułu.

Widok: 18805|Odpowiedź: 0

[Komunikacja] Podobieństwa i różnice między wirtualnym a (abstrakcyjnym) abstrakcją a interfejsem w C#...

[Skopiuj link]
Opublikowano 22.04.2019 14:41:09 | | |
Interpretacja 1

W C# Abstract i Virtual są mylące, oba związane z dziedziczeniem i wymagają stosowania nadpisywania. Omówmy różnice między nimi:

1. Metoda wirtualna

wirtualne słowo kluczowe służy do modyfikacji metod w klasie bazowej. Istnieją dwie sytuacje, w których używa się wirtualności:

Scenariusz 1: Wirtualna metoda jest zdefiniowana w klasie bazowej, ale wirtualna metoda nie jest przepisywana w klasie pochodnej. W wywołaniu do instancji klasy pochodnej, metoda wirtualna wykorzystuje metodę zdefiniowaną przez klasę bazową.

Scenariusz 2: W klasie bazowej definiowana jest metoda wirtualna, a następnie metoda jest przepisywana za pomocą nadpisania w klasie pochodnej. W wywołaniu do instancji klasy pochodnej, metoda wirtualna wykorzystuje metodę wyprowadzonej przepisu.

2. Metoda abstrakcyjna (metoda abstrakcyjna)

Abstrakcyjne słowo kluczowe może być używane tylko w klasach abstrakcyjnych do modyfikacji metod i nie ma konkretnej implementacji. Implementacja metod abstrakcyjnych musi być zaimplementowana przy użyciu słowa kluczowego nadpisującego w klasie pochodnej.

Najważniejsza różnica między interfejsem a klasą abstrakcyjną: klasa abstrakcyjna to klasa niekompletna, abstrakcja obiektu, podczas gdy interfejs jest normą behawioralną.


3. Słowa kluczowe

Statyczna: Gdy metoda jest deklarowana jako statyczna, jest metodą statyczną i kompilator zachowuje jej implementację w czasie kompilacji. To znaczy, metoda należy do klasy, ale nie do żadnego członka, niezależnie od tego, czy instancja tej klasy istnieje, czy nie. Podobnie jak funkcja entry Static void Main, ponieważ jest to funkcja statyczna, można ją wywołać bezpośrednio.

Virtua: Gdy metoda jest deklarowana jako Wirtualna, jest metodą wirtualną, dopóki nie użyjesz zmiennej ClassName = nowa ClassName(); Przed zadeklarowaniem instancji klasy nie istnieje ona w rzeczywistej przestrzeni pamięci. To słowo kluczowe jest bardzo często używane w dziedziczeniu klas, aby zapewnić wsparcie polimorfizmu dla metod klasowych.

overrride: oznacza przepisanie tej klasy
Wirtualne, abstrakcyjne to przekazanie innym klasom, które chcą odziedziczyć po nim, że możesz nadpisać tę moją metodę lub własność, w przeciwnym razie nie jest to dozwolone.
Streszczenie: Deklaracja abstrakcyjnej metody to metoda, którą trzeba nadpisać przez klasę pochodną, która jest dziedziczona; Można ją uznać za metodę wyimaginowaną bez realizacji; Jeśli klasa zawiera metodę abstrakcyjną, to klasa musi być zdefiniowana jako klasa abstrakcyjna, niezależnie od tego, czy zawiera inne metody ogólne, czy nie; Klasy abstrakcyjne nie mogą mieć substancji.

a) Metoda modyfikacji wirtualnej musi mieć implementację metody (nawet jeśli jest to tylko para nawiasów), a metoda abstrakcyjnej modyfikacji nie może mieć implementacji.

b) wirtualne mogą być przepisywane przez podklasy, abstrakcyjne muszą być przepisywane przez podklasy

c) Jeśli funkcja w klasie jest modyfikowana przez abstakt, nazwa klasy również musi zostać zmodyfikowana z abstaktem

d) Abstrakcyjne zmodyfikowane klasy nie mogą być tworzone jako instancje.

e) Jeśli metoda w C# jest gotowa przepisać klasę nadrzędną w podklasie, metoda musi zostać zmodyfikowana tak, by wirtualna w klasie nadrzędnej i nadchodziła w podklasie, zapobiegając przypadkowemu przepisaniu przez programistę metody nadarcza klasy nadrzędnej w podklasie.

Uwaga: Klasy modyfikowane abstrakcją mogą być tylko dziedziczone, a nie instancjonowane.

Interpretacja 2

Zarówno wirtualne, jak i abstrakcyjne służą do modyfikacji klasy nadrzędnej, umożliwiając redefinicję klasy potomnej poprzez nadpisywanie definicji klasy nadrzędnej.

Mają jedną wspólną cechę: jeśli są używane do modyfikowania metod, należy dodać publiczne przed nimi, w przeciwnym razie pojawią się błędy kompilacji: metody wirtualne lub abstrakcyjne nie mogą być prywatne. W końcu dodanie wirtualnych lub abstrakcyjnych pozwala na redefinicję podklasy, a prywatne członki nie mogą być dostępne dla tej podklasy.

Ale są bardzo różne. (wirtualny jest "wirtualny", abstrakcyjny to "abstrakcyjny").

(1) Metoda modyfikacji wirtualnej musi zostać zaimplementowana (nawet jeśli dodaje tylko parę nawiasów), natomiast metoda abstrakcyjnej modyfikacji nie może być zaimplementowana. Na przykład, jeśli metoda modyfikacji wirtualnej nie zostanie zaimplementowana:

Błąd: "Test1.fun1()" musi zadeklarować ciało, ponieważ nie jest oznaczone jako abstrakcyjne, zewnętrzne ani częściowe   

Dla modyfikatorów abstrakcyjnych, jeśli są zaimplementowane:


Błąd: "Test2.fun2()" nie może zadeklarować treści, ponieważ jest oznaczona jako abstrakcyjna   

(2) wirtualne mogą być przepisywane przez podklasy, natomiast abstrakcyjne muszą być przepisywane przez podklasy.
Nie ma błędu w kompilacji, jeśli metoda wirtualnego modyfikatora zostanie przepisana, należy dodać przed nią nadpisanie (które informuje kompilator, że chcesz przepisać tę metodę) i musi istnieć implementacja, w przeciwnym razie kompilacja będzie błędna:
(3) Jeśli członek klasy zostanie zmodyfikowany przez abstrakcję, abstrakcyjne musi zostać dodane przed klasą, ponieważ tylko klasy abstrakcyjne mogą mieć metody abstrakcyjne.

(4) Instancje klas abstrakcyjnych nie mogą być tworzone, można je jedynie dziedziczyć i nie można ich instancjonować, na przykład: BaseTest2 base2 = nowy BaseTest2(); Wystąpi błąd kompilacji: klasa abstrakcyjna lub interfejs nie może utworzyć instancji.

(5) W C#, jeśli chcesz przepisać metodę w podklasie, musisz dodać wirtualną metodę przed metodą nadrzędną i nadpisać ją przed metodą podklasy, aby uniknąć przypadkowego przepisania metody nadrzędnej w podklasie przez programistów.

(6) Metoda abstrakcyjna musi zostać nadpisana, a metoda wirtualna musi mieć implementację (nawet jeśli jest to metoda zdefiniowana w klasie abstrakcyjnej).
Interpretacja 3
Podobieństwa:
1. Wszystkie mogą być dziedziczone
2. Żadna z nich nie może być instancjonowana
3. Może zawierać deklaracje metod
4. Klasy pochodne muszą implementować metody niezrealizowane
Rozróżniać:
1. Abstrakcyjne klasy bazowe mogą definiować pola, atrybuty i implementacje metod. Interfejsy mogą definiować jedynie atrybuty, indeksery, zdarzenia i deklaracje metod, nie mogą zawierać pól.
2. Klasa abstrakcyjna to klasa niekompletna, którą trzeba jeszcze bardziej dopracować, podczas gdy interfejs jest normą behawioralną. Niestandardowe interfejsy Microsoftu zawsze mają odpowiednie pole, które potwierdza, że są wyrazem "Dam radę..." ”
3. Interfejsy mogą być implementowane wielokrotnie, a klasy abstrakcyjne mogą być dziedziczone tylko przez jedną osobę
4. Klasy abstrakcyjne są bardziej zdefiniowane pomiędzy serią blisko spokrewnionych klas, podczas gdy większość interfejsów jest luźno powiązana, ale wszystkie realizują określoną funkcję
5. Klasy abstrakcyjne to pojęcia abstrahowane z serii powiązanych obiektów, więc odzwierciedlają wewnętrzną wspólnotę rzeczy; Interfejs to konwencja funkcjonalna zdefiniowana w celu spełniania wywołań zewnętrznych, więc odzwierciedla zewnętrzne cechy rzeczy
6. Interfejs zasadniczo nie posiada żadnych specyficznych cech dziedziczenia, obiecuje jedynie metodę, którą można wywołać
7. Interfejs może wspierać wywołania zwrotne, ale dziedziczenie nie posiada tej funkcji
8. Konkretne metody zaimplementowane przez klasy abstrakcyjne są domyślnie wirtualne, ale metody interfejsu w klasie implementującej interfejs są domyślnie niewirtualne, oczywiście można je również zadeklarować jako wirtualne
9. Jeśli klasa abstrakcyjna implementuje interfejs, metoda w interfejsie może być odwzorowana na klasę abstrakcyjną jako metoda abstrakcyjna bez konieczności jej implementacji, ale metoda w interfejsie może być zaimplementowana w podklasie klasy abstrakcyjnej
Zasady użytkowania:
1. Klasy abstrakcyjne są głównie używane dla blisko powiązanych obiektów, podczas gdy interfejsy najlepiej sprawdzają się w celu zapewnienia ogólnej funkcjonalności dla klas nieistotnych
2. Jeśli chcesz zaprojektować dużą jednostkę funkcyjną, użyj klas abstrakcyjnych; Jeśli chcesz projektować małe, zwięzłe bloki funkcjonalne, użyj interfejsów.
3. Jeśli oczekuje się utworzenia wielu wersji komponentu, należy utworzyć klasę abstrakcyjną. Gdy interfejs zostanie utworzony, nie można go zmienić. Jeśli wymagana jest nowa wersja interfejsu, należy utworzyć całkowicie nowy interfejs.
4. Jeśli utworzona funkcja będzie używana pomiędzy szerokim zakresem heterogenicznych obiektów, użyj interfejsu; Jeśli chcesz zapewnić wspólną implementowaną funkcjonalność we wszystkich implementacjach komponentu, użyj klas abstrakcyjnych.
5. Analizować obiekt, dopracować wewnętrzną wspólność, tworząc abstrakcyjną klasę, która służy do wyrażenia istoty obiektu, czyli "czego". Interfejsy są priorytetyzowane, gdy zewnętrzne wywołania lub funkcje wymagają rozszerzenia
6. Dobra definicja interfejsu powinna być konkretna i funkcjonalna, a nie wielofunkcyjna, w przeciwnym razie powoduje zanieczyszczenie interfejsów. Jeśli klasa implementuje tylko jedną funkcję interfejsu, ale musi implementować inne metody w interfejsie, nazywa się to zanieczyszczeniem interfejsów
7. Staraj się unikać dziedziczenia do osiągnięcia funkcji formowania, ale używaj multipleksowania czarnej skrzynki, czyli kombinacji obiektów. Ze względu na wzrost liczby poziomów dziedziczenia najbardziej bezpośrednią konsekwencją jest to, że gdy wywołujesz klasę w tym taksonie, musisz załadować je wszystkie do stosu! Konsekwencje można sobie wyobrazić. (W połączeniu ze zrozumieniem zasady stosu). Jednocześnie zainteresowani znajomi mogą zauważyć, że Microsoft często stosuje metodę łączenia obiektów przy budowaniu klasy. Na przykład w asp.net klasa Page ma właściwości takie jak Server Request, ale w rzeczywistości są to wszystkie obiekty danej klasy. Użycie tego obiektu klasy Page do wywoływania metod i właściwości innych klas to bardzo podstawowa zasada projektowania
Na przykład:
Formy okien mogą być projektowane z klasami abstrakcyjnymi, a operacje publiczne i właściwości można umieścić w klasie abstrakcyjnej, tak aby forma i okno dialogowe mogły dziedziczyć z tej klasy abstrakcyjnej, a następnie rozszerzać się i ulepszać według własnych potrzeb.

Operacja drukowania może być udostępniona jako interfejs do każdego formularza, który potrzebuje tej funkcji, ponieważ treść formularza jest inna i muszą one zaimplementować własną funkcję druku zgodnie z własnymi wymaganiami. Podczas drukowania jest wywoływany tylko przez interfejs, niezależnie od tego, który formularz jest drukowany.

Wspólność, indywidualność i wybór:
Niektóre książki piszą, że C# zaleca używanie interfejsów zamiast abstrakcyjnych klas bazowych i podkreślają liczne zalety korzystania z interfejsów, z którymi nie odważę się nie zgłaszać; z powyższej listy wciąż istnieje wiele różnic między tymi dwoma elementami, a istnienie tych różnic musi determinować różnice w odpowiednich scenariuszach, na przykład abstrakcyjna klasa bazowa może zapewnić domyślne implementacje dla niektórych metod, aby uniknąć powtarzających się ich implementacji w podklasach i poprawić ponowne wykorzystanie kodu. To jest zaleta klas abstrakcyjnych; Interfejs może zawierać jedynie metody abstrakcyjne. Jeśli chodzi o to, kiedy używać abstrakcyjnych klas bazowych, a kiedy interfejsów, zależy to od tego, jak użytkownicy postrzegają powiązania między odziedziczonymi klasami, czy to różnice osobowości, czy wspólne połączenia między nimi. Pozwólcie, że zilustruję to przykładem z życia.

Jeśli dostaniesz trzy obiekty, czyli ludzi, ryby i żaby, i poproszono cię o zaprojektowanie dla nich kategorii podstawowej, która podsumuje ich powiązanie, to pierwszą rzeczą, którą poczujesz, jest to, że istnieją między nimi ogromne różnice i trudno jest je zabstrahować. To właśnie tutaj powinieneś rozważyć użycie interfejsów zamiast abstrakcyjnych klas bazowych z trzech powodów:
1. Indywidualność jest większa niż wspólnota.
2. Osobowości o dużych różnicach mają niektóre z tych samych zachowań.
3. Istnieją duże różnice w metodach realizacji tego samego zachowania.
W tym momencie otrzymujesz trzy kolejne obiekty: karpia karbija, karpia i złotą rybkę, i nadal możesz projektować klasy bazowe, by podsumować ich powiązania. Najpierw zauważasz, że wszystkie należą do ryb, a po drugie, sposób, w jaki pływają, może się nieco różnić, więc zamiast interfejsów powinieneś używać abstrakcyjnych klas bazowych, w porównaniu do powyższego przykładu, są trzy powody:
1. Wspólnota jest większa niż indywidualność
2. Osoby o podobnych cechach muszą mieć te same cechy i zachowania
3. Istnieją pewne różnice w metodach implementacji tego samego zachowania
Spośród kilku powodów stosowania interfejsów lub abstrakcyjnych klas bazowych, trzeci powód jest w rzeczywistości ten sam – opisuje pojęcie polimorfizmu w obiektowo-zorientowanym, czyli jest on realizowany przez nadpisywanie klasy rodzica i wywołanie odpowiadającej jej metody w czasie wykonywania zgodnie z przekazanym odwołaniem do obiektu. Drugi powód zaczyna się rozchodzić – interfejsy podkreślają to samo zachowanie między dziedziczonymi obiektami, podczas gdy klasy abstrakcyjne również podkreślają te same właściwości między dziedziczonymi obiektami. To, co naprawdę odróżnia interfejsy od abstrakcyjnych klas bazowych, to następujące powody:

Interfejsy są używane, gdy poszukiwane jest funkcjonalne podobieństwo między obiektami o dużych różnicach.
Abstrakcyjne klasy bazowe są stosowane, gdy poszukiwane są różnice funkcjonalne między obiektami o większej wspólności.
Porównując to samo i różne, możemy jedynie powiedzieć, że interfejsy i klasy abstrakcyjne mają swoje zalety, ale nie mają żadnych zalet. W praktyce programowania musimy mierzyć nasze umiejętności według konkretnej sytuacji, ale kolejne doświadczenie i nagromadzenie mogą dać ci inspirację, oprócz części mojego zbioru, wiele z nich pochodzi z klasyków i wierzę, że mogą wytrzymać test. Dlatego w zasadach i okazjach, gdy uczymy się tych klasyków, najważniejsze jest, by zastosować to, czego się nauczyliśmy, oczywiście, wywołam śmiech wszystkich słowami rodziny, proszę, kontynuujcie.

Zasady i okazje:
1. Pamiętaj, że jedną z najważniejszych zasad myślenia obiektowego jest: programowanie zorientowane na interfejs.
2. Dzięki interfejsom i klasom abstrakcyjnym wiele pomysłów w 23 wzorcach projektowych zostało sprytnie zaimplementowanych, a ich istotą jest po prostu orientacja na programowanie abstrakcyjne.
3. Klasy abstrakcyjne powinny być głównie używane dla blisko powiązanych obiektów, natomiast interfejsy najlepiej służą do zapewnienia ogólnej funkcjonalności dla klas nieistotnych.
4. Interfejs koncentruje się na typie relacji CAN-DO, natomiast klasa abstrakcyjna na relacji IS-A.
5. Zachowanie obiektów wielodefiniowanych w interfejsie; klasy abstrakcyjne wielokrotnie definiują właściwości obiektów;
6. Definicje interfejsów mogą wykorzystywać modyfikatory publiczne, chronione, wewnętrzne i prywatne, ale niemal wszystkie interfejsy są definiowane jako publiczne, więc nie ma potrzeby mówić więcej.
7. "Interfejs pozostaje niezmieniony" to ważny czynnik, który należy wziąć pod uwagę. Dlatego przy dodawaniu rozszerzeń z interfejsów należy dodawać nowe interfejsy, a nie istniejące.
8. Spróbuj zaprojektować interfejs jako blok funkcjonalny z jedną funkcją, biorąc na przykład .NET Framework, IDisposable, IDisposable, IComparable, IEquatable, IEnumerable itd. wszystkie zawierają tylko jedną wspólną metodę.
9. Wielka litera "I" przed nazwą interfejsu to konwencja, podobnie jak nazwa pola zaczyna się od podkreślenia, prosimy o przestrzeganie tych zasad.
10. W interfejsie wszystkie metody domyślnie są publiczne.
11. Jeśli spodziewane są problemy z wersją, możesz stworzyć "klasę abstrakcyjną". Na przykład, jeśli tworzysz psa, kurczaka i kaczkę, powinieneś rozważyć abstrahowanie zwierząt, aby radzić sobie z problemami, które mogą pojawić się w przyszłości. Dodanie nowych członków do interfejsu wymusza modyfikację i rekompilację wszystkich klas pochodnych, dlatego problemy wersjonowania najlepiej realizować za pomocą klas abstrakcyjnych.
12. Klasy nieabstrakcyjne pochodzące z klas abstrakcyjnych muszą zawierać wszystkie odziedziczone metody abstrakcyjne oraz rzeczywiste implementacje abstrakcyjnych akumulatorów.
13. Nowe słowo kluczowe nie może być używane dla klas abstrakcyjnych, ani nie można ich zapieczętować, ponieważ klas abstrakcyjnych nie można instancjonować.
14. Statyczne lub wirtualne modyfikatory nie mogą być używane w abstrakcyjnych deklaracjach metod.





Poprzedni:C# Enum Simple Permission Design wykorzystuje właściwość FlagsAttribute
Następny:Klasa Yiyun prowadzona przez Huang Yonga ma zerową wiedzę o mini-programie WeChat
Zrzeczenie się:
Całe oprogramowanie, materiały programistyczne lub artykuły publikowane przez Code Farmer Network służą wyłącznie celom edukacyjnym i badawczym; Powyższe treści nie mogą być wykorzystywane do celów komercyjnych ani nielegalnych, w przeciwnym razie użytkownicy ponoszą wszelkie konsekwencje. Informacje na tej stronie pochodzą z Internetu, a spory dotyczące praw autorskich nie mają z nią nic wspólnego. Musisz całkowicie usunąć powyższą zawartość z komputera w ciągu 24 godzin od pobrania. Jeśli spodoba Ci się program, wspieraj oryginalne oprogramowanie, kup rejestrację i korzystaj z lepszych, autentycznych usług. W przypadku naruszenia praw prosimy o kontakt mailowy.

Mail To:help@itsvse.com