Dziedziczenie wielokrotne w języku Java


168

Próbując w pełni zrozumieć, jak rozwiązać wiele problemów z dziedziczeniem w Javie, mam klasyczne pytanie, które muszę wyjaśnić.

Powiedzmy mam klasę Animalto ma sub klas Birdi Horsei muszę dokonać klasy Pegasus, która rozciąga się od Birda Horseponieważ Pegasusjest zarówno ptaków i koń.

Myślę, że to klasyczny problem z diamentami. Z tego co rozumiem, klasyczny sposób, aby rozwiązać ten jest aby Animal, Birdi Horsećwiczenia interfejsy i wdrożenie Pegasusod nich.

Zastanawiałem się, czy istnieje inny sposób rozwiązania problemu, w którym nadal mogę tworzyć obiekty dla ptaków i koni. Gdyby istniał sposób na stworzenie zwierząt, byłoby to świetne, ale niekonieczne.


6
Myślę, że możesz ręcznie tworzyć klasy i przechowywać je jako składowe (kompozycja zamiast dziedziczenia). W przypadku klasy Proxy ( docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html ) może to być opcja, chociaż będziesz również potrzebować interfejsów.
Gábor Bakos,

4
@RAM nie powinien więc rozszerzać Birda, a raczej mieć zachowanie, które umożliwi mu lot. : D problem rozwiązany
Yogesh

11
Dokładnie. Co powiesz na interfejs CanFly. :-)
Surprised Coconut

28
Myślę, że to niewłaściwe podejście. Masz zwierzęta - konie, ptaki. I masz właściwości - latanie, mięsożerne. Pegaz to nie koń, ptak to koń, który potrafi latać. Właściwości powinny znajdować się w interfejsach. A więc public class Pegasus extends Horse implements Flying.
Boris the Spider

12
Rozumiem, dlaczego uważasz, że jest to niewłaściwe i nie przestrzega zasad biologii i doceniam twoją troskę, ale jeśli chodzi o program, który muszę zbudować, a który ma do czynienia z bankami, było to dla mnie najlepsze podejście. Ponieważ nie chciałem publikować moich aktualnych problemów, ponieważ byłoby to sprzeczne z zasadami, nieco zmieniłem przykład. Ale dzięki ...
Sheli,

Odpowiedzi:


115

Mógłbyś stworzyć interfejsy dla klas zwierząt (klasa w znaczeniu biologicznym), na przykład public interface Equidaedla koni i public interface Avialaeptaków (nie jestem biologiem, więc terminy mogą być błędne).

Wtedy nadal możesz utworzyć plik

public class Bird implements Avialae {
}

i

public class Horse implements Equidae {}

i również

public class Pegasus implements Avialae, Equidae {}

Dodawanie z komentarzy:

Aby zmniejszyć liczbę duplikatów kodu, możesz utworzyć klasę abstrakcyjną zawierającą większość wspólnego kodu zwierząt, które chcesz zaimplementować.

public abstract class AbstractHorse implements Equidae {}

public class Horse extends AbstractHorse {}

public class Pegasus extends AbstractHorse implements Avialae {}

Aktualizacja

Chciałbym dodać jeszcze jeden szczegół. Jak zauważa Brian , jest to coś, o czym OP już wiedział.

Pragnę jednak podkreślić, że proponuję ominąć problem „wielokrotnego dziedziczenia” z interfejsami i nie polecam używania interfejsów, które reprezentują już konkretny typ (np. Bird), a raczej zachowanie (inne odnoszą się do typowanie kaczek, co też jest dobre, ale mam na myśli tylko biologiczną klasę ptaków, Avialae). Nie polecam również używania nazw interfejsów zaczynających się od dużej litery „I”, takich jakIBird , co nie mówi nic o tym, dlaczego potrzebny jest interfejs. Na tym polega różnica w pytaniu: skonstruuj hierarchię dziedziczenia za pomocą interfejsów, użyj klas abstrakcyjnych, gdy jest to przydatne, zaimplementuj konkretne klasy w razie potrzeby i użyj delegowania, jeśli to konieczne.


9
Co ... jest dokładnie tym, co mówi OP, że wie, że możesz zrobić w Q.
Brian Roach,

4
Ponieważ Pegasus JEST już Koniem (który lata), myślę, że możesz użyć więcej kodu, jeśli rozszerzy Horse i zaimplementuje Avialae.
Pablo Lozano,

8
Nie jestem pewien, jeszcze nie widziałem Pegaza. Jednak w takim przypadku wolałbym użyć AbstractHorse, który może być również użyty do budowy Zebry lub innych zwierząt podobnych do koni.
Moritz Petersen

5
@MoritzPetersen Jeśli naprawdę chcesz ponownie wykorzystać abstrakcje i nadać znaczące nazwy, prawdopodobnie AbstractEquidaebyłoby bardziej odpowiednie niż AbstractHorse. Byłoby dziwne, gdyby zebra przedłużała abstrakcyjnego konia. Nawiasem mówiąc, dobra odpowiedź.
afsantos

3
Wdrożenie typowania kaczego wymagałoby również Duckimplementacji klas Avialae?
mgarciaisaia,

88

Istnieją dwa podstawowe podejścia do łączenia obiektów razem:

  • Pierwsza to dziedziczenie . Ponieważ już zidentyfikowałeś ograniczenia dziedziczenia, oznacza to, że nie możesz tutaj zrobić tego, czego potrzebujesz.
  • Drugi to kompozycja . Ponieważ dziedziczenie nie powiodło się, musisz użyć kompozycji.

Sposób, w jaki to działa, polega na tym, że masz obiekt Animal. W ramach tego obiektu dodajesz następnie kolejne obiekty, które nadają wymagane właściwości i zachowania.

Na przykład:

  • Bird rozszerza Animal wdraża IFlier
  • Horse rozszerza narzędzia Animal IHerbivore, IQuadruped
  • Pegasus rozszerza Animal implementuje IHerbivore, IQuadruped, IFlier

Teraz IFlierwygląda to tak:

 interface IFlier {
     Flier getFlier();
 }

BirdWygląda więc tak:

 class Bird extends Animal implements IFlier {
      Flier flier = new Flier();
      public Flier getFlier() { return flier; }
 }

Teraz masz wszystkie zalety dziedziczenia. Możesz ponownie użyć kodu. Możesz mieć kolekcję IFliers i możesz wykorzystać wszystkie inne zalety polimorfizmu itp.

Jednak masz również pełną elastyczność dzięki kompozycji. Możesz zastosować dowolną liczbę różnych interfejsów i kompozytowych klas podkładowych do każdego typuAnimal - z taką samą kontrolą, jaką potrzebujesz, nad konfiguracją każdego bitu.

Strategia Pattern alternatywne podejście do kompozycji

Alternatywnym podejściem w zależności od tego, co i jak robisz, jest posiadanie Animalklasy bazowej zawierającej kolekcję wewnętrzną, aby zachować listę różnych zachowań. W takim przypadku używasz czegoś bliższego Wzorcowi Strategii. To daje korzyści pod względem uproszczenia kodu (na przykład Horsenie trzeba nic wiedzieć o Quadrupedlub Herbivore), ale jeśli nie zastosujesz również podejścia interfejsu, stracisz wiele zalet polimorfizmu itp.


Podobną alternatywą może być również użycie klas typów, chociaż nie są one tak naturalne w Javie (musisz użyć metod konwertujących itp.), To wprowadzenie może być przydatne, aby zrozumieć pomysł: typeclassopedia.bitbucket.org
Gábor Bakos

1
To znacznie lepsze rozwiązanie niż podejście zalecane w przyjętej odpowiedzi. Na przykład, jeśli później chcę dodać „kolor dzioba” do interfejsu Birda, mam problem. Pegasus to kompozyt, który bierze elementy z koni i ptaków, ale nie jest w pełni koniem ani ptakiem. W tym scenariuszu użycie kompozycji ma sens.
JDB wciąż pamięta Monikę z

Ale getFlier()trzeba go ponownie zaimplementować dla każdego gatunku ptaków.
SMUsamaShah

1
@ LifeH2O Podziel je na bloki o wspólnej funkcjonalności, a następnie daj im to. czyli może masz MathsTeacheri EnglishTeacherjak dziedziczenie Teacher, ChemicalEngineer, MaterialsEngineeretc dziedziczą Engineer. Teacheri Engineerobie implementują Component. To Personma po prostu listę Components i możesz nadać im do tego odpowiednie Components Person. tj. person.getComponent(Teacher.class), person.getComponent(MathsTeacher.class)itd.
Tim B,

1
To najlepsza odpowiedź. Z reguły dziedziczenie reprezentuje „jest”, a interfejs reprezentuje „może”. Pegaz to zwierzę, które potrafi latać i chodzić. Ptak to zwierzę, które potrafi latać. Koń to zwierzę, które może chodzić.
Robear

43

Mam głupi pomysł:

public class Pegasus {
    private Horse horseFeatures; 
    private Bird birdFeatures; 

   public Pegasus(Horse horse, Bird bird) {
     this.horseFeatures = horse;
     this.birdFeatures = bird;
   }

  public void jump() {
    horseFeatures.jump();
  }

  public void fly() {
    birdFeatures.fly();
  }
}

24
To zadziała, ale nie podoba mi się takie podejście (Wrappper), ponieważ wtedy wygląda na to, że Pegaz MA konia, a zamiast tego jest koniem.
Pablo Lozano

Dziękuję Ci. Nie mogłem się powstrzymać przed opublikowaniem pomysłu. Niby wiem, że to głupie, ale nie widziałem DLACZEGO to głupie ...
Pavel Janicek

3
To prawie jak nieodkryta wersja podejścia do kompozycji z odpowiedzi Tima B.
Stephan,

1
Jest to mniej więcej akceptowany sposób, aby to zrobić, chociaż powinieneś mieć również coś takiego jak IJumps z metodą „skoku”, która jest zaimplementowana przez Horse i Pegasus oraz IFlies z metodą „latania”, która jest zaimplementowana przez Birda i Pegasusa.
MatsT

2
@Pablo no, a Pegasus POSIADA konia i ma birdFeatures. +1 za odpowiedź, ponieważ utrzymuje kod w prostocie, w przeciwieństwie do bardziej zgrabnych, tworzących klasy, właściwych rozwiązań Java.
JaneGoodall

25

Czy mogę zasugerować koncepcję pisania na klawiaturze ?

Najprawdopodobniej miałbyś tendencję do rozszerzania interfejsu typu Bird and a Horse na Pegaza, ale pisanie typu kaczego sugeruje, że powinieneś raczej dziedziczyć zachowanie . Jak już wspomniano w komentarzach, pegaz nie jest ptakiem, ale potrafi latać. Więc twój Pegaz powinien raczej dziedziczyć Flyable-interface i powiedzmy Gallopable-interface.

Ten rodzaj koncepcji jest używany we wzorcu strategii . Podany przykład pokazuje, jak w rzeczywistości a dziedziczy kaczka FlyBehavioura QuackBehaviouri nadal nie może być kaczki, np RubberDuck, który nie może latać. Mogliby również Duckrozszerzyć Birdklasę a, ale wtedy zrezygnowaliby z pewnej elastyczności, ponieważ każdy Duckmógłby latać, nawet biedni RubberDuck.


19

Technicznie rzecz biorąc, można rozszerzyć tylko jedną klasę naraz i zaimplementować wiele interfejsów, ale kładąc ręce na inżynierię oprogramowania, sugerowałbym raczej rozwiązanie specyficzne dla problemu, na które nie ma odpowiedzi. Nawiasem mówiąc, dobrą praktyką OO jest nie rozszerzanie konkretnych klas / tylko rozszerzanie klas abstrakcyjnych, aby zapobiec niechcianemu zachowaniu dziedziczenia - nie ma czegoś takiego jak „zwierzę” i nie ma użycia obiektu zwierzęcego, a jedynie konkretne zwierzęta.


13

W Javie 8, która jest nadal w fazie rozwoju od lutego 2014 r., Można użyć domyślnych metod, aby uzyskać coś w rodzaju C ++ - jak wielokrotne dziedziczenie. Możesz również rzucić okiem na ten samouczek, który pokazuje kilka przykładów, z którymi łatwiej jest rozpocząć pracę niż oficjalna dokumentacja.


1
Należy jednak pamiętać, że jeśli zarówno Bird, jak i Horse mają domyślną metodę, nadal napotkasz problem z diamentem i będziesz musiał zaimplementować go oddzielnie w swojej klasie Pegasus (lub uzyskać błąd kompilatora).
Mikkel Løkke

@Mikkel Løkke: Klasa Pegasus musi zdefiniować przesłonięcia dla niejednoznacznych metod, ale może je zaimplementować, po prostu delegując do jednej z super metod (lub obu w wybranej kolejności).
Holger,

12

Trzymanie konia w stajni z półdrzwiami jest bezpieczne, ponieważ koń nie może przejść przez półdrzwi. Dlatego założyłem usługę zakwaterowania koni, która przyjmuje dowolny przedmiot typu koń i umieszcza go w stajni z półdrzwiami.

Czy więc koń jest jak zwierzę, które potrafi latać nawet koń?

Kiedyś dużo myślałem o dziedziczeniu wielokrotnym, ale teraz, gdy programuję od ponad 15 lat, nie obchodzi mnie już wdrażanie wielokrotnego dziedziczenia.

Najczęściej, kiedy próbowałem poradzić sobie z projektem, który wskazywał na wielokrotne dziedziczenie, później przychodziłem do wiadomości, że tęskniłem za zrozumieniem domeny problemu.

LUB

Jeśli wygląda jak kaczka i kwacze jak kaczka, ale potrzebuje baterii, prawdopodobnie masz złą abstrakcję .


Jeśli poprawnie odczytałem twoją analogię, to mówisz, że na początku interfejsy wydają się świetne, ponieważ pozwalają ominąć problemy projektowe, np. Możesz użyć cudzego API, wymuszając na swoich klasach ich interfejsy. Ale po kilku latach zdałeś sobie sprawę, że problem to zły projekt.
CS

8

Java nie ma problemu z dziedziczeniem wielokrotnym, ponieważ nie ma dziedziczenia wielokrotnego. Jest to zgodne z projektem, aby rozwiązać rzeczywisty problem wielokrotnego dziedziczenia (problem z diamentami).

Istnieją różne strategie łagodzenia tego problemu. Najbardziej natychmiast osiągalnym jest obiekt Composite, który sugeruje Pavel (zasadniczo jak radzi sobie z tym C ++). Nie wiem, czy wielokrotne dziedziczenie przez linearyzację C3 (lub podobne) jest na kartach przyszłości Javy, ale wątpię w to.

Jeśli twoje pytanie jest akademickie, to poprawnym rozwiązaniem jest to, że Ptak i Koń są bardziej konkretne i fałszywe jest założenie, że Pegaz to po prostu ptak i koń razem wzięci. Bardziej poprawne byłoby stwierdzenie, że Pegaz ma pewne nieodłączne właściwości wspólne z Ptakami i Koniami (to znaczy, że mogą mieć wspólnych przodków). Można to wystarczająco modelować, jak wskazuje odpowiedź Moritza.


6

Myślę, że to zależy w dużej mierze od twoich potrzeb i tego, jak twoje klasy zwierząt mają być użyte w twoim kodzie.

Jeśli chcesz mieć możliwość korzystania z metod i funkcji implementacji Horse i Bird w klasie Pegasus, możesz zaimplementować Pegaza jako kompozycję Bird and a Horse:

public class Animals {

    public interface Animal{
        public int getNumberOfLegs();
        public boolean canFly();
        public boolean canBeRidden();
    }

    public interface Bird extends Animal{
        public void doSomeBirdThing();
    }
    public interface Horse extends Animal{
        public void doSomeHorseThing();
    }
    public interface Pegasus extends Bird,Horse{

    }

    public abstract class AnimalImpl implements Animal{
        private final int numberOfLegs;

        public AnimalImpl(int numberOfLegs) {
            super();
            this.numberOfLegs = numberOfLegs;
        }

        @Override
        public int getNumberOfLegs() {
            return numberOfLegs;
        }
    }

    public class BirdImpl extends AnimalImpl implements Bird{

        public BirdImpl() {
            super(2);
        }

        @Override
        public boolean canFly() {
            return true;
        }

        @Override
        public boolean canBeRidden() {
            return false;
        }

        @Override
        public void doSomeBirdThing() {
            System.out.println("doing some bird thing...");
        }

    }

    public class HorseImpl extends AnimalImpl implements Horse{

        public HorseImpl() {
            super(4);
        }

        @Override
        public boolean canFly() {
            return false;
        }

        @Override
        public boolean canBeRidden() {
            return true;
        }

        @Override
        public void doSomeHorseThing() {
            System.out.println("doing some horse thing...");
        }

    }

    public class PegasusImpl implements Pegasus{

        private final Horse horse = new HorseImpl();
        private final Bird bird = new BirdImpl();


        @Override
        public void doSomeBirdThing() {
            bird.doSomeBirdThing();
        }

        @Override
        public int getNumberOfLegs() {
            return horse.getNumberOfLegs();
        }

        @Override
        public void doSomeHorseThing() {
            horse.doSomeHorseThing();
        }


        @Override
        public boolean canFly() {
            return true;
        }

        @Override
        public boolean canBeRidden() {
            return true;
        }
    }
}

Inną możliwością jest użycie systemu jednostka-składnik zamiast dziedziczenia do definiowania zwierząt. Oczywiście oznacza to, że nie będziesz mieć indywidualnych klas Java zwierząt, ale zamiast tego będą one definiowane tylko przez ich komponenty.

Niektóre pseudokody dla podejścia Entity-Component-System mogą wyglądać następująco:

public void createHorse(Entity entity){
    entity.setComponent(NUMER_OF_LEGS, 4);
    entity.setComponent(CAN_FLY, false);
    entity.setComponent(CAN_BE_RIDDEN, true);
    entity.setComponent(SOME_HORSE_FUNCTIONALITY, new HorseFunction());
}

public void createBird(Entity entity){
    entity.setComponent(NUMER_OF_LEGS, 2);
    entity.setComponent(CAN_FLY, true);
    entity.setComponent(CAN_BE_RIDDEN, false);
    entity.setComponent(SOME_BIRD_FUNCTIONALITY, new BirdFunction());
}

public void createPegasus(Entity entity){
    createHorse(entity);
    createBird(entity);
    entity.setComponent(CAN_BE_RIDDEN, true);
}

4

możesz mieć hierarchię interfejsów, a następnie rozszerzać swoje klasy z wybranych interfejsów:

public interface IAnimal {
}

public interface IBird implements IAnimal {
}

public  interface IHorse implements IAnimal {
}

public interface IPegasus implements IBird,IHorse{
}

a następnie zdefiniuj swoje klasy zgodnie z potrzebami, rozszerzając określony interfejs:

public class Bird implements IBird {
}

public class Horse implements IHorse{
}

public class Pegasus implements IPegasus {
}

1
Albo może po prostu: Publiczna klasa Pegasus przedłuża Animal Implements Horse, Bird
Batman

OP jest już świadomy tego rozwiązania, szuka innego sposobu, aby to zrobić
Yogesh

@Batman, oczywiście, że może, ale jeśli chce rozszerzyć hierarchię, musiałby zastosować to podejście
richardtz,

IBirdi IHorsepowinien wdrożyć IAnimalzamiastAnimal
oliholz

@Yogesh, masz rację. Przeoczyłem miejsce, w którym to stwierdza. Co mam teraz zrobić jako „nowicjusz”, usunąć odpowiedź lub zostawić ją tam ?, dziękuję.
richardtz

4

Ehm, twoja klasa może być podklasą tylko dla 1 innej, ale nadal możesz mieć zaimplementowanych tyle interfejsów, ile chcesz.

Pegaz to w rzeczywistości koń (jest to szczególny przypadek konia), który potrafi latać (co jest „umiejętnością” tego specjalnego konia). Z drugiej strony można powiedzieć, że Pegaz to ptak, który potrafi chodzić i jest czteronożny - wszystko zależy od tego, jak łatwiej będzie Ci napisać kod.

Tak jak w Twoim przypadku możesz powiedzieć:

abstract class Animal {
   private Integer hp = 0; 
   public void eat() { 
      hp++; 
   }
}
interface AirCompatible { 
   public void fly(); 
}
class Bird extends Animal implements AirCompatible { 
   @Override
   public void fly() {  
       //Do something useful
   }
} 
class Horse extends Animal {
   @Override
   public void eat() { 
      hp+=2; 
   }

}
class Pegasus extends Horse implements AirCompatible {
   //now every time when your Pegasus eats, will receive +2 hp  
   @Override
   public void fly() {  
       //Do something useful
   }
}

3

Interfejsy nie symulują wielokrotnego dziedziczenia. Twórcy Javy uważali, że wielokrotne dziedziczenie jest błędne, więc w Javie nie ma czegoś takiego.

Jeśli chcesz połączyć funkcjonalność dwóch klas w jedną - skorzystaj z kompozycji obiektów. To znaczy

public class Main {
    private Component1 component1 = new Component1();    
    private Component2 component2 = new Component2();
}

A jeśli chcesz ujawnić pewne metody, zdefiniuj je i pozwól im delegować wywołanie do odpowiedniego kontrolera.

Tutaj mogą się przydać interfejsy - jeśli Component1implementuje interfejs Interface1i Component2implementuje Interface2, możesz zdefiniować

class Main implements Interface1, Interface2

Abyś mógł używać obiektów zamiennie tam, gdzie pozwala na to kontekst.

Więc z mojego punktu widzenia nie możesz mieć problemu z diamentami.


Nie jest źle, tak samo jak bezpośrednie wskaźniki pamięci, typy bez znaku i przeciążenie operatora; po prostu nie jest konieczne wykonanie tej pracy. Java została zaprojektowana jako szczupły język łatwy do przyswojenia. Nie wymyślaj i miej nadzieję na najlepsze, to dziedzina wiedzy, a nie domysłów.
Gimby,


3
  1. Zdefiniuj interfejsy do definiowania możliwości. Możesz zdefiniować wiele interfejsów dla wielu możliwości. Te możliwości mogą być realizowane przez określone zwierzę lub ptaka .
  2. Użyj dziedziczenia, aby ustanowić relacje między klasami, udostępniając niestatyczne i niepubliczne dane / metody.
  3. Użyj wzoru Decorator_pattern, aby dynamicznie dodawać możliwości. Pozwoli to zmniejszyć liczbę klas i kombinacji dziedziczenia.

Spójrz na poniższy przykład, aby lepiej zrozumieć

Kiedy używać wzoru dekoratora?


2

Aby zmniejszyć złożoność i uprościć język, w Javie nie jest obsługiwane dziedziczenie wielokrotne.

Rozważmy scenariusz, w którym A, B i C to trzy klasy. Klasa C dziedziczy klasy A i B. Jeśli klasy A i B mają tę samą metodę i wywołujesz ją z obiektu klasy potomnej, wywołanie metody klasy A lub B będzie niejednoznaczne.

Ponieważ błędy czasu kompilacji są lepsze niż błędy czasu wykonania, java renderuje błąd czasu kompilacji, jeśli odziedziczysz 2 klasy. Więc niezależnie od tego, czy masz tę samą metodę, czy inną, teraz wystąpi błąd czasu kompilacji.

class A {  
    void msg() {
        System.out.println("From A");
    }  
}

class B {  
    void msg() {
        System.out.println("From B");
    }  
}

class C extends A,B { // suppose if this was possible
    public static void main(String[] args) {  
        C obj = new C();  
        obj.msg(); // which msg() method would be invoked?  
    }
} 

2

Do rozwiązania problemu wielokrotnego dziedziczenia w Javie używany jest → interfejs

J2EE (core JAVA) Uwagi Mr. KVR Strona 51

Dzień - 27

  1. Interfejsy są zasadniczo używane do tworzenia typów danych zdefiniowanych przez użytkownika.
  2. W odniesieniu do interfejsów możemy osiągnąć koncepcję wielokrotnego dziedziczenia.
  3. Dzięki interfejsom możemy osiągnąć koncepcję polimorfizmu, dynamicznego wiązania, a tym samym możemy poprawić wydajność programu JAVA na zmianę przestrzeni pamięci i czasu wykonywania.

Interfejs to konstrukcja zawierająca zbiór czysto niezdefiniowanych metod lub interfejs to zbiór czysto abstrakcyjnych metod.

[…]

Dzień - 28:

Składnia-1 do ponownego wykorzystania funkcji interfejsów do klasy:

[abstract] class <clsname> implements <intf 1>,<intf 2>.........<intf n>
{
    variable declaration;
    method definition or declaration;
};

W powyższej składni clsname reprezentuje nazwę klasy, która dziedziczy cechy z 'n' liczby interfejsów. „Implements” to słowo kluczowe, które służy do dziedziczenia funkcji interfejsu (interfejsów) do klasy pochodnej.

[…]

Syntax-2 dziedziczenie „n” liczby interfejsów do innego interfejsu:

interface <intf 0 name> extends <intf 1>,<intf 2>.........<intf n>
{     
    variable declaration cum initialization;
    method declaration;
};

[…]

Składnia-3:

[abstract] class <derived class name> extends <base class name> implements <intf 1>,<intf 2>.........<intf n>
{
  variable declaration;
  method definition or declaration;
};
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.