2010-07-05 9 views
16

Postanowiłem rozpocząć samodzielne wykonywanie małych projektów kodowania, które koncentrują się na jakości kodu, a nie na ilości kodu i mają pytania dotyczące wykorzystania klas abstrakcyjnych.Korzyści z używania klas abstrakcyjnych w stosunku do zwykłej klasy

Teraz znam różnice między klasami abstrakcyjnymi a interfejsami z największym (jak sądzę) tym, że interfejs pozwala tylko definiować metody, które muszą być implementowane przez klasy za pomocą interfejsu i klas abstrakcyjnych, pozwalając na zdefiniowanie obu metod i członkowie wraz z domyślną implementacją metody, jeśli sobie tego życzą. Moje pytanie brzmi: jaka jest główna korzyść z zastosowania abstrakcyjnej klasy w porównaniu do normalnej klasy? Jedyną istotną różnicą między tymi dwoma rzeczami, które mogę wymyślić, jest to, że nie można utworzyć instancji klasy abstrakcyjnej. Czy są jakieś inne różnice między tymi dwoma?

+7

Czy spadkodawcy powinni podać przyczynę odrzucenia odpowiedzi?!?! – apollodude217

Odpowiedz

14

Ściśle od strony projektowej najlepiej jest uprościć wszystko. Uważam, że najlepszym sposobem na uproszczenie jest użycie prostej analogii. Użyjmy analogii ptaków ...

Interfejs: użyj tego, gdy chcesz wymusić określone funkcje, które wymagają zdefiniowania. na przykład IBird ma umowę na ScreamLikeABird i Fly (funkcje interfejsu). Ale możesz uzyskać bardziej szczegółowe i mieć IOstrich, który ma kontrakt Run. Możesz również mieć IHawk, który ma kontrakt na Atak ... itd.

Streszczenie: użyj tego, gdy chcesz wymusić funkcje podstawowe i mieć właściwości podstawowe. na przykład Ptak może być klasą podstawową dla ptaków, które mogą mieć funkcję zwaną LayEgg, a także proroctwa o nazwie Wiek, Gatunek, NumberOfChicks ... itd. Te rzeczy nie/nie powinny zmieniać zachowania ptaka, ponieważ wszystkie ptaki składają jaja ... itd. Ale nie wszystkie ptaki brzmią tak samo, kiedy krzyczą lub latają w ten sam sposób (niektórzy nawet nie latają) ... itd .... dlatego powinny być zaimplementowane za pośrednictwem interfejsu (interfejsów).

+26

-1 dla mylących i niepraktycznych analogii zwierząt. –

+6

Zastosowano niepraktyczną analogię ze zwierzętami, aby pomóc w rozwiązaniu problemu "interfejsu z abstrakcją". BTW, jak niepraktyczne jest jakiekolwiek wydawanie Hello World? Praktyczność nie ma z tym nic wspólnego. Poza tym, widzę analogię, która jest niezwykle praktyczna w wielu aplikacjach i/lub grach. – AlvinfromDiaspar

+0

@AlvinfromDiaspar +1 Cóż, myślę, że jest to najprostsze wyjaśnienie na świecie. – Rohit

-2

Klasy abstrakcyjne mogą być używane do przechowywania metod w opartej na OOP "bibliotece"; ponieważ klasy nie trzeba tworzyć instancji i nie miałoby to większego sensu, utrzymywanie wspólnych metod statycznych wewnątrz klasy abstrakcyjnej jest powszechną praktyką.

+0

"W Javie możesz również zadeklarować klasę jako ostateczną, więc nie można jej rozszerzyć." Nie, nie możesz. 'abstract' +' final' nie jest dozwolone. Jeśli twoja klasa jest przeznaczona wyłącznie dla statycznych metod użyteczności, prawdopodobnie powinna to być klasa ostateczna z prywatnym (nieużywanym) konstruktorem. –

+0

@Matthew Flaschen: Punkt wzięty. Dziękuję za wyjaśnienie. – amphetamachine

+1

Metody statyczne nie są głównym powodem zajęć abstrakcyjnych. – apollodude217

8

Oprócz niemożności tworzenia wystąpień klas abstrakcyjnych, niektóre języki mogą obsługiwać metody abstrakcyjne w klasach abstrakcyjnych - podobnie jak w przypadku interfejsów, metoda abstrakcyjna będzie musiała zostać zaimplementowana przez klasę dziedziczącą z klasy abstrakcyjnej.

Główną zaletą klas abstrakcyjnych moim zdaniem jest to, że istnieje kod, który musi być dzielony między klasami tego samego typu. Zwykle można użyć do tego interfejsu, ale czasami funkcjonalność takich klas może się pokrywać, a skończy się powielaniem kodu. W takim przypadku możesz użyć klasy abstrakcyjnej i po prostu umieścić tam kod.

+3

+1, aby uzyskać prawidłową, krótką odpowiedź. – apollodude217

+0

Nawet jeśli klasa nie ma żadnych abstrakcyjnych członków, a utworzone wystąpienia mają dobrze zdefiniowane zachowanie, może być sensowne zdefiniowanie klasy jako abstrakcyjnej, jeśli nie zawiera ona niczego, co odróżniłoby instancje od siebie. Na przykład, można zdefiniować '' ImmutableList klasę bazową z podklasy dla 'ArrayBackedImmutableList ', 'ComputedImmutableList ', '' LazyImmutableList itd Chociaż może to być możliwe, że instancje klasy bazowej zachowywać się jak zero pozycji lista, byłoby czystsze zdefiniowanie konkretnej klasy 'EmptyImmutableList ' w tym celu. – supercat

-1

To może pomóc, Pozwala rozważyć podróżnik, który może wykorzystać każdy rodzaj samochodu, czyli pojazd cyklu, rower itp ...
ale wszystkie pojazdy porusza się w taki sam sposób, z różnymi ograniczeniami prędkości, dzięki czemu możemy mieć jeden

abstract class Avehicle  
{ 
     string fuel; 
     public void move() 
{ 
sysout("moving"); 
} 
} 

ale wszystkie pojazdy systemu łamanie różni

interface Ivehicle  
{ 

     public void breakorstop(); 
} 
class Traveler  
{ 
    Ivehicle v; 
//Settrers and getters 
public drive() 
{ 
v.move(); 
} 
public break() 
{ 
v.breakorstop(); 
} 
} 

Więc wreszcie samochodów lub zajęcia rowerowe lub rowerowe mogą przedłużyć Avehicle i może implementować Vehicl Interfejs e:

6

W świecie OO abstrakcyjne klasy używane do narzucania pewnych ograniczeń implementacji projektu &. Nic więcej. W żadnym wypadku nie musisz używać klas abstrakcyjnych. Ale mogą istnieć przypadki, w których lepiej narzucić te ograniczenia. Więc czym one są?Spójrzmy na to porównując jego odpowiedniki z oo.

Klasy abstrakcyjne vs interfejsy

Jak wiadomo, są to dwa z podstawowych pojęć dziedziczenia.

Zasadniczo interfejs służy tylko do deklarowania, że ​​chcesz odziedziczyć podstawową usługę i to wszystko. Nie zawiera implementacji & nie ma funkcjonalności. W tym sensie interfejs jest abstrakcyjny. Dlatego jest to bardziej ograniczenie projektowe niż ograniczenie implementacyjne. Pomyśl o gniazdku słuchawkowym na głośniku. Każde wyjście słuchawkowe musi zaimplementować interfejs jack (z funkcjami start, stop, listen, turnDown, turnup). Każde wyjście słuchawkowe powinno zastąpić ten interfejs, aby dziedziczyć funkcje, które zapewnia i odpowiednio implementuje głośnik.

Klasy abstrakcyjne, z drugiej strony, mogą zawierać metody z implementacją. To podstawowa różnica iw tym sensie może wykorzystywać więcej niż interfejs. Ponadto mogą zawierać prywatne, chronione niestatyczne pola, których nie można uzyskać za pośrednictwem interfejsów. Możesz wymusić na podklasach implementację niektórych niezbędnych funkcji za pomocą metod abstrakcyjnych (bez implementacji). Klasy abstrakcyjne bardziej zwinne niż interfejsy.

Oczywiście nie wspominając o tym, że można rozszerzyć tylko jedną klasę w języku Java, w której można implementować wiele interfejsów.

Klasy abstrakcyjne vs regularne zajęcia

Więc dlaczego nie użyć regularne zajęcia czasu. Jaka jest korzyść z używania klasy abstrakcyjnej? To jest całkiem proste. Jeśli używasz klas abstrakcyjnych, wymuszasz implementację podstawowej funkcjonalności przez rodzeństwo. Jako programista nie musisz pamiętać, że powinieneś wdrożyć podstawowe funkcje. To tutaj klasy abstrakcyjne nakładają ograniczenia projektowe na zwykłe klasy. Dodatkowo, tworząc streszczenie klasy, unikasz tej (niepełnej) klasy, która ma zostać utworzona przypadkowo.

+0

Przez ** rodzeństwo ** masz na myśli dziecko, biorąc pod uwagę, że streszczenie zostanie odziedziczone po klasie, która uczyni ją rodzicem. Dobrze ? –

+0

@DaniyalNasir tak. – zgulser

0

Klasy abstrakcyjne a regularne klasy kontra interfejsy. Klasa abstrakcyjna zwykle wspiera ideę uogólniania i wkładu od programistów, aby utrzymać dość małą ilość disipline dla mózgu, projektując wieloletnie projekty, ponieważ zawierają one abstrakcyjne metody, które muszą opisywać implementację metod abstrakcyjnych w podnoszeniu klas. ta funkcja jest wadą dla projektów krótkoterminowych, gdy deweloper ma zeitnot.

0

Jedynym powodem deklarowania klasy jako abstrakcyjnej jest to, że nie można jej utworzyć. Są sytuacje, w których będziesz mieć wspólną funkcjonalność, która jest współdzielona przez wiele klas, ale sama przez się, że wspólna funkcjonalność nie reprezentuje obiektu lub reprezentuje niekompletny obiekt. W takim przypadku definiujesz wspólną funkcję jako streszczenie, aby nie można było utworzyć instancji.

+0

Co jest nie tak? –

1

Moim zdaniem klasy abstrakcyjne mają więcej zastosowań w prawdziwych projektach niż w książkach. czasami menedżerowie projektów po prostu dostarczają deklarację metod i trzeba napisać kod dla metod bez modyfikacji podstawowej składni zapewnianej przez menedżera. tak więc klasa abstrakcyjna jest pełna. w prostej metodzie klasy zdefiniuj, zadeklaruj i zakoduj w tym samym czasie, ale nie w klasach abstrakcyjnych. na przykład: -

abstract class Test 
{ 
    abstract void show();//method provided 
} 
class Child extends Test 
{ 
    void show()//coding 
    { 
     System.out.println("saurav"); 
    } 
} 
class main 
{ 
    public static void main(String[] args) 
    { 
    Test c = new Child(); 
    c.show(); 
    } 
} 
Powiązane problemy