Есть ли интерфейсы наследовать от класса объекта в Java


157

Интерфейсы наследуют от Objectкласса в Java?

Если нет, то как мы можем вызвать метод класса объекта на экземпляре интерфейса

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

interface Employee {
}

@EJP, технически говоря, не имеет значения, что содержит класс java / io / Serializable.class. Я думаю, что вы путаете Java Lang Spec со спецификацией JVM.
aioobe

@aioobe Поскольку я не упомянул ни одну из этих спецификаций, я не понимаю вашу точку зрения. Serializableинтерфейс, максимально простой; бег javapна нем говорит вам, от чего он наследует; и это продиктовано Спецификацией языка Java. Если вы думаете, что JVM Spec где-то входит в это, пожалуйста, просветите нас.
Маркиз Лорн

2
@EJP, вопрос касается языка Java (то есть спецификации языка Java). То, что когда-либо содержит java / io / Serializable.class, связано с тем, что говорится в спецификации JVM. Технически говоря, нет никакой гарантии, что между характеристиками двух спецификаций существует взаимно-однозначное соответствие.
aioobe

Я подробно рассказал об этом в недавнем сообщении в блоге .
августа

Ответы:


161

Интерфейсы наследуют от Objectкласса в Java?

Нет, они не И нет никакого общего «корневого» интерфейса, неявно унаследованного всеми интерфейсами (как в случае с классами) в этом отношении. (*)

Если нет, то как мы можем вызвать метод класса объекта на экземпляре интерфейса

Интерфейс неявно объявляет один метод для каждого открытого метода в Object. Таким образом, equalsметод неявно объявляется как член в интерфейсе (если он уже не наследует его от суперинтерфейса).

Это подробно объясняется в Спецификации языка Java, § 9.2 Члены интерфейса .

9.2 Члены интерфейса

[...]

  • Если интерфейс не имеет прямых суперинтерфейсов, то этот интерфейс неявно объявляет открытый метод абстрактного члена m с сигнатурой s , типом возврата r и выбрасывает условие t, соответствующее каждому методу открытого экземпляра m с сигнатурой s , типом возврата r и предложением throws t объявляется вObject , если интерфейс явно не объявил метод с той же сигнатурой, тем же типом возврата и совместимым предложением throws.

[...]


Этот пост был переписан как статья здесь .


(*) Обратите внимание, что понятие подтипа не эквивалентно наследованию от : Интерфейсы без суперинтерфейса действительно являются подтипами Object( § 4.10.2. Подтипирование между типами классов и интерфейсов ), даже если они не наследуются от Object.


1
@aioobe Если мы реализуем какой-либо интерфейс, то почему бы нам не дать реализацию метода «равно» в классе, который реализует этот интерфейс. Согласно моим понятиям, мы должны реализовать методы интерфейса в реализации класса, иначе класс будет абстрактным.
Викас Мангал

1
Вам не нужно (повторно) реализовывать унаследованные методы. Посмотрите на этот пример . Другими словами, equals уже определен и унаследован от класса, реализующего интерфейс.
aioobe

3
Я понял суть здесь. Но один вопрос - зачем нам это? Какая разница, если бы методы Objectкласса не были объявлены в интерфейсе?
Викас Мангал

2
Если бы этого не было, программа в вопросе не скомпилировалась бы. Есть equalsметод по Employeeинтерфейсу.
aioobe

1
Этот вопрос и ответ все еще напоминают мне, что даже после опыта я должен сосредоточиться на том, чтобы сделать свои основы сильными.
Ананд Дж. Kadhi

13

Object является супертипом любого интерфейса [1]

Однако, интерфейс не implements, extendsили, «унаследуют от» Object .

У JLS есть специальное предложение для добавления Objectметодов в интерфейсы [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


Это самый точный ответ. Должен быть принятым. Например, метод, который принимает java.lang.Object, также принимает ссылку любого типа интерфейса. Более того, вы можете Objectнеявно приводить интерфейс без какой-либо ошибки компилятора.
NME

12

На самом деле в каждом .classфайле есть поле суперкласса , включая те, которые представляют интерфейсы.

Для интерфейса это всегда указывает на java.lang.Object. Но это не используется ни для чего.

Еще один способ взглянуть на это:

interface MyInterface {
    // ...
}

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

Здесь приведение (Object) paramвсегда допустимо, что означает, что каждый тип интерфейса является подтипом java.lang.Object.


4
Файл .class является артефактом файла .java. Спорить о том, почему что-то работает на языке Java, взглянув на результирующий файл .class, - рассуждение обратное.
aioobe

Object obj = (Object) param; не выдает ошибку компиляции. Но методы MyInterface (общедоступные) не видны объекту. Поэтому не могу предположить, что MyInterface - каждый тип интерфейса является подтипом java.lang.Object
sabarinathan u

5

Это потому, что employee e = ...читает, что есть класс, который реализует employee , и назначается переменной e. Каждый класс, который реализует интерфейс, неявно расширяет Object, поэтому, когда вы это делаете e.equals(null), язык знает, что у вас есть класс, который является подтипом employee.

JVM выполнит проверку вашего кода во время выполнения (например, throw NullPointerException).


3

Если интерфейс наследует класс объекта, как мы можем получить доступ к методам класса объекта через ссылку на тип интерфейса.
Нет. Интерфейс не наследует Objectкласс, но он обеспечивает доступ ко всем методам Objectкласса. Члены интерфейса:

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

объявляет открытый абстрактный метод-член, соответствующий каждому общедоступному методу экземпляра, объявленному в Objectклассе .
Это ошибка времени компиляции, если интерфейс явно объявляет такой метод m в случае, когда объявлено, что m находится finalв Object.

Теперь ясно, что все суперинтерфейсы имеют abstractметод-член, соответствующий каждому publicметоду экземпляра, объявленному в Object.

источник: http://ohmjavaclasses.blogspot.com/2011/11/is-intreface-inherits-object-clashow.html


0

Любой класс, реализующий любой интерфейс, также является производным от Objectопределения.


0

«Все ссылочные типы наследуются от java.lang.Object . Классы, перечисления, массивы и интерфейсы являются ссылочными типами ».

Цитируется по адресу : http://docs.oracle.com/javase/tutorial/reflect/class/index.html Второе предложение должно быть понятным.


Classes, enums, and arrays (which all inherit from java.lang.Object) as well as interfaces are all reference types: это не говорит, что интерфейс наследует от Object. Только классы, перечисления и массивы.
Number945

Они изменили это :)
dalvarezmartinez1

Даже если «они изменили это» (в чем я сомневаюсь), учебник может быть неправильным. Нормативной ссылкой является Спецификация языка Java (JLS).
Лью Блох
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.