2009-07-08 22 views
5

Załóżmy, że tworzymy formant ogólny w .NET. Na przykład. drzewo. Nie rozumiem, dlaczego ludzie używają Ta ogólna definicja typuTypy generyczne a Klasa abstrakcyjna/Interfejsy

Control<T> 

gdy w Object Oriented Programming można użyć klasy abstrakcyjnej lub interfejsu:

Control<IItem> or Control<BaseClass> 

Więc jedyną rzeczą do zrobienia jest, że ich typy muszą pochodzić z tej klasy bazowej lub implementować interfejs . Czy to oznacza, że ​​typy ogólne są wygodniejsze, ponieważ nie muszę niczego wdrażać ani dziedziczyć?

Odpowiedz

16

Myślę, że jesteś nieco zdezorientowany. Typy ogólne i abstrakcyjne klasy/interfejsy służą różnym celom dla różnych podejść w projektowaniu aplikacji. Abstrakcyjne klasy/interfejsy służą do uogólnienia wspólnej funkcjonalności grupy encji. Później ten interfejs API może zostać zaimplementowany inaczej, ale ponieważ w grę wchodzi polimorfizm, nie wpłynie to na nikogo.

Z drugiej strony, czasami masz bardzo podobną implementację czegoś, a jedyną różnicą jest rodzaj obiektów, z którymi pracujesz. Tutaj będziesz potrzebował generycznych. Można użyć polimorfizmu, ale nie ma takiej potrzeby. W tym celu znacznie wyraźniej zdefiniować interfejs, dokonać implementacji i pozwolić użytkownikowi końcowemu zdecydować, jakiego rodzaju obiektu użyć.

Najlepszym przykładem jest List, gdzie głównym celem listy jest przechowywanie elementów. Wykonawca List nie powinien przejmować się jakim typem obiektów będziesz używał, więc później będziesz mógł po prostu zdefiniować List i użyć listy całkowitej.

+0

OK, teraz rozumiem różnicę, dziękuję bardzo. –

+0

Cieszę się, że zrobiłem dla ciebie trochę jasne. –

3

Ponieważ w przypadku kontroli drzewa zdefiniowanie ogólnej kontroli drzewa oznaczałoby, że elementy drzewa mogą być dowolnego rodzaju (można również dodać pewne ograniczenia).

Podczas tworzenia formantu trzeba oczywiście zadeklarować typ przedmiotu (jak w drugim przykładzie kodu z IItem i BaseClass).

Jeśli kontrola drzewa nie byłaby typem ogólnym, konieczne byłoby utworzenie kilku elementów sterujących dla każdego typu elementu.

Dlaczego po prostu nie używać typu interface/abstractBase? Jeśli użyjesz interfejsu/abonenta jako klasy typu Element, ograniczą cię jego definicje. Widziałbyś tylko jego właściwości i metody. Dzięki ogólnemu sterowaniu drzewem i dowolnemu typowi elementu nadal możesz uzyskać dostęp do wszystkich właściwości i metod elementu, niezależnie od implementacji interfejsu lub dziedziczenia klasy nadrzędnej ...

+0

Tak, dziękuję, właśnie tego chciałem usłyszeć. –

+0

Ale mam jeszcze jedno pytanie, co jeśli chcę ograniczyć typ T do posiadania właściwości Parent i Children i nie używam interfejsu. Czy to możliwe? –

+0

@stefan - ograniczenia muszą być wyrażone poprzez interfejsy, z wyjątkiem kilku prostych rzeczy: jest to typ wartości ("where T: struct") lub typ odniesienia ("where T: class") lub ma on domyślny konstruktor ('where T: new()') –

Powiązane problemy