Jaka jest różnica między interfejsem a klasą abstrakcyjną?


1753

Jaka jest dokładnie różnica między interfejsem a klasą abstrakcyjną?


96
To jest bardzo częste pytanie podczas wywiadu. To zaskakujące, ponieważ klasa abstrakcyjna jest rzadko używana w rozwiązaniach w porównaniu do innych rzeczy. Twoje pytanie pomogło mi Safraz.
Catto

5
To pytanie może również pomóc w zrozumieniu koncepcji interfejsów stackoverflow.com/q/8531292/1055241
gprathour

6
Usunąłem tag PHP z tego pytania, ponieważ prawie żadna z odpowiedzi nie jest specyficzna dla języka, a samo pytanie nie jest specyficzne dla języka.
Brice

2
kiedyś w c ++ interfejs jest czystą abstrakcyjną klasą bazową ze wszystkimi implementacjami metod = 0. Jeśli pojedyncza metoda nie była = 0, to ma implementację, a podstawa abstrakcyjna nie jest już czysta i nie jest już interfejsem . Myślę, że VMT ma mniejszą pośredniość, gdy wielokrotne dziedziczenie używa tylko czystych abstrakcyjnych zasad, ale nie pamiętam, jak wyglądają, były zbyt długie.
Jim

Odpowiedzi:


2255

Interfejsy

Interfejs to umowa : osoba pisząca interfejs mówi: „ hej, akceptuję rzeczy wyglądające w ten sposób ”, a osoba korzystająca z interfejsu mówi „ OK, klasa, którą piszę, wygląda w ten sposób ”.

Interfejs jest pustą powłoką . Są tylko sygnatury metod, co oznacza, że ​​metody nie mają ciała. Interfejs nic nie może zrobić. To tylko wzór.

Na przykład (pseudo kod):

// I say all motor vehicles should look like this:
interface MotorVehicle
{
    void run();

    int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

    int fuel;

    void run()
    {
        print("Wrroooooooom");
    }


    int getFuel()
    {
        return this.fuel;
    }
}

Wdrożenie interfejsu zużywa bardzo mało procesora, ponieważ nie jest to klasa, tylko kilka nazw, a zatem nie trzeba wykonywać żadnych kosztownych przeglądów. Jest świetny, gdy ma to znaczenie, na przykład w urządzeniach osadzonych.


Klasy abstrakcyjne

Klasy abstrakcyjne, w przeciwieństwie do interfejsów, są klasami. Są one droższe w użyciu, ponieważ istnieje dziedzina, w której można je odziedziczyć.

Klasy abstrakcyjne przypominają interfejsy, ale mają coś więcej: możesz zdefiniować dla nich zachowanie. Chodzi raczej o osobę, która mówi: „ te klasy powinny tak wyglądać i mają to wspólne, więc wypełnij puste pola! ”.

Na przykład:

// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

    int fuel;

    // They ALL have fuel, so lets implement this for everybody.
    int getFuel()
    {
         return this.fuel;
    }

    // That can be very different, force them to provide their
    // own implementation.
    abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
    void run()
    {
        print("Wrroooooooom");
    }
}

Realizacja

Podczas gdy abstrakcyjne klasy i interfejsy mają być różnymi pojęciami, implementacje powodują, że to stwierdzenie jest czasami nieprawdziwe. Czasami nie są nawet tym, czym myślisz, że są.

W Javie ta zasada jest silnie egzekwowana, podczas gdy w PHP interfejsy są klasami abstrakcyjnymi bez zadeklarowanej metody.

W Pythonie klasy abstrakcyjne są bardziej sztuczką programistyczną, którą można uzyskać z modułu ABC i faktycznie używa metaklas, a zatem klas. Interfejsy są bardziej związane z pisaniem kaczek w tym języku i jest to połączenie konwencji i specjalnych metod wywołujących deskryptory (metody __method__).

Jak zwykle w przypadku programowania, istnieje teoria, praktyka i praktyka w innym języku :-)


6
Kluczową kwestią dotyczącą interfejsów nie jest to, że mówią one, co robi klasa, ale pozwalają obiektom, które mogą Wizzle, przydać się w kodzie, który potrzebuje Wizzlera. Zauważ, że w wielu przypadkach ani osoba, która napisze coś, co potrafi Wizzle, ani osoba, która potrzebuje Wizzlera, nie będzie osobą, która napisze interfejs.
supercat

187
Nie sądzę, aby zużycie procesora było najważniejszym punktem interfejsów.
Dan Lugg,

5
@ e-satis Czy możesz wyjaśnić swoje zdanie na temat wykorzystania procesora? Dlaczego klasa abstrakcyjna będąca klasą zwiększa wykorzystanie procesora? Do jakiego rodzaju odnośnika tu chodzi?
Geek

36
@ e-satis W Javie 8 można zdefiniować domyślne metody w interfejsach, co jest równoważne z posiadaniem metod nieabstrakcyjnych w klasach abstrakcyjnych. Dzięki temu dodatkowi nie widzę już prawdziwej różnicy między klasami abstrakcyjnymi a interfejsem, poza tym, że powinienem używać interfejsów, ponieważ klasy mogą implementować wiele interfejsów, ale mogą dziedziczyć tylko jedną klasę
Ogen

23
Wydaje mi się, że porównanie między interfacei classod Head First Javajest bardzo wyraźneA class defines who you are, and an interface tells what roles you could play
LittleLittleQ

872

Kluczowe różnice techniczne między klasą abstrakcyjną a interfejsem to:

  • Klasy abstrakcyjne mogą mieć stałe, elementy, kody pośredniczące metod (metody bez treści) i zdefiniowane metody , podczas gdy interfejsy mogą mieć tylko stałe i kody pośredniczące metod .

  • Metody i elementy klasy abstrakcyjnej można zdefiniować z dowolną widocznością , podczas gdy wszystkie metody interfejsu należy zdefiniować jako public(domyślnie są one zdefiniowane jako publiczne).

  • Dziedzicząc klasę abstrakcyjną, konkretna klasa potomna musi zdefiniować metody abstrakcyjne , podczas gdy klasa abstrakcyjna może rozszerzać inną klasę abstrakcyjną, a metody abstrakcyjne z klasy nadrzędnej nie muszą być definiowane.

  • Podobnie interfejs rozszerzający inny interfejs nie jest odpowiedzialny za implementację metod z interfejsu nadrzędnego. Wynika to z faktu, że interfejsy nie mogą zdefiniować żadnej implementacji.

  • Klasa podrzędna może rozszerzyć tylko jedną klasę (abstrakcyjną lub konkretną), podczas gdy interfejs może zostać rozszerzony lub klasa może zaimplementować wiele innych interfejsów .

  • Klasa potomna może definiować metody abstrakcyjne z taką samą lub mniej restrykcyjną widocznością , podczas gdy klasa implementująca interfejs musi definiować metody z dokładnie taką samą widocznością (publiczna).


123
myślę, że jest to najlepsza odpowiedź, ponieważ podkreśla wszystkie kluczowe różnice. przykład nie jest tak naprawdę konieczny.
Joshua K,

4
I zwykle za pomocą klas można utworzyć z niego obiekt, w przeciwieństwie do klas abstrakcyjnych, które CANNOTsą tworzone.
SASM,

Myślałem, że klasa, która implementuje interfejs, musi zdefiniować wszystkie metody interfejsu?
Użytkownik Jiazzy

@Jiazzyuser Jeśli klasa abstrakcyjna implementuje interfejs, nie musi tak naprawdę definiować metod interfejsu. Wymóg ten można odroczyć do dziedziczenia / potomnych klas betonowych. Jednak konkretna klasa musi implementować wszystkie metody interfejsu, które nie są zaimplementowane przez jej klasę nadrzędną. Dodam przykład, aby zilustrować ten punkt.
Justin Johnson

5
„Podczas dziedziczenia klasy abstrakcyjnej klasa potomna musi zdefiniować metody abstrakcyjne, podczas gdy interfejs może rozszerzyć inny interfejs i metod nie trzeba definiować.” - To nie jest prawda. Tak jak interfejs może rozszerzyć interfejs bez definiowania metod, tak klasa abstrakcyjna może dziedziczyć klasę abstrakcyjną bez definiowania metod.
Nick

141

Interfejs zawiera tylko definicję / podpis funkcji, a jeśli mamy jakąś wspólną funkcjonalność, a także wspólne podpisy, musimy użyć klasy abstrakcyjnej. Używając klasy abstrakcyjnej, możemy zapewnić zarówno zachowanie, jak i funkcjonalność jednocześnie. Inny programista dziedziczący klasę abstrakcyjną może z łatwością korzystać z tej funkcji, ponieważ musiałby jedynie wypełnić puste pola.

wprowadź opis zdjęcia tutaj Pochodzą z:

http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html

http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.html http://www.dotnetbull.com/2011/11/what-is-interface-in -c-net.html


17
Musisz powiedzieć, do jakiego języka się to odnosi („Klasa abstrakcyjna nie obsługuje wielokrotnego dziedziczenia” jest daleka od uniwersalności)
Ben Voigt

Ostatnie porównanie jest mylące jak na tabelę! Metody w interfejsie nie mogą być statyczne, ale zmienne są statyczne końcowe Zaimplementowane metody w klasie abstrakcyjnej mogą być statyczne
realPK

8
Element interfejsu musi być statyczny końcowy. Ostatnie stwierdzenie jest nieprawidłowe.
Jawad Zeb

Myślę, że „funkcjonalność” w tej odpowiedzi oznacza „wdrożenie”. Nie wiesz, co oznacza „zachowanie” - może „podpisy”?
LarsH

2
Jaki jest tutaj docelowy język programowania? DO#?
Peter Mortensen,

80

Wyjaśnienie można znaleźć tutaj: http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm

Klasa abstrakcyjna to klasa, która jest tylko częściowo implementowana przez programistę. Może zawierać jedną lub więcej metod abstrakcyjnych. Metoda abstrakcyjna jest po prostu definicją funkcji, która informuje programistę, że metoda musi zostać zaimplementowana w klasie potomnej.

Interfejs jest podobny do klasy abstrakcyjnej; w rzeczywistości interfejsy zajmują tę samą przestrzeń nazw co klasy i klasy abstrakcyjne. Z tego powodu nie można zdefiniować interfejsu o tej samej nazwie co klasa. Interfejs jest w pełni abstrakcyjną klasą; żadna z jego metod nie jest zaimplementowana i zamiast podklasy klas, mówi się, że implementuje ten interfejs.

W każdym razie to wyjaśnienie interfejsów jest nieco mylące. Częstszą definicją jest: Interfejs definiuje umowę, którą muszą spełniać klasy implementujące. Definicja interfejsu składa się z podpisów członków publicznych, bez żadnego kodu implementującego.


4
Jest to najbardziej poprawna odpowiedź, ponieważ interfejsy PHP różnią się od innych języków tym, że interfejsy PHP SĄ abstrakcyjnymi klasami pod maską, podczas gdy interfejsy innych języków są sygnaturami, które klasy muszą pasować. Zachowują się tak samo, dopóki nie ma błędów.
Tor Valamo,

1
To prawda, że ​​dla PHP jest to najlepsza odpowiedź. Ale trudniej jest uzyskać z obiektu blob tekstowego niż z prostego fragmentu kodu.
e-satis,

Z podanych przez ciebie definicji wyglądają tak samo, z wyjątkiem jednego szczegółu: interfejs jest w 100% abstrakcyjny, podczas gdy klasa abstrakcyjna jest częściowo abstrakcyjna i może mieć pewne implementacje metod (być może wszystkie metody mogą mieć implementacje?).
jww

41

Nie chcę podkreślać różnic, które zostały już powiedziane w wielu odpowiedziach (dotyczących publicznych statycznych modyfikatorów końcowych dla zmiennych w interfejsie i obsługi chronionych, prywatnych metod w klasach abstrakcyjnych)

W prostych słowach chciałbym powiedzieć:

interfejs: Aby wdrożyć umowę przez wiele niepowiązanych obiektów

Klasa abstrakcyjna: Aby zaimplementować to samo lub inne zachowanie wśród wielu powiązanych obiektów

Z dokumentacji Oracle

Rozważ użycie klas abstrakcyjnych, jeśli:

  1. Chcesz dzielić kod między kilkoma blisko spokrewnionymi klasami.
  2. Oczekujesz, że klasy, które rozszerzają twoją klasę abstrakcyjną, mają wiele wspólnych metod lub pól lub wymagają modyfikatorów dostępu innych niż publiczne (takie jak chronione i prywatne).
  3. Chcesz zadeklarować pola niestatyczne lub nie-końcowe.

Rozważ użycie interfejsów, jeśli:

  1. Oczekujesz, że niepowiązane klasy zaimplementują Twój interfejs. Na przykład wiele niepowiązanych obiektów może implementować Serializableinterfejs.
  2. Chcesz określić zachowanie określonego typu danych, ale nie przejmuj się tym, kto wdraża to zachowanie.
  3. Chcesz skorzystać z wielokrotnego dziedziczenia typu.

Klasa abstrakcyjna ustanawia „jest” relacją z konkretnymi klasami. interfejs zapewnia możliwość „klas” dla klas.

Jeśli szukasz Javajako języka programowania, oto kilka innych aktualizacji:

Java 8 w pewnym stopniu zmniejszyła lukę między klasami interfacei abstractudostępniając funkcję defaultmetody. Interfejs nie ma implementacji dla metody, która nie jest już poprawna.

Więcej informacji można znaleźć na tej stronie dokumentacji .

Spójrz na to pytanie SE, aby znaleźć przykłady kodu, aby lepiej zrozumieć.

Jak powinienem wyjaśnić różnicę między interfejsem a klasą abstrakcyjną?


38

Kilka ważnych różnic:

W formie tabeli:

Różnica

Jak stwierdził Joe z javapapers :

1. Główna różnica polega na tym, że metody interfejsu Java są domyślnie abstrakcyjne i nie mogą mieć implementacji. Klasa abstrakcyjna Java może mieć metody instancji, które implementują domyślne zachowanie.

2. Zmienne zadeklarowane w interfejsie Java są domyślnie ostateczne. Klasa abstrakcyjna może zawierać nie-końcowe zmienne.

3. Członkowie interfejsu Java są domyślnie publiczni. Klasa abstrakcyjna Java może mieć zwykłe smaki członków klasy, takie jak prywatny, chroniony itp.

4. Interfejs Java powinien zostać zaimplementowany przy użyciu słowa kluczowego „implements”; Klasa abstrakcyjna Java powinna zostać rozszerzona za pomocą słowa kluczowego „extends”.

5. Interfejs może rozszerzyć tylko inny interfejs Java, klasa abstrakcyjna może rozszerzyć inną klasę Java i zaimplementować wiele interfejsów Java.

6. Klasa Java może implementować wiele interfejsów, ale może rozszerzać tylko jedną klasę abstrakcyjną.

7. Interfejs jest absolutnie abstrakcyjny i nie można go tworzyć; Nie można również utworzyć instancji klasy abstrakcyjnej Java, ale można ją wywołać, jeśli istnieje main ().

8. W porównaniu z klasami abstrakcyjnymi Java, interfejsy Java są wolne, ponieważ wymaga dodatkowej pośredniczenia.


3
Zredagowałem twoją odpowiedź, aby zapewnić prawidłowe uznanie. Nie możesz po prostu upuścić linku na dole odpowiedzi. Musisz również zacytować cały język, który został skopiowany z innego źródła. Ponadto, jeśli ta tabela została narysowana, należy wyraźnie wskazać, skąd ona pochodzi.
Brad Larson

Proszę również wspomnieć o C ++ .. chociaż w C ++ nie ma słowa kluczowego „interfejs”, ale jest to również często zadawane pytanie o Cn regd C ++.
cbinder

@ cbinder: W c ++ nie ma słowa kluczowego „interfejs”. Różnice w c ++ znajdują się w 1. tutorialspoint.com/cplusplus/cpp_interfaces.htm 2. tutorialspoint.com/cplusplus/cpp_interfaces.htm
softmage99

@MageshBabu Być może zdefiniowanie funkcji w klasie zawierającej czystą funkcję wirtualną czyni z niej klasę abstrakcyjną, a nie interfejs
cbinder

2
W Javie 8 różnice są teraz mniejsze. Sprawdź zaktualizowane różnice tutaj: journaldev.com/1607/…
Pankaj

31

Najważniejsze jest to, że:

  • Streszczenie jest zorientowane obiektowo . Oferuje podstawowe dane, które powinien posiadać „obiekt” i / lub funkcje, które powinien być w stanie wykonać. Dotyczy podstawowych cech obiektu: tego, co ma i co może zrobić. Zatem obiekty dziedziczące z tej samej klasy abstrakcyjnej mają podstawowe cechy (uogólnienie).
  • Interfejs jest zorientowany na funkcjonalność . Definiuje funkcje, które powinien mieć obiekt. Bez względu na to, jaki to obiekt, o ile jest on w stanie wykonywać funkcje zdefiniowane w interfejsie, jest w porządku. Ignoruje wszystko inne. Obiekt / klasa może zawierać kilka (grup) funkcji; dlatego klasa może implementować wiele interfejsów.

Dziękujemy, teraz docieramy gdzieś z dobrą reakcją wysokiego poziomu. Zabawne, jak daleko w głąb komentarzy musisz znaleźć odpowiedź bardziej opartą na zrozumieniu.
Andrew

1
Pozostałe odpowiedzi są zbyt techniczne. To zmierza ku temu, co uważam za „właściwą” odpowiedź. Cały sens OOP dotyczy semantyki i to, czy prywatne klasy zagnieżdżone są wywoływane przez procesory kosztowne wyszukiwania, nie ma tutaj znaczenia
Sentinel

26

Jeśli chcesz zapewnić zachowanie polimorficzne w hierarchii dziedziczenia, użyj klas abstrakcyjnych.

Jeśli chcesz zachować zachowanie polimorficzne dla klas, które są całkowicie niezwiązane, użyj interfejsu.


24

Buduję budynek o 300 piętrach

Interfejs projektu budynku

  • Na przykład Servlet (I)

Budynek zbudowany do 200 pięter - częściowo ukończony --- streszczenie

  • Częściowa implementacja, na przykład serwlet ogólny i HTTP

Konstrukcja budynku zakończona - beton

  • Pełna implementacja, na przykład własny serwlet

Berło

  • Nic nie wiemy o implementacji, tylko wymagania. Możemy wybrać interfejs.
  • Każda metoda jest domyślnie publiczna i abstrakcyjna
  • Jest to w 100% czysta klasa abstrakcyjna
  • Jeśli ogłaszamy się publicznie, nie możemy zadeklarować, że są prywatne i chronione
  • Jeśli zadeklarujemy streszczenie, nie możemy zadeklarować wersji ostatecznej, statycznej, zsynchronizowanej, ścisłej i rodzimej
  • Każdy interfejs ma publiczny, statyczny i końcowy
  • Serializacja i przejściowe nie ma zastosowania, ponieważ nie możemy utworzyć instancji dla interfejsu
  • Nielotna, ponieważ jest ostateczna
  • Każda zmienna jest statyczna
  • Kiedy deklarujemy zmienną w interfejsie, musimy inicjalizować zmienne podczas deklarowania
  • Instancja i blok statyczny są niedozwolone

Abstrakcyjny

  • Częściowe wdrożenie
  • Ma abstrakcyjną metodę. Dodatek wykorzystuje beton
  • Brak ograniczeń dla abstrakcyjnych modyfikatorów metod klasy
  • Brak ograniczeń dla abstrakcyjnych modyfikatorów zmiennych klas
  • Nie możemy deklarować innych modyfikatorów oprócz abstrakcyjnych
  • Brak ograniczeń inicjalizacji zmiennych

Zaczerpnięte ze strony internetowej DurgaJobs


Klasa abstrakcyjna może mieć konstruktor
vimal krishna

4
Całkowicie nie zgadzam się z tym poglądem. Plan jest zupełnie inną koncepcją niż „interfejs”. Plan jest bardziej analogiczny do modelu statycznego lub specyfikacji projektowej dla konkretnej implementacji. Jest bliżej „klasy”, ponieważ plan może być wielokrotnie tworzony za pomocą swojego konstruktora, ale nawet to nie jest wystarczająco blisko, ponieważ „klasa” zawiera również specyfikację budowy (ctor) oraz środki do wykonania więc. Interfejs jako koncepcja ma reprezentować pewne zachowania, takie jak podgrzewanie / ochładzanie, które można zastosować do różnych rzeczy, np .: budynków, pieców itp.
Sentinel,

18

Ponownie popracujmy nad tym pytaniem:

Pierwszą rzeczą, którą należy poinformować, jest to, że wyniki 1/1 i 1 * 1 dają to samo, ale nie oznacza to, że mnożenie i dzielenie są takie same. Oczywiście utrzymują dobre relacje, ale pamiętajcie, że oboje jesteście inni.

Wskażę główne różnice, a pozostałe zostały już wyjaśnione:

Klasy abstrakcyjne są przydatne do modelowania hierarchii klas. Na pierwszy rzut oka na każde wymaganie, częściowo wiemy, co dokładnie ma być zbudowane, ale wiemy, co zbudować. Tak więc twoje abstrakcyjne klasy są twoimi klasami podstawowymi.

Interfejsy są przydatne, aby umożliwić innym hierarchom lub klasom wiedzieć, co jestem w stanie zrobić. A kiedy mówisz, że jestem zdolny do czegoś, musisz mieć taką zdolność. Interfejsy oznaczą to jako obowiązkowe, aby klasa mogła wdrożyć te same funkcje.


2
Dobra odpowiedź, ale metafora matematyczna jest bezużyteczna i zmarnowałam mniej więcej tyle samo czasu czytając ją, pisząc ten komentarz. Teraz pomnóż to przez wszystkie inne osoby, które przeczytały to pytanie.
Andrew

„metafora matematyki jest bezużyteczna”, dlaczego tak myślisz?
Dhananjay,

12

Właściwie to całkiem proste.

Możesz myśleć o interfejsie jako o klasie, która może mieć tylko abstrakcyjne metody i nic więcej.

Interfejs może więc tylko „zadeklarować” i nie definiować zachowania, które ma mieć klasa.

Klasa abstrakcyjna pozwala zarówno zadeklarować (przy użyciu metod abstrakcyjnych), jak i zdefiniować (przy użyciu pełnych implementacji metod) zachowanie, które ma mieć klasa.

A zwykła klasa pozwala tylko definiować, a nie deklarować zachowanie / działania, które ma mieć klasa.

Ostatnia rzecz,

W Javie możesz zaimplementować wiele interfejsów, ale możesz rozszerzyć tylko jeden (Klasa abstrakcyjna lub Klasa) ...

Oznacza to, że dziedziczenie zdefiniowanego zachowania jest ograniczone, aby zezwolić tylko na jedną na klasę ... tzn. Jeśli chciałbyś, aby klasa obejmowała zachowanie z klas A, B i C, musisz wykonać następujące czynności: Klasa A rozszerza B, klasa C rozszerza A. to trochę okrągły sposób na wielokrotne dziedziczenie ...

Z drugiej strony interfejsy można po prostu zrobić: interfejs C implementuje A, B

W efekcie Java obsługuje wielokrotne dziedziczenie tylko w „zadeklarowanym zachowaniu”, tj. Interfejsach, i tylko pojedyncze dziedziczenie ze zdefiniowanym zachowaniem. O ile nie zrobisz tego w sposób opisany ...

Mam nadzieję, że to ma sens.


11

Porównanie interfejsu z klasą abstrakcyjną jest nieprawidłowe. Zamiast tego powinny być dwa inne porównania: 1) interfejs vs. klasa i 2) abstrakcja vs. klasa ostateczna .

Interfejs a klasa

Interfejs to umowa między dwoma obiektami. Np. Jestem listonoszem, a ty paczką do dostarczenia. Oczekuję, że znasz swój adres dostawy. Kiedy ktoś daje mi Paczkę, musi znać jej adres dostawy:

interface Package {
  String address();
}

Klasa to grupa obiektów zgodnych z umową. Np. Jestem skrzynką z grupy „Box” i przestrzegam kontraktu wymaganego przez Listonosza. Jednocześnie przestrzegam innych umów:

class Box implements Package, Property {
  @Override
  String address() {
    return "5th Street, New York, NY";
  }
  @Override
  Human owner() {
    // this method is part of another contract
  }
}

Streszczenie kontra finał

Klasa abstrakcyjna to grupa niekompletnych obiektów. Nie można ich użyć, ponieważ brakuje niektórych części. Na przykład jestem abstrakcyjnym pudełkiem obsługującym GPS - wiem, jak sprawdzić swoją pozycję na mapie:

abstract class GpsBox implements Package {
  @Override
  public abstract String address();
  protected Coordinates whereAmI() {
    // connect to GPS and return my current position
  }
}

Ta klasa, jeśli zostanie odziedziczona / rozszerzona przez inną klasę, może być bardzo przydatna. Ale sam w sobie - jest bezużyteczny, ponieważ nie może mieć przedmiotów. Klasy abstrakcyjne mogą być elementami budującymi klasy końcowe.

Ostateczna klasa to grupa kompletnych obiektów, których można używać, ale nie można ich modyfikować. Wiedzą dokładnie, jak pracować i co robić. Na przykład jestem skrzynką, która zawsze idzie na adres podany podczas jej budowy:

final class DirectBox implements Package {
  private final String to;
  public DirectBox(String addr) {
    this.to = addr;
  }
  @Override
  public String address() {
    return this.to;
  }
}

W większości języków, takich jak Java lub C ++, można mieć tylko klasę , ani abstrakcyjnej, ani końcowej. Taką klasę można odziedziczyć i utworzyć jej instancję. Nie sądzę jednak, aby było to ściśle zgodne z paradygmatem obiektowym.

Ponownie porównanie interfejsów z klasami abstrakcyjnymi jest nieprawidłowe.


9

W skrócie różnice są następujące:

Różnice składniowe między interfejsem a klasą abstrakcyjną :

  1. Metody i członkowie klasy abstrakcyjnej mogą mieć dowolną widoczność. Wszystkie metody interfejsu muszą być publiczne . // Nie jest już prawdą w Javie 9
  2. Konkretna klasa potomna klasy abstrakcyjnej musi definiować wszystkie metody abstrakcyjne. Klasa potomna Abstrakcja może mieć metody abstrakcyjne. interfejs rozszerzenie interfejsu nie inną potrzebę zapewnienia domyślną implementację metod odziedziczonych z interfejsu nadrzędnego.
  3. Klasa podrzędna może rozszerzyć tylko jedną klasę. interfejs może przedłużyć wiele interfejsów. Klasa może implementować wiele interfejsów.
  4. Klasa potomna może definiować metody abstrakcyjne z taką samą lub mniej restrykcyjną widocznością, podczas gdy klasa implementująca interfejs musi zdefiniować wszystkie metody interfejsu jako publiczne.
  5. Klasy abstrakcyjne mogą mieć konstruktory, ale nie interfejsy .
  6. Interfejsy Java 9 mają prywatne metody statyczne.

Teraz w interfejsach:

public static- obsługiwane - obsługiwane
public abstract- obsługiwane
public default- obsługiwane
private static- obsługiwane
private abstract- błąd
private defaultkompilacji
private- błąd kompilacji - obsługiwane


8

Jedyna różnica polega na tym, że jeden może uczestniczyć w wielokrotnym dziedziczeniu, a drugi nie.

Definicja interfejsu zmieniła się z czasem. Czy uważasz, że interfejs ma tylko deklaracje metod i są tylko umowami? Co ze statycznymi zmiennymi końcowymi, a co z definicjami domyślnymi po Javie 8?

Interfejsy zostały wprowadzone do Javy ze względu na problem diamentów z wielokrotnym dziedziczeniem i właśnie to zamierzają zrobić.

Interfejsy to konstrukcje utworzone w celu uniknięcia problemu wielokrotnego dziedziczenia, które mogą zawierać metody abstrakcyjne, definicje domyślne i statyczne zmienne końcowe.

Zobacz Dlaczego Java zezwala na statyczne zmienne końcowe w interfejsach, skoro mają one być jedynie kontraktami? .


1
Chociaż jest to ważna różnica, nie jest to jedyna różnica.
Govind Parmar

7

Interfejs: Skręć (skręć w lewo, skręć w prawo.)

Klasa abstrakcyjna: koło.

Klasa: Kierownica, wywodzi się z koła, odsłania zakręt interfejsu

Jednym z nich jest kategoryzowanie zachowań, które można zaoferować w odniesieniu do różnych przedmiotów, a drugim - modelowanie ontologii rzeczy.


6

Jeśli masz kilka typowych metod, które mogą być używane przez wiele klas, przejdź do klas abstrakcyjnych. Jeśli chcesz, aby klasy postępowały zgodnie z określonym schematem, wybierz interfejsy.

Poniższe przykłady pokazują to.

Klasa abstrakcyjna w Javie:

abstract class animals
{
    // They all love to eat. So let's implement them for everybody
    void eat()
    {
        System.out.println("Eating...");
    }
    // The make different sounds. They will provide their own implementation.
    abstract void sound();
}

class dog extends animals
{
    void sound()
    {
        System.out.println("Woof Woof");
    }
}

class cat extends animals
{
    void sound()
    {
        System.out.println("Meoww");
    }
}

Poniżej przedstawiono implementację interfejsu w Javie:

interface Shape
{
    void display();
    double area();
}

class Rectangle implements Shape 
{
    int length, width;
    Rectangle(int length, int width)
    {
        this.length = length;
        this.width = width;
    }
    @Override
    public void display() 
    {
        System.out.println("****\n* *\n* *\n****"); 
    }
    @Override
    public double area() 
    {
        return (double)(length*width);
    }
} 

class Circle implements Shape 
{
    double pi = 3.14;
    int radius;
    Circle(int radius)
    {
        this.radius = radius;
    }
    @Override
    public void display() 
    {
        System.out.println("O"); // :P
    }
    @Override
    public double area() 
    { 
        return (double)((pi*radius*radius)/2);
    }
}

Kilka ważnych kluczowych punktów w skrócie:

  1. Zmienne zadeklarowane w interfejsie Java są domyślnie ostateczne. Klasy abstrakcyjne mogą mieć nie-końcowe zmienne.

  2. Zmienne zadeklarowane w interfejsie Java są domyślnie statyczne. Klasy abstrakcyjne mogą mieć zmienne niestatyczne.

  3. Członkowie interfejsu Java są domyślnie publiczni. Klasa abstrakcyjna Java może mieć zwykłe smaki członków klasy, takie jak prywatny, chroniony itp.


4

Wielu młodszych programistów popełnia błąd, uważając interfejsy, klasy abstrakcyjne i konkretne za niewielkie odmiany tego samego, i wybiera jeden z nich wyłącznie ze względów technicznych: Czy potrzebuję wielokrotnego dziedziczenia? Czy potrzebuję miejsca, aby zastosować wspólne metody? Czy muszę zawracać sobie głowę czymś innym niż konkretną klasą? Jest to błędne i ukryty w tych pytaniach jest główny problem: „ja” . Pisząc kod dla siebie, rzadko myślisz o innych obecnych lub przyszłych programistach pracujących nad tym kodem lub z nim.

Interfejsy i klasy abstrakcyjne, choć pozornie podobne z technicznego punktu widzenia, mają zupełnie inne znaczenia i cele.

Podsumowanie

  1. Interfejs definiuje umowę, którą zrealizuje dla Ciebie niektóre wdrożenie .

  2. Klasa abstrakcyjna zapewnia domyślne zachowanie, którego implementacja może ponownie użyć.

Alternatywne podsumowanie

  1. Interfejs służy do definiowania publicznych interfejsów API
  2. Klasa abstrakcyjna służy do użytku wewnętrznego i do definiowania wskaźników SPI

O znaczeniu ukrywania szczegółów wdrożenia

Konkretna klasa wykonuje konkretną pracę w bardzo specyficzny sposób. Na przykład, ArrayListwykorzystuje ciągły obszar pamięci do przechowywania listy obiektów w zwarty sposób, który oferuje szybki losowy dostęp, iterację i zmiany w miejscu, ale jest straszny przy wstawianiu, usuwaniu, a czasem nawet dodawaniu; w międzyczasieLinkedList wykorzystuje podwójnie połączone węzły do ​​przechowywania listy obiektów, która zamiast tego oferuje szybką iterację, zmiany w miejscu oraz wstawianie / usuwanie / dodawanie, ale jest straszna przy przypadkowym dostępie. Te dwa typy list są zoptymalizowane pod kątem różnych przypadków użycia i bardzo ważne jest, jak je wykorzystasz. Kiedy próbujesz wycisnąć wydajność z listy, z którą intensywnie wchodzisz w interakcję, i gdy wybór rodzaju listy zależy od ciebie, powinieneś ostrożnie wybrać, który z nich tworzysz.

Z drugiej strony, użytkownicy wysokiego poziomu listy tak naprawdę nie dbają o to, jak jest ona faktycznie implementowana i powinni być odizolowani od tych szczegółów. Wyobraźmy sobie, że Java nie ujawnia Listinterfejsu, ale ma tylko konkretną Listklasę, która jest właśnie tym, co LinkedListjest teraz. Wszyscy programiści Java dostosowaliby swój kod do szczegółów implementacji: unikaj losowego dostępu, dodaj pamięć podręczną, aby przyspieszyć dostęp, lub po prostu dokonaj ponownej implementacji ArrayListsamodzielnie, chociaż byłoby to niezgodne z całym innym kodem, który faktycznie działa zList tylko . To byłoby okropne ... Ale teraz wyobraź sobie, że mistrzowie Javy faktycznie zdają sobie sprawę, że połączona lista jest okropna w większości rzeczywistych przypadków użycia, i postanowili przełączyć się na listę tablic tylko dla siebieListklasa dostępna. Wpłynęłoby to na wydajność każdego programu Java na świecie i ludzie nie byliby z tego powodu zadowoleni. A głównym winowajcą jest to, że szczegóły implementacji były dostępne, a programiści założyli, że są to stałe umowy, na których mogą polegać. Dlatego ważne jest, aby ukryć szczegóły implementacji i zdefiniować tylko abstrakcyjną umowę. Jest to cel interfejsu: zdefiniowanie, jakiego rodzaju dane wejściowe akceptuje metoda i jakiego rodzaju danych wyjściowych oczekuje się, bez ujawniania wszystkich odwagi, która skusiłaby programistów do poprawienia kodu w celu dopasowania do wewnętrznych szczegółów, które mogą ulec zmianie przy każdej przyszłej aktualizacji .

Klasa abstrakcyjna znajduje się pośrodku między interfejsami a konkretnymi klasami. Ma to pomóc implementacjom we wspólnym lub nudnym kodzie. Na przykład, AbstractCollectionzapewnia, że ​​podstawowe implementacje isEmptyoparte na rozmiarze są containsrówne 0, gdy iterują i porównują, addAlljak powtórzono additd. Pozwala to implementacjom skoncentrować się na kluczowych elementach, które je odróżniają: jak faktycznie przechowywać i odzyskiwać dane.

Interfejsy API a interfejsy SPI

Interfejsy są bramami o niskiej spójności między różnymi częściami kodu. Pozwalają one na istnienie i ewolucję bibliotek bez rozbijania każdego użytkownika biblioteki, gdy coś zmienia się wewnętrznie. To się nazywa interfejs programowania aplikacji , a nie klasy programowania aplikacji. Na mniejszą skalę pozwalają także wielu programistom z powodzeniem współpracować przy projektach na dużą skalę, oddzielając różne moduły za pomocą dobrze udokumentowanych interfejsów.

Klasy abstrakcyjne są pomocnikami o wysokiej spójności, które można stosować podczas implementacji interfejsu, przy założeniu pewnego poziomu szczegółów implementacji. Alternatywnie klasy abstrakcyjne są używane do definiowania SPI, interfejsów dostawcy usług.

Różnica między interfejsem API a interfejsem SPI jest subtelna, ale ważna: w przypadku interfejsu API skupia się na tym, kto go używa , aw przypadku interfejsu SPI koncentruje się na tym, kto go implementuje .

Dodawanie metod do interfejsu API jest łatwe, wszyscy obecni użytkownicy interfejsu API będą się nadal kompilować. Dodawanie metod do SPI jest trudne, ponieważ każdy dostawca usług (konkretne wdrożenie) będzie musiał wdrożyć nowe metody. Jeśli interfejsy są używane do definiowania SPI, dostawca będzie musiał wydać nową wersję za każdym razem, gdy zmieni się umowa SPI. Jeśli zamiast tego zostaną użyte klasy abstrakcyjne, nowe metody można zdefiniować w kategoriach istniejących metod abstrakcyjnych lub jako puste throw not implemented exceptionkody pośredniczące, co pozwoli przynajmniej kompilować i uruchamiać starszą wersję implementacji usługi.

Uwaga na temat Java 8 i metod domyślnych

Chociaż Java 8 wprowadziła domyślne metody interfejsów, co sprawia, że ​​linia między interfejsami a klasami abstrakcyjnymi jest jeszcze bardziej rozmyta, nie było to tak, że implementacje mogą ponownie wykorzystywać kod, ale aby ułatwić zmianę interfejsów, które służą zarówno jako interfejs API, jak i SPI (lub są niewłaściwie używane do definiowania SPI zamiast klas abstrakcyjnych).

Którego użyć?

  1. Czy rzecz ma być publicznie używana przez inne części kodu, czy przez inny kod zewnętrzny? Dodaj interfejs, aby ukryć szczegóły implementacji przed publiczną umową abstrakcyjną, która jest ogólnym zachowaniem rzeczy.
  2. Jest rzeczą coś, co miało mieć wiele implementacje z partii kodu wspólnego? Wykonaj zarówno interfejs, jak i abstrakcyjną, niepełną implementację.
  3. Czy kiedykolwiek będzie tylko jedna implementacja i nikt inny jej nie wykorzysta? Zrób z tego konkretną klasę.
    1. „ever” jest od dawna, możesz grać bezpiecznie i nadal dodawać interfejs.

Następstwo: odwrotnie jest często źle robione: używając czegoś , zawsze staraj się używać najbardziej ogólnej klasy / interfejsu, którego naprawdę potrzebujesz. Innymi słowy, nie deklaruj zmiennych jako ArrayList theList = new ArrayList(), chyba że faktycznie masz bardzo silną zależność od tego, że jest to lista tablic i żaden inny typ listy nie wyciąłby jej za ciebie. Użyj List theList = new ArrayListzamiast tego, a nawet Collection theCollection = new ArrayListjeśli fakt, że jest to lista, a nie jakikolwiek inny rodzaj kolekcji, nie ma znaczenia.


4

Naprawdę nie jest to odpowiedź na pierwotne pytanie, ale kiedy już znajdziesz odpowiedź na różnicę między nimi, wejdziesz w dylemat „ kiedy używać” : kiedy używać interfejsów lub klas abstrakcyjnych? Kiedy używać obu?

Mam ograniczoną wiedzę na temat OOP, ale do tej pory sprawdzanie interfejsów jako odpowiednika przymiotnika w gramatyce (popraw mnie, jeśli ta metoda jest fałszywa!). Na przykład nazwy interfejsów są jak atrybuty lub funkcje, które można nadać klasie, a klasa może mieć wiele z nich: ISerializable, ICountable, IList, ICacheable, IHappy, ...


3

Dziedziczenie służy dwóm celom:

  • Aby obiekt mógł traktować elementy danych typu macierzystego i implementacje metod jako własne.

  • Aby umożliwić odwołanie do obiektów jednego typu przez kod, który oczekuje odwołania do obiektu nadtypu.

W językach / frameworkach, które obsługują uogólnione wielokrotne dziedziczenie, często nie ma potrzeby klasyfikowania typu jako „interfejsu” lub „klasy abstrakcyjnej”. Jednak popularne języki i frameworki pozwolą typowi traktować elementy danych jednego typu lub implementacje metod jako własne, mimo że pozwalają one na zamianę typu na dowolną liczbę innych typów.

Klasy abstrakcyjne mogą mieć elementy danych i implementacje metod, ale mogą być dziedziczone tylko przez klasy, które nie dziedziczą z żadnych innych klas. Interfejsy nie nakładają prawie żadnych ograniczeń na typy, które je implementują, ale nie mogą zawierać żadnych elementów danych ani implementacji metod.

Są chwile, w których użyteczne jest zastępowanie typów wieloma różnymi rzeczami; zdarzają się sytuacje, w których obiekty mogą traktować elementy danych typu macierzystego i implementacje metod jako własne. Dokonanie rozróżnienia między interfejsami a klasami abstrakcyjnymi pozwala na użycie każdej z tych umiejętności w przypadkach, gdy jest to najbardziej istotne.


3

Kluczowe punkty:

  • Klasa abstrakcyjna może mieć właściwość, pola danych, metody (kompletne / niekompletne).
  • Jeśli metoda lub właściwości definiują w abstrakcyjnym słowie kluczowym, które musi zastąpić klasę pochodną. (Działa jako ściśle powiązana funkcjonalność)
  • Jeśli zdefiniujesz abstrakcyjne słowo kluczowe dla metody lub właściwości w klasie abstrakcyjnej, nie możesz zdefiniować treści metody i uzyskać / ustawić wartości dla właściwości, które muszą zastąpić w klasie pochodnej.
  • Klasa abstrakcyjna nie obsługuje wielokrotnego dziedziczenia.
  • Klasa abstrakcyjna zawiera konstruktory.
  • Klasa abstrakcyjna może zawierać modyfikatory dostępu dla napisów, funkcji i właściwości.
  • Tylko pełny element członkowski klasy abstrakcyjnej może być statyczny.
  • Interfejs może dziedziczyć tylko z innego interfejsu i nie może dziedziczyć z klasy abstrakcyjnej, gdzie jako klasa abstrakcyjna może dziedziczyć z innej klasy abstrakcyjnej lub innego interfejsu.

Korzyść:

  • Jest to rodzaj umowy, która zmusza wszystkie podklasy do przestrzegania tych samych hierarchii lub standardów.
  • Jeśli różne implementacje są tego samego rodzaju i używają wspólnego zachowania lub statusu, lepiej jest użyć klasy abstrakcyjnej.
  • Jeśli dodamy nową metodę do klasy abstrakcyjnej, mamy opcję zapewnienia domyślnej implementacji, a zatem cały istniejący kod może działać poprawnie.
  • Umożliwia szybkie wykonanie niż interfejs. (Interfejs Potrzebuje więcej czasu na znalezienie faktycznej metody w odpowiednich klasach).
  • Może być stosowany do ciasnego i luźnego łączenia.

znajdź szczegóły tutaj ... http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abstract-class-in-c-oops/


3

Najkrótszym sposobem na podsumowanie jest to, że an interface:

  1. Streszczenie całkowicie poza defaulti staticmetody; chociaż ma definicje (podpisy metod + implementacje) defaulti staticmetody, ma tylko deklaracje (podpisy metod) dla innych metod.
  2. Z zastrzeżeniem reguł Laxera niż klas (klasa może implementować wiele interfaces, a interfacemoże dziedziczyć z wielu interfaces). Wszystkie zmienne są domyślnie stałe, niezależnie od tego, czy są określone jako public static finalczy nie. Wszyscy członkowie są domyślnie public, niezależnie od tego, czy są określeni jako tacy, czy nie.
  3. Ogólnie stosowany jako gwarancja, że ​​klasa implementująca będzie miała określone funkcje i / lub będzie kompatybilna z dowolną inną klasą, która implementuje ten sam interfejs.

Tymczasem abstractklasa to:

  1. Gdziekolwiek, od w pełni abstrakcyjnego po w pełni wdrożony, z tendencją do posiadania jednej lub więcej abstractmetod. Może zawierać zarówno deklaracje, jak i definicje, z deklaracjami oznaczonymi jakoabstract .
  2. Klasa pełnoprawna i podlegająca regułom rządzącym innymi klasami (może dziedziczyć tylko z jednej klasy), pod warunkiem, że nie można jej utworzyć (ponieważ nie ma gwarancji, że zostanie w pełni zaimplementowana). Może mieć niestałe zmienne składowe. Można realizować kontrolę dostępu użytkownika, ograniczając jako członków protected, privatelub pakiet prywatnej (nieokreślony).
  3. Zwykle używany albo do zapewnienia tyle implementacji, ile może być współużytkowane przez wiele podklas, albo do zapewnienia takiej implementacji, ile programista jest w stanie dostarczyć.

Lub, jeśli chcemy gotować to wszystko na jednym zdaniu: AN interfaceco klasa wykonania ma , ale abstractklasa jest co podklasa jest .


3

Chciałbym dodać jeszcze jedną różnicę, która ma sens. Na przykład masz strukturę z tysiącami wierszy kodu. Teraz, jeśli chcesz dodać nową funkcję w całym kodzie za pomocą metody enhUI (), lepiej jest dodać tę metodę w klasie abstrakcyjnej, a nie w interfejsie. Ponieważ jeśli dodasz tę metodę do interfejsu, powinieneś ją zaimplementować we wszystkich zaimplementowanych klasach, ale nie jest tak w przypadku dodania metody w klasie abstrakcyjnej.


3

Aby dać prostą, ale jasną odpowiedź, pomaga ustawić kontekst: używasz obu, gdy nie chcesz zapewniać pełnych implementacji.

Główną różnicą jest to, że interfejs nie ma żadnej implementacji (tylko metody bez treści), podczas gdy klasy abstrakcyjne mogą mieć również elementy i metody z treścią, tzn. Mogą być częściowo implementowane.


Ponieważ odpowiedziałeś na nie teraz, twoja odpowiedź nie uwzględnia defaultsłowa kluczowego w Javie 8, za pomocą którego możesz również zdefiniować konkretne metody w interfejsach.
philantrovert

Jak powiedziałem, miała to być „prosta, ale jasna odpowiedź” dla kogoś na etapie uczenia się, na czym polega różnica. Dla kogoś takiego nie jest żadną korzyścią wiedzieć o tego rodzaju wyjątku, byłoby to bardzo mylące.
user3775501

3

Różnice między klasą abstrakcyjną a interfejsem w imieniu rzeczywistej implementacji.

Berło : Jest to słowo kluczowe i służy do zdefiniowania szablonu lub niebieskiego wydruku obiektu i wymusza, aby wszystkie podklasy podążały za tym samym prototypem, ponieważ w przypadku implementacji wszystkie podklasy mogą implementować funkcjonalność zgodnie z to wymóg.

Niektóre inne przypadki użycia, w których powinniśmy użyć interfejsu.

Komunikacja między dwoma obiektami zewnętrznymi (integracja strony trzeciej w naszej aplikacji) odbywa się za pośrednictwem interfejsu tutaj Interfejs działa jako umowa.

Klasa abstrakcyjna: streszczenie, jest słowem kluczowym, a kiedy używamy tego słowa kluczowego przed jakąkolwiek klasą, staje się klasą abstrakcyjną. Jest używana głównie, gdy musimy zdefiniować szablon, a także niektóre domyślne funkcje obiektu, po którym następuje podklasy, w ten sposób usuwa zbędny kod i jeszcze jeden przypadek użycia, w którym możemy użyć klasy abstrakcyjnej , ponieważ nie chcemy, aby inne klasy mogły bezpośrednio tworzyć instancję obiektu klasy, tylko klasy pochodne mogą korzystać z tej funkcji.

Przykład klasy abstrakcyjnej:

 public abstract class DesireCar
  {

 //It is an abstract method that defines the prototype.
     public abstract void Color();

  // It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.   
 // and hence no need to define this in all the sub classes in this way it saves the code duplicasy     

  public void Wheel() {          

               Console.WriteLine("Car has four wheel");
                }
           }


    **Here is the sub classes:**

     public class DesireCar1 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red color Desire car");
            }
        }

        public class DesireCar2 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red white Desire car");
            }
        }

Przykład interfejsu:

  public interface IShape
        {
          // Defines the prototype(template) 
            void Draw();
        }


  // All the sub classes follow the same template but implementation can be different.

    public class Circle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Circle");
        }
    }

    public class Rectangle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Rectangle");
        }
    }

3

Można znaleźć wyraźną różnicę między interfejsem a klasą abstrakcyjną.

Berło

  • Interfejs zawiera tylko metody abstrakcyjne.
  • Zmusza użytkowników do wdrożenia wszystkich metod podczas implementacji interfejsu.
  • Zawiera tylko zmienne końcowe i statyczne.
  • Zadeklaruj za pomocą słowa kluczowego interfejsu.
  • Wszystkie metody interfejsu muszą być zdefiniowane jako publiczne.
  • Interfejs może zostać rozszerzony lub klasa może implementować wiele innych interfejsów.

Klasa abstrakcyjna

  • Klasa abstrakcyjna zawiera metody abstrakcyjne i nieabstrakcyjne.

  • Nie zmusza użytkowników do implementacji wszystkich metod po odziedziczeniu klasy abstrakcyjnej.

  • Zawiera wszystkie rodzaje zmiennych, w tym prymitywne i nieprymitywne

  • Zadeklaruj za pomocą abstrakcyjnego słowa kluczowego.

  • Metody i elementy klasy abstrakcyjnej można definiować z dowolną widocznością.

  • Klasa podrzędna może rozszerzyć tylko jedną klasę (abstrakcyjną lub konkretną).


2

Klasa abstrakcyjna to klasa, której obiektu nie można utworzyć, lub klasa, której nie można utworzyć. Metoda abstrakcyjna czyni klasę abstrakcyjną. Klasa abstrakcyjna musi zostać odziedziczona, aby zastąpić metody zadeklarowane w klasie abstrakcyjnej. Brak ograniczeń dotyczących specyfikatorów dostępu. Klasa abstrakcyjna może zawierać w sobie konstruktor i inne konkretne metody (nie-abstarct), ale interfejs nie może.

Interfejs to schemat / szablon metod (np. Podany jest dom na papierze (interfejs domu), a różni architekci wykorzystają swoje pomysły do ​​jego zbudowania (klasy architektów wdrażających interfejs domu). Jest to zbiór metody abstrakcyjne, metody domyślne, metody statyczne, zmienne końcowe i klasy zagnieżdżone. Wszyscy członkowie będą ostateczni lub publiczni, specyfikatory dostępu chronionego i prywatnego są niedozwolone. Nie można tworzyć obiektów. Klasa musi być stworzona w celu użycia implementuje interfejs, a także zastępuje metodę abstrakcyjną zadeklarowaną w interfejsie. Interfejs jest dobrym przykładem luźnego sprzężenia (dynamiczny polimorfizm / dynamiczne wiązanie) Interfejs implementuje polimorfizm i abstrakcję. Mówi, co robić, ale jak to zrobić, jest zdefiniowane przez klasa implementacyjna, np. tam ”jest firmą samochodową i chce, aby niektóre funkcje były takie same dla wszystkich samochodów, które produkuje, dlatego firma stworzyłaby interfejs, który będzie posiadał te cechy i różne klasy samochodów (takie jak Maruti Suzkhi, Maruti 800) zastąpią te funkcje (funkcje).

Po co interfejs, skoro mamy już klasę abstrakcyjną? Java obsługuje tylko dziedziczenie wielopoziomowe i hierarchiczne, ale za pomocą interfejsu możemy zaimplementować wielokrotne dziedziczenie.


2

W praktyce (JAVA), główna różnica między klasą abstrakcyjną a interfejsem polega na tym, że klasa abstrakcyjna może utrzymać stan. Oprócz stanu wstrzymania możemy również wykonywać operacje spoczynku za pomocą interfejsu.


1

W interfejsie wszystkie metody muszą być tylko definicjami, nie należy implementować pojedynczej.

Ale w klasie abstrakcyjnej musi istnieć metoda abstrakcyjna z tylko definicją, ale inne metody mogą być również w klasie abstrakcyjnej z implementacją ...


1

Mamy różne różnice strukturalne / składniowe między interfejsem a klasą abstrakcyjną. Są jeszcze inne różnice

[1] Różnica oparta na scenariuszu :

Klasy abstrakcyjne są używane w scenariuszach, w których chcemy ograniczyć użytkownika do tworzenia obiektu klasy nadrzędnej ORAZ uważamy, że w przyszłości zostanie dodanych więcej metod abstrakcyjnych.

Interfejs musi być użyty, gdy jesteśmy pewni, że nie będzie już więcej abstrakcyjnej metody do dostarczenia. Następnie publikowany jest tylko interfejs.

[2] Różnica koncepcyjna :

„Czy w przyszłości będziemy musieli zapewnić więcej abstrakcyjnych metod”, jeśli TAK sprawi, że będzie to klasa abstrakcyjna, a jeśli NIE sprawi, że będzie to interfejs?

(Najbardziej odpowiedni i ważny do java 1.7)


1

zwykle Klasa abstrakcyjna używana do rdzenia czegoś, ale interfejs używany do dołączania urządzeń peryferyjnych.

gdy chcesz utworzyć typ podstawowy dla pojazdu, powinieneś użyć klasy abstrakcyjnej, ale jeśli chcesz dodać funkcjonalność lub właściwość, która nie jest częścią podstawowej koncepcji pojazdu, powinieneś użyć interfejsu, na przykład chcesz dodać funkcję „ToJSON ()” .

interfejs ma szeroki zakres abstrakcji zamiast abstrakcyjnej klasy. możesz to zobaczyć przekazując argumenty. spójrz na ten przykład:

wprowadź opis zdjęcia tutaj

jeśli użyjesz pojazdu jako argumentu, możesz po prostu użyć jednego z jego pochodnych typów (autobus lub pojazd tej samej kategorii, tylko kategoria pojazdu). ale kiedy używasz interfejsu IMoveable jako argumentu, masz więcej możliwości.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.