2011-09-28 13 views
8

Mam kilka systemów, można je nazwać A, B, C, D, E, F, G, H, I, J.Metody interfejsu, abstrakcyjne lub tylko wirtualne?

Wszystkie mają podobne metody i właściwości. Niektóre zawierają dokładnie tę samą metodę i właściwości, niektóre mogą się nieznacznie różnić, a niektóre mogą się bardzo różnić. Obecnie mam wiele zduplikowanych kodów dla każdego systemu. Na przykład mam metodę o nazwie GetPropertyInformation(), która jest zdefiniowana dla każdego systemu. Próbuję dowiedzieć się, która metoda będzie najlepszym rozwiązaniem w celu zmniejszenia duplikat kodu lub może jeden z poniższych sposobów nie jest sposobem, aby przejść:

Interfejs

public Interface ISystem 
{ 
    public void GetPropertyInformation(); 
    //Other methods to implement 
} 

public class A : ISystem 
{ 
    public void GetPropertyInformation() 
    { 
     //Code here 
    } 
} 

Streszczenie

public abstract class System 
{ 
    public virtual void GetPropertyInformation() 
    { 
     //Standard Code here 
    } 
} 

public class B : System 
{ 
    public override void GetPropertyInformation() 
    { 
     //B specific code here 
    } 
} 

wirtualne metody w klasie Super bazy

public class System 
{ 
    public virtual void GetPropertyInformation() 
    { 
    //System Code 
    } 
} 

public class C : System 
{ 
    public override void GetPropertyInformation() 
    { 
     //C Code 
    } 
} 

Jedno pytanie, chociaż może być głupi, to załóżmy, że poszedłem z abstrakcyjnego podejścia i chciałem zastąpić GetPropertyInformation, ale musiałem przekazać mu dodatkowy parametr, jest to możliwe, czy musiałbym stworzyć inną metodę w klasie abstrakcyjnej? Na przykład: GetPropertyInformation(x)

Odpowiedz

6

Twoje abstrakcyjne i "superpodstawowe" podejścia nie różnią się zbytnio. Powinieneś zawsze uczynić klasę podstawową abstraktową i możesz podać domyślną implementację (metody wirtualne) lub nie (metody abstrakcyjne). Decydującym czynnikiem jest to, czy kiedykolwiek chcesz mieć instancje klasy bazowej, nie sądzę.

Jest to więc między klasą bazową a interfejsem. Jeśli istnieje silne powiązanie między twoimi klasami A, B C, możesz użyć klasy bazowej i prawdopodobnie wspólnej implementacji.

Jeśli klasy A, B, C w naturalny sposób nie należą do jednej "rodziny", należy użyć interfejsu.

I System nie jest tak dobrą nazwą.

Nie można zmienić listy parametrów podczas przesłonięcia. Może domyślne parametry mogą pomóc, w przeciwnym razie potrzebujesz tylko 2 przeciążenia dla GetPropertyInformation().

+0

Miałem wrażenie, że klasy abstrakcyjne i super-bazowe są podobne. Systemy A, B, C mają silne połączenie. Istnieje standard branżowy, ale nie trzeba go stosować, aby każdy mógł zastosować standard lub zmienić standard ich dopasowania. W pośpiechu wybrałem System :) – Xaisoft

+0

Dobre punkty przy okazji. – Xaisoft

3

Zasadniczo wybierasz dziedziczenie obiektów, gdy chcesz udostępnić implementację i zredukować to, co w przeciwnym razie byłoby przyczyną duplikowania. W przeciwnym razie wygrywają interfejsy, ponieważ są bardziej elastyczne, ponieważ nie ma potrzeby posiadania wspólnej klasy bazowej.

Co do nadpisywania metody i modyfikowania listy parametrów, która jest po prostu niemożliwa. Wyobraź sobie, jak nazwałbyś tę metodę na podstawie klasy bazowej lub odniesienia do interfejsu?

+0

Jest "możliwe" - powinieneś być w stanie zadeklarować taką metodę, to po prostu nie jest już przesłonięcie oryginalnej metody. – millimoose

+2

@Sii To na pewno nie jest możliwe. Pytanie: * przesłonić * metodę i dodać parametr. Tego nie można zrobić. –

+0

Miałem przeczucie, że nie da się tego zrobić, pobożne życzenie. – Xaisoft

3

Poszedłbym z czymś podobnym do tego, co dodałem poniżej. Nadal możesz korzystać z umowy interfejsu i wspólnej implementacji.

+0

Czy możesz wyjaśnić, dlaczego zrobiłbyś to podejście? – Xaisoft

+0

W ten sposób nadal otrzymujesz wszystkie swoje właściwości, nawet jeśli programujesz tylko z interfejsem 'ISystem' (co powinieneś zrobić, gdy je masz). Jeśli jednak kodujesz w kontekście, w którym istnieje tylko B: 'B bSystem = new B();' również ujawniasz specyficzną metodę 'B' do jawnego użycia. – scottm

2

Nie można przekazać dodatkowego parametru w trybie zastępowania. Kiedy nadpisujesz, nadpisujesz metodę dokładnym podpisem. Sugerowałbym, abyś przekazał parametr interfejsu, taki jak IPropertyInformation, który może zmieniać się w zależności od implementacji.

Decyzja o wyborze klasy bazowej lub interfejsu do wdrożenia naprawdę zależy od sposobu użycia. Czy A-I ma ze sobą tyle wspólnego, że naprawdę wszyscy powinni wywodzić się z tej samej klasy bazowej? Jeśli tak, użyj klasy bazowej. Czy to naprawdę, że tylko GetPropertyInformation jest udostępniany, a poza tym systemy są całkowicie funkcjonalnie różne? Wtedy naprawdę chcesz, aby współużytkowali interfejs.

2

Inne dotyczyły tego, co było pierwotnie w mojej odpowiedzi, ale o punkcie "dodawanie parametru": nie zapominaj, że najnowsze C# również pozwala ci mieć opcjonalne parametry w metodach.

+0

Ale musiałbym zadeklarować opcjonalne parametry na samym początku. Mogę nie wiedzieć, że potrzebuję parametru do 1 roku w dół drogi, więc opcjonalne parametry nie robią mi nic dobrego w tym przypadku. – Xaisoft

2

Jeśli nie masz innego nieodpartego powodu, skorzystałbym z interfejsu. Publiczne metody wirtualne, choć dużo zrobione, to not ideal.

Powiązane problemy