Czy interfejsy dziedziczą po klasie Object w java

157

Czy interfejsy dziedziczą z Objectklasy w Javie?

Jeśli nie, to w jaki sposób możemy wywołać metodę klasy obiektu na instancji interfejsu

public class Test {
    public static void main(String[] args) {
        Employee e = null;
        e.equals(null);
    }
}

interface Employee {
}
stawy
źródło
56
+1, doskonałe pytanie.
aioobe
@EJP, technicznie rzecz biorąc, nie ma znaczenia, co zawiera java / io / Serializable.class. Myślę, że mylisz specyfikację Java Lang ze specyfikacją JVM.
aioobe
@aioobe Ponieważ nie wspomniałem o żadnej z tych specyfikacji, nie rozumiem twojego punktu. Serializablejest interfejsem, najprostszym z możliwych; bieganie javappo nim mówi ci, z czego dziedziczy; i jest to podyktowane specyfikacją języka Java. Jeśli sądzisz, że gdzieś w grę wchodzi specyfikacja JVM, proszę nas oświecić.
Markiz Lorne,
2
@EJP, pytanie dotyczy języka Java (tj. Specyfikacji języka Java). To, co zawiera java / io / Serializable.class, jest powiązane z tym, co mówi specyfikacja JVM. Z technicznego punktu widzenia nie ma gwarancji, że między cechami obu specyfikacji istnieje zgodność jeden do jednego.
aioobe
Omówiłem to w ostatnim poście na blogu .
aioobe

Odpowiedzi:

161

Czy interfejsy dziedziczą z Objectklasy w Javie?

Nie, nie robią. I nie ma też wspólnego interfejsu "root", domyślnie dziedziczonego przez wszystkie interfejsy (jak w przypadku klas). (*)

Jeśli nie, to w jaki sposób możemy wywołać metodę klasy obiektu na instancji interfejsu

Interfejs niejawnie zadeklarował jedną metodę dla każdej metody publicznej w programie Object. Więcequals sposób metoda jest niejawnie zadeklarowana jako element członkowski w interfejsie (chyba że dziedziczy ją już z superinterfejsu).

Jest to szczegółowo wyjaśnione w specyfikacji języka Java, § 9.2 Członkowie interfejsu .

9.2 Członkowie interfejsu

[…]

  • Jeśli interfejs nie ma bezpośrednich superinterfejsów, to interfejs niejawnie deklaruje publiczną abstrakcyjną metodę składową m z sygnaturą s , zwracanym typem r i rzuca klauzulę t odpowiadającą każdej metodzie wystąpienia publicznego m z sygnaturą s , zwracanym typem r i throws klauzulą t wObject , chyba że metoda z taką samą sygnaturą, tym samym zwracanym typem i zgodną klauzulą ​​throws jest jawnie zadeklarowana przez interfejs.

[…]


Ten post został przepisany jako artykuł tutaj .


(*) Należy zauważyć, że pojęcie bycia podtypem nie jest równoznaczne z dziedziczeniem po : Interfejsy bez super interfejsu są rzeczywiście podtypami Object( § 4.10.2. Podtypy między typami klas i interfejsów ), mimo że nie dziedziczą po Object.

aioobe
źródło
1
@aioobe Jeśli zaimplementujemy dowolny interfejs, to dlaczego nie damy implementacji metody „equals” w klasie implementującej ten interfejs. Zgodnie z moimi koncepcjami musimy implementować metody interfejsu w implementacji klasy, w przeciwnym razie klasa będzie abstrakcyjna.
Vikas Mangal
1
Nie musisz (ponownie) implementować dziedziczonych metod. Spójrz na ten przykład . Innymi słowy, equals jest już zdefiniowane i dziedziczone do klasy implementującej interfejs.
aioobe
3
Mam o co chodzi. Ale jedno pytanie - dlaczego tego potrzebujemy? Jaką różnicę miałoby to, gdyby metody Objectklasy nie zostały zadeklarowane w interfejsie?
Vikas Mangal
2
Gdybyśmy tego nie mieli, program, o którym mowa, nie skompilowałby się. W interfejsie jest włączona equalsmetoda Employee.
aioobe,
1
To pytanie i odpowiedź wciąż przypominają mi, że nawet po doświadczeniu powinienem skupić się na wzmocnieniu moich podstaw.
Anand J. Kadhi
13

Object jest nadtypem dowolnego interfejsu [1]

Jednak interfejs nie robi implements, extendsalbo, „dziedziczy z” Object .

JLS ma specjalną klauzulę do dodawania Objectmetod do interfejsów [2]

[1] http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.10.2

[2] http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.2

nieoceniony
źródło
To najdokładniejsza odpowiedź. Powinien być akceptowany. Np. Metoda, która przyjmuje a, java.lang.Objectprzyjmie również referencje dowolnego typu interfejsu. Co więcej, możesz rzutować interfejs na Objectniejawnie bez żadnego błędu kompilatora.
nme
12

W rzeczywistości w każdym .classpliku znajduje się pole nadklasy , łącznie z tymi, które reprezentują interfejsy.

W przypadku interfejsu zawsze wskazuje java.lang.Object. Ale to nie jest używane do niczego.

Można na to inaczej spojrzeć:

interface MyInterface {
    // ...
}

public myMethod(MyInterface param) {
    Object obj = (Object) param;
    // ...
}

Tutaj rzutowanie (Object) paramjest zawsze prawidłowe, co oznacza, że ​​każdy typ interfejsu jest podtypem java.lang.Object.

finnw
źródło
4
Plik .class jest artefaktem pliku .java. Argumentowanie, dlaczego coś działa w języku Java, patrząc na wynikowy plik .class, jest rozumowaniem wstecznym.
aioobe
Object obj = (Object) param; nie zgłasza błędu kompilacji. Ale metody MyInterface (public) nie są widoczne dla obj. Dlatego nie można założyć, że MyInterface to każdy typ interfejsu jest podtypem java.lang.Object
sabarinathan u
5

Dzieje się tak, ponieważ employee e = ...czyta, że ​​istnieje klasa, która implementuje employee i jest przypisana do zmiennej e. Każda klasa, która implementuje interfejs, rozszerza Object niejawnie, więc kiedy to robisz e.equals(null), język wie, że masz klasę, która jest podtypememployee .

JVM będzie sprawdzać kod w czasie wykonywania (np. Rzut NullPointerException).

Buhake Sindi
źródło
Odpowiedzi powinny być zgodne z konwencjami nazewnictwa.
Lew Bloch
3

Czy interfejs dziedziczy klasę Object, w jaki sposób możemy uzyskać dostęp do metod klasy obiektu poprzez odniesienie do typu interfejsu?
No Interface nie dziedziczy Objectklasy, ale zapewnia dostęp do wszystkich metod Objectklasy. Członkami interfejsu są:

Those members declared in the interface.
Those members inherited from direct superinterfaces.
If an interface has no direct superinterfaces, then the interface implicitly 

deklaruje publiczną abstrakcyjną metodę składową odpowiadającą każdej metodzie wystąpienia publicznego zadeklarowanej w Objectklasie .
Jest to błąd czasu kompilacji, jeśli interfejs jawnie deklaruje taką metodę m w przypadku, gdy zadeklarowano, że m znajduje się finalw Object.

Teraz jest jasne, że wszystkie superinterfejsy mają abstractmetodę składową odpowiadającą każdej publicmetodzie instancji zadeklarowanej w Object.

źródło: http://ohmjavaclasses.blogspot.com/2011/11/is-intreface-inherits-object-clashow.html

Sheo
źródło
0

Z Objectdefinicji również wywodzi się każda klasa implementująca dowolny interfejs .

jabal
źródło
0

Wszystkie typy odwołań dziedziczą po java.lang.Object . Wszystkie klasy, wyliczenia, tablice i interfejsy są typami odwołań ”.

Cytat z: http://docs.oracle.com/javase/tutorial/reflect/class/index.html Drugie zdanie powinno być jasne.

dalvarezmartinez1
źródło
Classes, enums, and arrays (which all inherit from java.lang.Object) as well as interfaces are all reference types: nie mówi, że interfejs dziedziczy po Object. Tylko klasy, wyliczenia i tablice.
Number945
Zmienili to :)
dalvarezmartinez1
Nawet jeśli „zmienili to” (w co wątpię), samouczek może się mylić. Odniesieniem normatywnym jest specyfikacja języka Java (JLS).
Lew Bloch