Interfejs to 100% klasa abstrakcyjna, więc możemy użyć interfejsu do wydajnego programowania. Czy jest jakaś sytuacja, w której klasa abstrakcyjna jest lepsza niż interfejs?Potrzebujesz klasy abstrakcyjnej, a także interfejsu?
Odpowiedz
Klasy abstrakcyjne są wykorzystywane, gdy zamierzamy stworzyć konkretną klasę, ale chcesz się upewnić, że istnieje jakiś wspólny stan we wszystkich podklas lub ewentualna wspólna realizacjadla niektórych operacji.
Interfejsy nie mogą zawierać żadnego z nich.
Interfejs klasy abstrakcyjnej v/s to jeden z tematów, który generuje wiele ciekawostek/zainteresowań/dezorientacji dla każdego, kto jest nowicjuszem w Javie i chce pogłębić swoją wiedzę.
This article zawiera szczegółowe wyjaśnienie tematu.
Podany link był bardzo użyteczny. Daje jasne użycie zarówno abstrakcji, jak i interfejsu. – Warrior
Tak, istnieje miejsce zarówno dla klas abstrakcyjnych, jak i interfejsów.
Chodźmy konkretnym przykładem. Przyjrzymy się, jak utworzyć CheckingAccount
i SavingsAccount
z abstrakcji i zobaczyć, jak możemy użyć interfejsu odróżniającego dwa typy kont.
Aby rozpocząć, tutaj jest klasą abstrakcyjną AbstractBankAccount
:
abstract class AbstractBankAccount
{
int balance;
public abstract void deposit(int amount);
public abstract void withdraw(int amount);
}
Mamy saldo konta balance
jak i dwóch metod deposit
i withdraw
które muszą być wdrożone przez podklasy.
Jak widać, klasa abstrakcyjna deklaruje strukturę sposobu definiowania kont bankowych. Jak wspomina @Uri w swojej odpowiedzi, istnieje stan do tej abstrakcyjnej klasy, która jest polem balance
. Nie byłoby to możliwe dzięki interfejsowi.
Teraz niech podklasa AbstractBankAccount
dokonać CheckingAccount
class CheckingAccount extends AbstractBankAccount
{
public void deposit(int amount)
{
balance += amount;
}
public void withdraw(int amount)
{
balance -= amount;
}
}
W tej podklasy CheckingAccount
wdrożyliśmy dwie klasy abstrakcyjne - nic zbyt ciekawy tutaj.
Jak możemy wdrożyć SavingsAccount
? Różni się on od CheckingAccount
tym, że zyska zainteresowanie. Oprocentowanie może zostać zwiększone za pomocą metody deposit
, ale z drugiej strony nie jest to tak, jakby klient sam zdeponował zainteresowanie. Dlatego może być bardziej zrozumiałe, jeśli mamy inny sposób dodawania pieniędzy na konto, szczególnie w przypadku zainteresowania, na przykład, metodą accrueInterest
.
Mogliśmy bezpośrednio wdrożyć metodę w SavingsAccount
, ale możemy mieć więcej rodzajów kont bankowych, które mogą oprocentowane w przyszłości, więc możemy chcieć, aby interfejs InterestBearing
który ma metodę accrueInterest
:
interface InterestBearing
{
public void accrueInterest(int amount);
}
Więc teraz można zrobić klasę SavingsAccount
które mogą zyskać zainteresowanie poprzez wdrożenie interfejsu InterestBearing
:
class SavingsAccount extends AbstractBankAccount implements InterestBearing
{
public void deposit(int amount)
{
balance += amount;
}
public void withdraw(int amount)
{
balance -= amount;
}
public void accrueInterest(int amount)
{
balance += amount;
}
}
teraz, jeśli chcemy, aby anothe r typu konta, powiedzmy PremiumSavingsAccount
, możemy zrobić podklasę AbstractBankAccount
i wdrożyć interfejs InterestBearing
, aby utworzyć inne konto oprocentowane.
Interfejs InterestBearing
można zobaczyć jako , dodając wspólną funkcję do różnych klas. Nie miałoby sensu posiadanie funkcji do obsługi odsetek na kontach czekowych, gdy nie są naliczane odsetki.
Rzeczywiście istnieją miejsca, w których zarówno klasy abstrakcyjne, jak i interfejsy współistnieją i współpracują w jednej sytuacji.
Jeden więcej:
Jest artykuł na świecie Javy, która opisuje za pomocą klas interfejsu i abstrakcyjnych razem:
Ogólnie interfejsy opisać publicznych API, że kod należy użyć, mając na uwadze, że abstrakcyjne klasy bazowe najlepiej zachowywać jako szczegół wdrażania, w którym można zachować wspólny kod lub państwo, aby ograniczyć powielanie w dowolnych klasach wdrażania.
Korzystając z interfejsów w swoim interfejsie API, łatwiej jest napisać kod testowy na twoich klasach, ponieważ możesz używać klas testowych, które na przykład nie zależą od zewnętrznych zasobów lub wykazują jawne rodzaje złego, ale trudnego do symulacji zachowania w rzeczywistości.
Tak Java zapewnia interfejs listy, a AbstractList abstrakcyjnej klasy bazowej do „zminimalizować wysiłek potrzebny do wdrożenia” interfejs ...
Istnieje kilka powodów, dla których może wolisz klasy abstrakcyjnej implementacji darmo przez interfejs:
- Niektóre niemożliwe rzuty i operacje instanceof mogą zostać przechwycone podczas kompilacji.
- Istnieje możliwość dodania konkretnych metod w późniejszej wersji.
- Wiele lat temu istniała znacząca korzyść z wydajności.
- Z bardzo niejasnej perspektywy zabezpieczeń nie można uzyskać istniejącej klasy do implementacji metod, tworząc podklasę wcześniejszej klasy i klasy abstrakcyjnej.
Ale z drugiej strony, słowo kluczowe Java interfejsu umożliwia czystsze źródło.
Dziękuję pal. Podarowałeś mi cenne pomysły na moje zapytanie. – Warrior
- 1. Konstruktor - wzór bez abstrakcyjnej klasy/interfejsu
- 2. Dlaczego używać pustej klasy abstrakcyjnej zamiast interfejsu?
- 3. Jak zdecydujesz między używaniem abstrakcyjnej klasy a interfejsem?
- 4. Nie można utworzyć instancję klasy abstrakcyjnej lub interfejsu
- 5. Uszczelnianie klasy abstrakcyjnej lub interfejsu w klasie .NET
- 6. instancja klasy abstrakcyjnej
- 7. wirtualny desctructor na czystym abstrakcyjnej klasy bazowej
- 8. Uzyskaj wszystkie odziedziczone klasy ogólnej klasy abstrakcyjnej
- 9. Klasy przypadków dziedziczących z klasy abstrakcyjnej
- 10. Zastępowanie pól klasy abstrakcyjnej Java
- 11. Uzyskaj nazwę klasy betonu od klasy abstrakcyjnej
- 12. Deserializowanie klasy abstrakcyjnej w Gson
- 13. ForeignKey relacji do klasy abstrakcyjnej
- 14. Python - Testowanie abstrakcyjnej klasy bazowej
- 15. Korzystanie z metody abstrakcyjnej klasy
- 16. Dlaczego nie możemy utworzyć instancji interfejsu lub klasy abstrakcyjnej w języku Java bez metody anonimowej klasy?
- 17. Wyjątek NHibernate DuplicateMappingException podczas odwzorowywania klasy abstrakcyjnej i podklasy klasy abstrakcyjnej
- 18. Mix w abstrakcyjnej klasy i namedtuple
- 19. Jak wywołać metodę klasy abstrakcyjnej w java
- 20. Jak przedłużyć klasę enum z klasy abstrakcyjnej?
- 21. Używać klasy statycznej według interfejsu?
- 22. Usuwanie wszystko po znaku (a także znaków)
- 23. jQuery: Pobierz HTML, a także wartości wejściowe
- 24. Wskaźnik do abstrakcyjnej klasy bazowej szablonów?
- 25. C# Interfejs Dziedziczenie do klasy abstrakcyjnej
- 26. Tworzenie instancji klasy abstrakcyjnej lub anonimowej
- 27. Mocking abstrakcyjną klasę pochodną od klasy abstrakcyjnej
- 28. Używanie Moq do testowania abstrakcyjnej klasy
- 29. Błąd serializacji klasy abstrakcyjnej z doładowaniem
- 30. Nierozwiązany zewnętrzny (konstruktor klasy abstrakcyjnej/destruktor)
Będę nadal definiować interfejs, nawet jeśli definiujemy klasę abstrakcyjną. Dzięki temu Twój kod jest bardziej przyjazny dla testu i mniej powiązany z konkretną implementacją. – tvanfosson
Tak, oczywiście, zgadzam się na 100%. W moim kodzie zazwyczaj przypisuję interfejs do interfejsu (który brzmiał głupio) i używam klasy abstrakcyjnej jako podstawy dla standardowej implementacji i stanu. – Uri
Powiedziałeś: "i użyj klasy abstrakcyjnej jako podstawy standardowej implementacji i powiedz: Prawdopodobnie miałeś na myśli: " i użyj klasy abstrakcyjnej jako podstawy dla "wspólnej implementacji" i określ " – Shaw