Implementuje vs rozszerza: kiedy używać? Co za różnica?

719

Proszę wyjaśnić w łatwym do zrozumienia języku lub link do jakiegoś artykułu.

Saad Masood
źródło
9
link Ten przykład ułatwił zrozumienie interfejsu i klasy abstrakcyjnej, tj. implementuje i rozszerza java.
User Learning

Odpowiedzi:

734

extendssłuży do rozszerzenia klasy.

implementssłuży do implementacji interfejsu

Różnica między interfejsem a zwykłą klasą polega na tym, że w interfejsie nie można zaimplementować żadnej z zadeklarowanych metod. Tylko klasa, która „implementuje” interfejs może implementować metody. Odpowiednikiem interfejsu w C ++ byłaby klasa abstrakcyjna (NIE DOKŁADNIE taka sama, ale w zasadzie).

Również Java nie obsługuje wielokrotnego dziedziczenia klas. Można to rozwiązać za pomocą wielu interfejsów.

 public interface ExampleInterface {
    public void doAction();
    public String doThis(int number);
 }

 public class sub implements ExampleInterface {
     public void doAction() {
       //specify what must happen
     }

     public String doThis(int number) {
       //specfiy what must happen
     }
 }

teraz rozszerzając klasę

 public class SuperClass {
    public int getNb() {
         //specify what must happen
        return 1;
     }

     public int getNb2() {
         //specify what must happen
        return 2;
     }
 }

 public class SubClass extends SuperClass {
      //you can override the implementation
      @Override
      public int getNb2() {
        return 3;
     }
 }

w tym przypadku

  Subclass s = new SubClass();
  s.getNb(); //returns 1
  s.getNb2(); //returns 3

  SuperClass sup = new SuperClass();
  sup.getNb(); //returns 1
  sup.getNb2(); //returns 2

Sugeruję, abyś przeprowadził więcej badań nad dynamicznym wiązaniem, polimorfizmem i ogólnie dziedziczeniem w programowaniu obiektowym

tgoossens
źródło
46
Interfejs może zawierać znacznie więcej niż deklaracje metod: pola stałe, adnotacje, interfejsy, a nawet klasy.
Philipp Reichart
czy są czymś podobnym do modułów i miksów w rubinie?
user2492854
@ user2492854 trochę, ale w interfejsie nie będzie żadnych zaimplementowanych metod. To dosłownie opis interfejsu, a nie implementacja.
Rob Grant,
34
Nowa funkcja w Javie 8 umożliwia implementację defaultzachowania metod w interfejsach, dzięki czemu niestandardowa implementacja tych metod jest opcjonalna. Dlatego stwierdzenie „możesz tylko określić metody, ale nie wdrożyć ich” jest w pełni poprawne tylko dla Javy 7 i niższych .
ADTC
5
„extends służy do rozszerzenia klasy”, jest nieco mylące. Sinus interfejsu i rozszerza również interfejs . Na przykład:public interface ListIterator<E> extends Iterator<E>
weiheng,
77

Zauważyłem, że masz kilka pytań w C ++ w swoim profilu. Jeśli rozumiesz pojęcie wielokrotnego dziedziczenia po C ++ (odnoszące się do klas, które dziedziczą cechy z więcej niż jednej innej klasy), Java nie pozwala na to, ale ma słowo kluczowe interface, które jest w C ++ czymś w rodzaju czystej klasy wirtualnej. Jak wspomniało wiele osób, jesteś extendklasą (i możesz rozszerzyć tylko z jednej), a ty implementinterfejsem - ale twoja klasa może implementować tyle interfejsów, ile chcesz.

Tzn. Te słowa kluczowe i reguły rządzące ich użyciem określają możliwości wielokrotnego dziedziczenia w Javie (możesz mieć tylko jedną superklasę, ale możesz zaimplementować wiele interfejsów).

delikatna gorączka
źródło
51

Ogólnie implementuje używane do implementacji interfejsu i rozszerzeń używanych do rozszerzenia zachowania klasy bazowej lub klasy abstrakcyjnej .

extends : klasa pochodna może rozszerzyć klasę podstawową. Możesz przedefiniować zachowanie ustanowionej relacji. Klasa pochodna „ jest ” typem klasy podstawowej

implementuje : wdrażasz umowę. Klasa implementująca interfejs „ ma ” zdolność.

W wersji java 8 interfejs może mieć domyślne metody w interfejsie, co zapewnia implementację w samym interfejsie.

Sprawdź, kiedy używać każdego z nich:

Interfejs vs Klasa abstrakcyjna (ogólne OO)

Przykład zrozumienia rzeczy.

public class ExtendsAndImplementsDemo{
    public static void main(String args[]){

        Dog dog = new Dog("Tiger",16);
        Cat cat = new Cat("July",20);

        System.out.println("Dog:"+dog);
        System.out.println("Cat:"+cat);

        dog.remember();
        dog.protectOwner();
        Learn dl = dog;
        dl.learn();

        cat.remember();
        cat.protectOwner();

        Climb c = cat;
        c.climb();

        Man man = new Man("Ravindra",40);
        System.out.println(man);

        Climb cm = man;
        cm.climb();
        Think t = man;
        t.think();
        Learn l = man;
        l.learn();
        Apply a = man;
        a.apply();

    }
}

abstract class Animal{
    String name;
    int lifeExpentency;
    public Animal(String name,int lifeExpentency ){
        this.name = name;
        this.lifeExpentency=lifeExpentency;
    }
    public void remember(){
        System.out.println("Define your own remember");
    }
    public void protectOwner(){
        System.out.println("Define your own protectOwner");
    }

    public String toString(){
        return this.getClass().getSimpleName()+":"+name+":"+lifeExpentency;
    }
}
class Dog extends Animal implements Learn{

    public Dog(String name,int age){
        super(name,age);
    }
    public void remember(){
        System.out.println(this.getClass().getSimpleName()+" can remember for 5 minutes");
    }
    public void protectOwner(){
        System.out.println(this.getClass().getSimpleName()+ " will protect owner");
    }
    public void learn(){
        System.out.println(this.getClass().getSimpleName()+ " can learn:");
    }
}
class Cat extends Animal implements Climb {
    public Cat(String name,int age){
        super(name,age);
    }
    public void remember(){
        System.out.println(this.getClass().getSimpleName() + " can remember for 16 hours");
    }
    public void protectOwner(){
        System.out.println(this.getClass().getSimpleName()+ " won't protect owner");
    }
    public void climb(){
        System.out.println(this.getClass().getSimpleName()+ " can climb");
    }
}
interface Climb{
    public void climb();
}
interface Think {
    public void think();
}

interface Learn {
    public void learn();
}
interface Apply{
    public void apply();
}

class Man implements Think,Learn,Apply,Climb{
    String name;
    int age;

    public Man(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void think(){
        System.out.println("I can think:"+this.getClass().getSimpleName());
    }
    public void learn(){
        System.out.println("I can learn:"+this.getClass().getSimpleName());
    }
    public void apply(){
        System.out.println("I can apply:"+this.getClass().getSimpleName());
    }
    public void climb(){
        System.out.println("I can climb:"+this.getClass().getSimpleName());
    }
    public String toString(){
        return "Man :"+name+":Age:"+age;
    }
}

wynik:

Dog:Dog:Tiger:16
Cat:Cat:July:20
Dog can remember for 5 minutes
Dog will protect owner
Dog can learn:
Cat can remember for 16 hours
Cat won't protect owner
Cat can climb
Man :Ravindra:Age:40
I can climb:Man
I can think:Man
I can learn:Man
I can apply:Man

Ważne punkty do zrozumienia:

  1. Pies i kot są zwierzętami i rozszerzyli remember() i protectOwner(), dzieląc się name,lifeExpentencyzAnimal
  2. Kot może się wspinać (), ale Pies nie. Pies może myśleć (), ale Kot nie . Te specyficzne możliwości są dodawane do Cati Dogpoprzez implementację tej możliwości.
  3. Człowiek nie jest zwierzęciem, ale może Think,Learn,Apply,Climb

Przechodząc przez te przykłady, możesz to zrozumieć

Klasy niezwiązane mogą mieć możliwości poprzez interfejs, ale klasy pokrewne nadpisują zachowanie poprzez rozszerzenie klas podstawowych.

Ravindra babu
źródło
1
Bardzo dobrze wyjaśnione. Właśnie kliknął. Wielkie dzięki!
Emir Memic
Czy to naprawdę tak jest? Zawsze myślałem, że „ma” odnosi się do posiadania czegoś, posiadania tego. Można powiedzieć, że kot „ma” zdolność wspinania się, ale chciałbym przeredagować swój przykład. Kot „jest„ wspinaczem ”, człowiek„ jest ”„ myślicielem, uczniem, wspinaczem ”. Ponieważ człowiek„ jest ”myślicielem, może robić to, co potrafi myśliciel. Jest to jeszcze bardziej przejrzyste w przypadku niektórych protokołów - jeśli ma dom, ma drzwi, ale nie implementuje pushingHandle. Jest to także „MaterialObject”, co oznacza, że ​​implementuje interfejs do posłuszeństwa grawitacji; nie ma „GravityObeyingSkill” ani czegoś podobnego.
MatthewRock
Jeśli człowiek jest myślicielem, nawiążę związek z rozszerzeniami, a nie z narzędziami. Myśliciel może mieć pewne role i inne funkcje / funkcje, ale zaimplementuję zdolność myślenia tylko z interfejsem. IS A jest standardowym terminem używanym do dziedziczenia.
Ravindra babu
@Ravindrababu Bardzo dziękuję za tak jasne wytłumaczenie.
kanudo
1
świetnie wyjaśnione!
Dary,
43

extendsjest przeznaczony do dziedziczenia po klasie podstawowej (tj. rozszerzeniu jej funkcjonalności).

implementsjest przeznaczony do implementacji interfejsu .

Oto dobre miejsce na rozpoczęcie: interfejsy i dziedziczenie .

Oliver Charlesworth
źródło
24
Rozbudowa dotyczy również rozszerzenia interfejsu :-).
Mark Peters
34

classTylko można „wdrożyć” an interface. Klasa tylko „rozszerza” a class. Podobnie interfacemoże przedłużyć inny interface.

A classmoże przedłużać tylko jeden inny class. A classmoże zaimplementować kilka interfaces.

Jeśli zamiast tego bardziej interesuje Cię wiedza, kiedy użyć abstract classes i interfaces, zapoznaj się z tym wątkiem: Interfejs vs Klasa abstrakcyjna (ogólne OO)

Hari Menon
źródło
2
Możesz także rozszerzyć interfejs.
Mark Peters
2
A classmoże wdrożyć tylko jeden interface. A classmoże rozszerzyć kilka innych klas. Wierzę, że dostałeś to wstecz.
pb2q
Aby wyjaśnić komentarz pb2q, odpowiedź została już edytowana / poprawiona. „Klasa może rozszerzać tylko jedną inną klasę. Klasa może implementować kilka interfejsów” jest poprawnym stwierdzeniem.
wisbucky
29

Interfejs to opis działań, które może wykonywać obiekt ... na przykład po naciśnięciu przełącznika światła światło się zapala, nie obchodzi cię, jak to działa. W programowaniu obiektowym interfejs to opis wszystkich funkcji, które musi posiadać obiekt, aby mógł być „X”. Ponownie, na przykład, wszystko, co „ACTS LIKE” światło, powinno mieć metodę turn_on () i metodę turn_off (). Interfejsy mają na celu umożliwienie komputerowi wymuszenia tych właściwości oraz wiedzy, że obiekt TYPU T (niezależnie od interfejsu) musi mieć funkcje o nazwach X, Y, Z itp.

Interfejs to struktura / składnia programowania, która umożliwia komputerowi wymuszanie określonych właściwości obiektu (klasy). Załóżmy na przykład, że mamy klasę samochodów, klasę skuterów i klasę ciężarówek. Każda z tych trzech klas powinna mieć akcję start_engine (). Sposób, w jaki „silnik jest uruchamiany” dla każdego pojazdu, jest pozostawiony poszczególnym klasom, ale fakt, że muszą one mieć działanie start_engine, jest domeną interfejsu .

Ryan Efendy
źródło
4
Świetne wyjaśnienie; zasługuje na większe uznanie.
Arvindh Mani
22

Jak pokazano na poniższym rysunku, klasa rozszerza inną klasę, interfejs rozszerza inny interfejs, ale klasa implementuje interfejs. wprowadź opis zdjęcia tutaj

Po więcej szczegółów

JustCode
źródło
16

Rozszerza : służy do przeniesienia atrybutów klasy nadrzędnej do klasy podstawowej i może zawierać już zdefiniowane metody, które można zastąpić w klasie podrzędnej.

Implementuje : służy do implementacji interfejsu (klasa nadrzędna tylko z podpisami funkcji, ale nie ich definicjami) poprzez zdefiniowanie go w klasie potomnej.

Jest jeden specjalny warunek: „Co jeśli chcę, aby nowy interfejs był dzieckiem istniejącego interfejsu?”. W powyższym stanie interfejs potomny rozszerza interfejs macierzysty.

Guru
źródło
15
  • A rozszerza B:

    A i B to obie klasy lub oba interfejsy

  • A implementuje B.

    A to klasa, a B to interfejs

  • Pozostały przypadek, w którym A jest interfejsem, a B jest klasą, nie jest legalny w Javie.

użytkownik207421
źródło
12

Implementacje są używane w interfejsach, a extends służą do rozszerzania klasy.

Aby uczynić go bardziej zrozumiałym w prostszych terminach, interfejs wygląda tak, jak brzmi - interfejs - model, który należy zastosować, podążać wraz z Twoimi pomysłami na niego.

Rozszerzenie służy do klas, tutaj rozszerzasz coś, co już istnieje, dodając do niego więcej funkcji.

Jeszcze kilka notatek:

interfejs może rozszerzyć inny interfejs.

A kiedy musisz wybrać pomiędzy implementacją interfejsu lub rozszerzeniem klasy dla konkretnego scenariusza, przejdź do implementacji interfejsu. Ponieważ klasa może implementować wiele interfejsów, ale rozszerzyć tylko jedną klasę.

Kazekage Gaara
źródło
7

Gdy podklasa rozszerza klasę, pozwala ona dziedziczyć (ponownie wykorzystywać) i zastępować kod zdefiniowany w nadtypie. Kiedy klasa implementuje interfejs, pozwala na użycie obiektu utworzonego z klasy w dowolnym kontekście, który oczekuje wartości interfejsu.

Prawdziwy haczyk polega na tym, że chociaż wdrażamy wszystko, oznacza to po prostu, że używamy tych metod takimi, jakimi są. Nie ma możliwości zmiany ich wartości i typów zwracanych.

Ale kiedy coś przedłużamy, staje się przedłużeniem twojej klasy. Możesz go zmienić, użyć, użyć ponownie, użyj go i niekoniecznie musi zwracać te same wartości, co w nadklasie.

Nikhil Arora
źródło
Czytam tę odpowiedź napisaną przeze mnie po ponad 3 latach 19 września. Przysięgam, że nie jestem w stanie zrozumieć, co napisałem. Mógłbym teraz napisać o wiele lepszą odpowiedź. Dziwna rzecz.
Nikhil Arora,
7

Używamy podklasy rozciąga SuperClass tylko wtedy, gdy podklasa chce wykorzystać niektóre funkcje (metody lub zmiennych instancji), który jest już zadeklarowana w SuperClass , lub jeśli chcesz nieznacznie zmodyfikować funkcjonalność SuperClass (Metoda nadrzędne). Powiedzmy na przykład, że mam klasę Animal ( SuperClass ) i Dog ( SubClass ) i istnieje kilka metod, które zdefiniowałem w klasie Animal, np. doEat (); , doSleep (); ... i wiele więcej.

Teraz moja klasa Dog może po prostu rozszerzyć klasę Animal, jeśli chcę, aby mój pies używał dowolnej metody zadeklarowanej w klasie Animal, mogę wywoływać te metody, po prostu tworząc obiekt Dog. W ten sposób mogę zagwarantować, że mam psa, który może jeść i spać i robić wszystko, co chcę, aby pies to zrobił.

Teraz wyobraź sobie, że pewnego dnia jakiś miłośnik kotów wchodzi do naszego miejsca pracy i próbuje rozszerzyć klasę zwierząt (koty też jedzą i śpią). Robi obiekt Cat i zaczyna wywoływać metody.

Ale powiedzmy, że ktoś próbuje stworzyć obiekt klasy Animal. Możesz powiedzieć, jak śpi kot, możesz powiedzieć, jak pies je, możesz powiedzieć, jak pije słoń. Ale nie ma sensu tworzyć obiektu klasy Animal. Ponieważ jest to szablon i nie chcemy żadnego ogólnego sposobu jedzenia.

Zamiast tego wolę stworzyć klasę abstrakcyjną, której nikt nie będzie mógł utworzyć, ale może być użyty jako szablon dla innych klas.

Podsumowując, interfejs jest niczym innym jak klasą abstrakcyjną (czystą klasą abstrakcyjną), która nie zawiera żadnych implementacji metod, a jedynie definicje (szablony). Więc ktokolwiek implementuje interfejs, wie tylko, że ma szablony doEat (); i doSleep (); ale muszą zdefiniować własne doEat (); i doSleep (); metody według ich potrzeb.

Rozszerzasz tylko wtedy, gdy chcesz ponownie wykorzystać część SuperClass (ale pamiętaj, że zawsze możesz zastąpić metody SuperClass zgodnie z potrzebami) i wdrażasz, kiedy chcesz szablony i chcesz je zdefiniować samodzielnie (w zależności od potrzeb).

Podzielę się z tobą fragmentem kodu: wypróbujesz go z różnymi zestawami danych wejściowych i spojrzysz na wyniki.

class AnimalClass {

public void doEat() {

    System.out.println("Animal Eating...");
}

public void sleep() {

    System.out.println("Animal Sleeping...");
}

}

public class Dog extends AnimalClass implements AnimalInterface, Herbi{

public static void main(String[] args) {

    AnimalInterface a = new Dog();
    Dog obj = new Dog();
    obj.doEat();
    a.eating();

    obj.eating();
    obj.herbiEating();
}

public void doEat() {
    System.out.println("Dog eating...");
}

@Override
public void eating() {

    System.out.println("Eating through an interface...");
    // TODO Auto-generated method stub

}

@Override
public void herbiEating() {

    System.out.println("Herbi eating through an interface...");
    // TODO Auto-generated method stub

}


}

Zdefiniowane interfejsy :

public interface AnimalInterface {

public void eating();

}


interface Herbi {

public void herbiEating();

}
Shubham Arya
źródło
7

Oba słowa kluczowe są używane podczas tworzenia własnej nowej klasy w języku Java.

Różnica: implementsoznacza, że ​​używasz elementów interfejsu Java w swojej klasie. extendsoznacza, że ​​tworzysz podklasę rozszerzanej klasy podstawowej. Możesz rozszerzyć tylko jedną klasę w klasie podrzędnej, ale możesz zaimplementować tyle interfejsów, ile chcesz.

Więcej informacji znajduje się na stronie dokumentacji Oracle w interfejsie .

Pomoże to wyjaśnić, czym jest interfejs i jakie są konwencje korzystania z niego.

Daniel
źródło
7

W najprostszych terminach ext służy do dziedziczenia po klasie, a implementacja służy do zastosowania interfejsu w klasie

rozszerza :

public class Bicycle {
    //properties and methods
}
public class MountainBike extends Bicycle {
    //new properties and methods
}

wdraża :

public interface Relatable {
    //stuff you want to put
}
public class RectanglePlus implements Relatable {
    //your class code
}

jeśli nadal masz wątpliwości, przeczytaj to: https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html https://docs.oracle.com/javase/tutorial/java/IandI/usinginterface.html

Irteza Asad
źródło
5

Klasy i interfejsyumowami . Zapewniają metody i właściwości, na których opiera się inna część aplikacji.

Interfejs definiuje się , gdy nie są Państwo zainteresowani szczegółami realizacji tej umowy. Jedyne, na co należy zwrócić uwagę, to to, że umowa (interfejs) istnieje.

W takim przypadku należy pozostawić to klasie, która implementuje interfejs, aby dbał o szczegóły dotyczące realizacji umowy. Tylko klasy mogą implementować interfejsy.

Przedłużenie jest używane, gdy chcesz zastąpić szczegóły istniejącej umowy. W ten sposób zamieniasz jeden sposób na wypełnienie umowy innym sposobem. Klasy mogą rozszerzać inne klasy, a interfejsy mogą rozszerzać inne interfejsy.

Martin Komischke
źródło
3

Extendsjest używany, gdy chcesz mieć atrybuty klasy / interfejsu nadrzędnego w klasie / interfejsie podrzędnym i implementsjest używany, gdy chcesz mieć atrybuty interfejsu w klasie.

Przykład:

  1. Rozszerza za pomocą klasy

    klasa Parent {

    }

    klasa Dziecko rozszerza Rodzica {

    }

  2. Rozszerza za pomocą interfejsu

    interfejs Parent {

    }

    interfejs Dziecko rozszerza Rodzica {

    }

  3. Narzędzia

interfejs A {

}

klasa B implementuje A {

}

Połączenie rozszerzeń i narzędzi

interface A{

}

class B

{

}

class C implements A,extends B{

}
Alekya
źródło
2

rozszerza się

  • klasa rozszerza tylko jedną klasę
  • Interfejs rozszerza jeden lub więcej interfejsów

narzędzia

  • klasa implementuje jeden lub więcej interfejsów
  • interfejsy „nie mogą” niczego zaimplementować

klasy abstrakcyjne działają również jak klasa, z rozszerzeniami i implementacjami

Yuresh Karunanayake
źródło
0

Te dwa słowa kluczowe są bezpośrednio związane z dziedziczeniem, które jest podstawową koncepcją OOP. Kiedy odziedziczymy jakąś klasę do innej klasy, możemy użyć rozszerzeń, ale kiedy zamierzamy odziedziczyć niektóre interfejsy do naszej klasy, nie możemy użyć rozszerzeń, powinniśmy użyć narzędzi i możemy użyć słowa kluczowego rozszerzenia do dziedziczenia interfejsu z innego interfejsu.

Kavinda Pushpitha
źródło