2013-05-20 12 views
11

Mam część kodu, gdzie niektóre klasy implementują interfejs.Klasa abstrakcyjna i interfejs razem?

To wydaje się być poprawne, ale wśród zajęć dziecięcych występuje niewielka duplikacja - a mianowicie 3 metody.

Więc to krzyczy, aby użyć klasy abstrakcyjnej.

Moje pytanie brzmi, czy będzie jakieś minusy w użyciu zarówno klasa abstrakcyjna i interfejs w następujących sytuacjach:

  1. klasy abstrakcyjnej wdrożyć klas interfejsu i dziecko do rozszerzenia klasy abstrakcyjnej
  2. klas podrzędnych rozszerzenie klasy abstrakcyjnej i implementować interfejs

Albo

powinien klasy abstrakcyjne i interfejsy nie używać w ogóle w ten sposób?

+1

Nie ma powodu, dla którego nie powinny one być –

+2

Nop, wcale. W rzeczywistości większość tego, co robię, jest właśnie taka. –

Odpowiedz

16

Używanie tych dwóch elementów jest całkowicie normalne. Rozważmy na przykład AbstractList (wdrażanie List) i AbstractMap (wdrażanie Map) w JDK.

Moja odruchowa reakcja byłaby mają abstrakcyjne klasy implementują interfejs, a następnie mieć konkretne klasy wywodzą się z nim:

abstract class Base implements TheInterface { 
    /* ...shared methods... */ 
} 

class Concrete1 extends Base { } 

class Concrete1 extends Base { } 

Ale twoje pytanie podniesienie innej możliwości mi myśleć, a ja nie można zobaczyć wiele argumentów przeciwko robią to w ten sposób:

abstract class Base { 
    /* ...shared methods... */ 
} 

class Concrete1 extends Base implements TheInterface { } 

class Concrete1 extends Base implements TheInterface { } 

Ponadto widzę argumentu dla robi to w ten sposób, zwłaszcza, że ​​usuwa sprzężenia abstrakcyjnej C lass i interfejs. Jeśli masz inną klasę, która wymaga tej funkcji, ale nie wymaga potrzeby implementacji interfejsu, możesz to zrobić elastycznie.

Istnieje również trzecia opcja: Kompozycja. Nie może mieć klasę abstrakcyjną w ogóle, ale raczej mają wiele konkretnych klas, które implementują interfejs korzystanie wspólny klasy pomocnika w ich realizacji:

class Helper { 
    /* ...shared methods... */ 
} 

class Concrete1 implements TheInterface { 
    /* ...uses instance of Helper */ 
} 

class Concrete1 implements TheInterface { 
    /* ...uses instance of Helper */ 
} 

ma to, że sama elastyczność, w innej formie.

1

Nie sądzę, że istnieje zasada kciuka jako taka. Podczas projektowania należy postępować zgodnie z zasadami SOLID, aby ustalić, czy to, co robisz, jest dobre czy złe. Możesz znaleźć te zasady ponad here. W tym konkretnym przypadku uważam, że powinieneś upewnić się, że przestrzegasz zasady otwartego zamknięcia.

0

Osobiście wolę stwierdzenie, że klasa abstrakcyjna jest tłem dla innych klas, więc jeśli trzy inne klasy mają coś wspólnego, ich wspólny przodek, klasa abstrakcyjna stworzona tylko dla tych trzech innych klas, powinna również dostarczyć kod z berło. To sprawiłoby, że klasa abstrakcyjna "kompletnie" (na swój sposób) zapewniała wszystkie te właściwości i metody, którymi dzielą się te trzy klasy.

Jednak ostatecznie nie ma znaczenia, czy wszystkie z nich zastosują ten sam interfejs. Tworzenie klas abstrakcyjnych, dających wszystko, co wspólne, jest według mnie bardziej klarownym sposobem. Łatwiej jest porównywać klasy, patrząc tylko na to, co się różni.

Powiązane problemy