Czy interfejs może rozszerzyć wiele interfejsów w Javie?

126

Czy interfejs może rozszerzyć wiele interfejsów w Javie? Ten kod wygląda na prawidłowy w moim IDE i kompiluje się:

interface Foo extends Runnable, Set, Comparator<String> { }

ale słyszałem, że wielokrotne dziedziczenie nie jest dozwolone w Javie. Dlaczego wydaje się, że istnieje wyjątek dla interfejsów?

Prateek
źródło
3
Które artykuły mówią, że to niemożliwe? Albo się mylą, albo źle je zrozumiałeś i mówią o klasach, a nie o interfejsach.
7
To pytanie wydaje się być
niezwiązane
4
@StephenC Jeśli znalazł sprzeczne artykuły, powinien je opublikować. W ten sposób ludzie wiedzą, że nie powinni czytać tych artykułów ...
Ale ja nie jestem
10
Odpowiedź na to pytanie pozwoliła mi zaoszczędzić czas. Twierdzę, że ma wartość jako ważne pytanie.
xdhmoore
6
pomocne pytanie, zrobiłem to spodziewając się, że moje IDE wyrzuci kilka ostrzeżeń, byłem zdumiony, że nie widziałem żadnego. Więc nieświadomie wpisałem w google to samo pytanie co operacja, która doprowadziła mnie do tej strony z kilkoma odpowiedziami / potwierdzeniami
Arthur

Odpowiedzi:

170

Tak, możesz to zrobić. Interfejs może rozszerzyć wiele interfejsów, jak pokazano poniżej:

interface Maininterface extends inter1, inter2, inter3 {  
  // methods
}

Pojedyncza klasa może również implementować wiele interfejsów. Co się stanie, jeśli dwa interfejsy mają metodę definiującą tę samą nazwę i podpis?

Jest trudny punkt:

interface A {
    void test();
}

interface B {
    void test();
}

class C implements A, B {

    @Override
    public void test() {

    }     

}

Wtedy pojedyncza implementacja działa dla obu :).

Przeczytaj mój pełny post tutaj:

http://codeinventions.blogspot.com/2014/07/can-interface-extend-multiple.html

Suresh Atta
źródło
@RahulBhadana Metoda abstrakcyjna powinna zastąpić, prawda?
Suresh Atta
13
Co jeśli masz interfejs A void test()zi interfejs B z boolean test()? (Czy to kuzyn problemu z diamentem ?) __Wypróbowałem go i wydarzyła się rozsądna rzecz: niedozwolone, jeśli typ zwracania jest inny.
Daniel
@sureshatta - więc co się dzieje? czy to nazywa oba ?
Fattie
4
Klasa nie zezwala na 2 metody z tym samym podpisem i innym typem zwracania. stackoverflow.com/questions/16149285/…
Ninh Pham
73

Interfejs może przedłużyć wiele interfejsów .

Klasa może zaimplementować wiele interfejsów .

Jednak klasa może rozszerzać tylko jedną klasę .

Uważaj, jak używasz słów extendsi implementskiedy mówisz o interfacei class.

Ale nie jestem klasą opakowującą
źródło
8

Czy interfejs może rozszerzyć wiele interfejsów w Javie?

Odpowiedź brzmi: tak.

Według JLS

Interfejs może być zadeklarowany jako bezpośrednie rozszerzenie jednego lub więcej innych interfejsów, co oznacza, że ​​niejawnie określa wszystkie typy składowe, metody abstrakcyjne i stałe interfejsów, które rozszerza, z wyjątkiem wszystkich typów elementów członkowskich i stałych, które może ukrywać.

Masudul
źródło
JLS = „Specyfikacja języka Java”, która jest autorytatywnym źródłem w tych pytaniach.
Hontvári Levente
6

Na stronie dokumentacji Oracle dotyczącej wielu typów dziedziczenia możemy znaleźć tutaj dokładną odpowiedź . Tutaj powinniśmy najpierw poznać typ wielokrotnego dziedziczenia w java: -

  1. Wielokrotne dziedziczenie stanu.
  2. Wielokrotne dziedziczenie implementacji.
  3. Wielokrotne dziedziczenie typu.

Java ”nie obsługuje wielokrotnego dziedziczenia stanu, ale obsługuje wielokrotne dziedziczenie implementacji z metodami domyślnymi od wersji Java 8 oraz wielokrotne dziedziczenie typów z interfejsami.

Następnie pojawia się pytanie o „problem z diamentami” i jak sobie z tym radzi Java: -

  1. W przypadku wielokrotnego dziedziczenia implementacji, kompilator java podaje błąd kompilacji i prosi użytkownika o jego naprawienie poprzez podanie nazwy interfejsu. Przykład tutaj: -

                interface A {
                    void method();
                }
    
                interface B extends A {
                    @Override
                    default void method() {
                        System.out.println("B");
                    }
                }
    
                interface C extends A { 
                    @Override
                    default void method() {
                        System.out.println("C");
                    }
                }
    
                interface D extends B, C {
    
                }

Więc tutaj otrzymamy błąd, ponieważ: - interfejs D dziedziczy niepowiązane wartości domyślne metody () z typów B i C interfejs D rozszerza B, C

Możesz to naprawić na przykład: -

interface D extends B, C {
                @Override
                default void method() {
                    B.super.method();
                }
            }
  1. W przypadku wielokrotnego dziedziczenia typu java pozwala na to, ponieważ interfejs nie zawiera zmiennych zmiennych i tylko jedna implementacja będzie należała do klasy, więc java nie daje żadnego problemu i pozwala to zrobić.

Podsumowując, możemy powiedzieć, że java nie obsługuje wielokrotnego dziedziczenia stanu, ale obsługuje wielokrotne dziedziczenie implementacji i wielokrotne dziedziczenie typu .

shankar upadhyay
źródło
1
Myślę, że jest to bardziej odpowiednia odpowiedź i bardziej wyjaśnia pytanie. +1
Ketan Joshi
Dziękuję @KetanJoshi To motywuje wiele do prowadzenia :)
Shankara Upadhyay
4

Możesz przedłużyć wiele, Interfacesale nie możesz przedłużyć wielu classes.

Powodem, dla którego w Javie nie jest możliwe rozszerzenie wielu klas, jest złe doświadczenie z C ++, gdzie jest to możliwe.

Alternatywą dla dziedziczenia wielopunktowego jest to, że klasa może implementować wiele interfejsów (lub interfejs może rozszerzać wiele interfejsów)

AlexWien
źródło
2

Myślę, że twoje zamieszanie wiąże się z dziedziczeniem wielokrotnym, w którym robienie tego jest złą praktyką, aw Javie jest to również niemożliwe. Jednak implementowanie wielu interfejsów jest dozwolone w Javie i jest również bezpieczne.

Cem Sultan
źródło