Подтвердить что ты не робот

Java: если A расширяет B и B расширяет Object, то это множественное наследование

У меня только что было интервью, и меня задали вопрос.

Интервьюер. Поддерживает ли Java множественное наследование?

Me - Нет

Интервьюер. Каждый класс в Java расширяет класс Object (кроме класса Object) и если мы извне расширяем один класс, например

Class A extends B{
  // some code here
}

то вы можете сказать, что класс A расширяет класс B и класс Object, что означает, что это множественное наследование. Итак, как вы можете сказать, что Java не поддерживает множественное наследование?

Me. На самом деле класс B расширяет класс Object, поэтому, когда вы расширяете класс B в классе A, класс A распространяется косвенным образом на объект Object. Это многоуровневое наследование, а не множественное наследование.

Но мой ответ не удовлетворил его.

Правильно ли мой ответ? Или где я ошибаюсь? Что на самом деле происходит внутри страны?

4b9b3361

Ответ 1

Мой ответ правильный?

Да, в основном, и, конечно же, в контексте, который вы описываете. Это не множественное наследование:

Object ^- ClassA ^- ClassB

Это то, что вы сказали, однократное наследование с несколькими уровнями.

Это множественное наследование: унаследовать от двух или более баз, которые не имеют отношения "есть" друг к другу; который наследуется от несвязанных строк или из строк, которые ранее расходились (в Java, так как Object всегда является базой, он будет последним):

Object ^- ClassA, Object ^- ClassB, ClassA ^- ClassC, ClassB ^- ClassC

(Image credits: http://yuml.me в режиме "scruffy" )

Внутри Что происходит на самом деле?

Только то, что вы сказали: Есть несколько уровней. Когда компилятор разрешает член в экземпляре:

obj.member

... он видит, что тип obj (который в этом случае является классом, например ClassB) имеет member, либо потому, что он предоставляет его напрямую, либо имеет его через наследование. Во время выполнения JVM использует member объект на самом деле.


Причина, по которой я сказал "в основном" выше, заключается в том, что Java имеет интерфейсы, а с Java 8 имеет "методы по умолчанию" на интерфейсах. Это немного усложняет ситуацию, но ваш ответ об уровнях правилен в контексте того, что вы описали интервьюера, говорящего о Object, ClassA и ClassB.

Интерфейсы всегда позволяли в Java, чтобы что-то имело "отношение" к двум различным типам: тип класса, на который он наследует, и любой из нескольких типов интерфейсов, которые он реализует. Интерфейсы без методов по умолчанию не являются множественным наследованием практическим способом (класс должен обеспечить реализацию), но они сделали возможным, чтобы класс имел несколько "является" отношением от несвязанных деревьев типов. (Я не академик, возможно, академик будет утверждать, что они обеспечивают множественное наследование академическим способом.)

В Java 8 интерфейсы могут предоставлять стандартные реализации методов, которые они определяют, что действительно стирает линии даже на практическом уровне. Давайте посмотрим на это немного глубже:

Скажем, что ClassA:

class ClassA {
    void doSomething() {
        // Code here
    }
}

и Interface1:

interface Interface1 {
    default void doSomethingElse() { // Requires Java 8
        // Code here
    }
}

и, наконец, ClassB:

class ClassB extends ClassA implements Interface1 {
}

ClassB наследует реализацию doSomething от ClassA. Но он также получает "default" версию doSomethingElse от Interface1. Мы не реализовали его в ClassB, но ClassB не является абстрактным: у него действительно есть doSomethingElse. Он получает это от интерфейса. Я использовал слово "получает", а не "наследует", но это похоже на наследование метода по умолчанию.

Это в основном многократное наследование "свет" (как в "легком пиве" ). Он выполняет бесконечные проблемы с истинным множественным наследованием, например:

  • Каким должен быть тип super? (Ответ Java 8: ClassA)
  • В каком порядке вы запускаете конструкторы? (Ответ Java 8: цепочка конструкторов Single-lineage, интерфейсы не имеют конструкторов.)
  • Запускаете ли вы конструкторы, которые вы наследуете более одного раза, более одного раза? (Ответ Java 8: вы не можете наследовать конструкторы более одного раза, интерфейсы их не имеют.)
  • Что произойдет, если вы наследуете несколько методов с одной и той же сигнатурой? (Ответ Java 8: если один из них относится к базовому классу, тот, который использовал; реализация базового класса может переопределить метод по умолчанию для нескольких интерфейсов. Если у вас есть несколько методов по умолчанию с одной и той же сигнатурой с разных интерфейсов при компиляции, time, это ошибка времени компиляции. Если интерфейс был изменен без повторного компиляции класса и возникает ситуация во время выполнения, это исключение среды выполнения IncompatibleClassChangeError, указывающее конфликтующие методы по умолчанию.)

Ответ 2

вы правы

Прежде всего, класс Object - это класс super/base/parent для каждого класса, включая пользовательские классы.

Таким образом, даже если мы не будем указывать его явно, пользовательские классы по умолчанию расширяют класс Object.

его как

class A 
class B extends A

 but compiler read it as 
class A extends Object
class B extends A

оказалось

для более подробной информации проверьте java-документацию для наследования

Ответ 3

Мой ответ правильный?

Вы абсолютно правы, говоря, что это многоуровневое наследование, а не множественное наследование.

Только root иерархии Object, все классы не расширяют объект Object отдельно.

Счетчик интервьюера:

Если все классы расширяются Object, то сколько раз конструктор Object будет вызываться на A a = new A();

Ответ будет только один раз, и это будет для корня иерархии.

Ответ 4

Да, вы правы... как указали многие другие. Я просто хотел сказать, что интервью связано не только с техническими знаниями, но и с тем, чтобы придерживаться ваших орудий. Некоторые интервьюеры будут подвергать сомнению ваш ответ не потому, что они хотят знать, уверены ли вы в своих убеждениях, но и чтобы проверить, насколько хорошо вы можете учить других и насколько хорошо вы справляетесь с авторитетной цифрой.

В первом случае, если вы не можете учить других, тогда вы не можете быть наставником. В настоящее время крайне важно нанять кого-то, кто может обучать младших разработчиков... потому что это имеет смысл экономически.

Во втором случае, потому что они не хотят, чтобы вы меняли технические аспекты только потому, что ваш босс попросил вас. Если ваш босс попросит вас удалить все индексы из базы данных, потому что они занимают слишком много места, вы бы это сделали? Не могли бы вы попытаться убедить своего босса? Как?

Ответ 5

Does java support multiple inheritance?

Да для интерфейсов, но не для классов.

Класс и интерфейс могут реализовывать множество интерфейсов, но расширяют только один класс

Ответ 6

Ответ правильный!

class Object //for illustration purpose
{
}

class B
{
}

class A extends B
{
}

Когда вы создаете объект класса A, происходит цепочка конструкторов . т.е. конструктор класса A вызывает неявно super() и, следовательно, вызывается конструктор класса B, который затем неявно вызывает его суперкласс, который является классом Object.

В java класс расширяет только один класс, потому что конструктор этого класса вызывает только один суперклассический конструктор. Это неверно в случае интерфейсов, поскольку у них нет конструкторов.

Также, когда объект класса A создан и предположим, что вы определили конструкторы обоих классов A и B, сначала выполняется конструктор класса B, а затем конструктор класса A.

Ответ 7

Ваш ответ прав, потому что java не поддерживает множественное наследование от классов. Java поддерживает множественное наследование от интерфейсов, и никакого другого наследования нет. Но вы можете использовать состав классов, но это другая история.

Ответ 8

Ваш ответ совершенно в порядке. Вы можете объяснить промежутки многоуровневой поддержки наследования от класса Object в java

Ответ 9

Какой тупой вопрос.

Конечно, Java не поддерживает множественное наследование, а интерфейсы не наследуются.

Наследование происходит только через "extends", а не через "реализует". Когда вы определяете класс, реализующий несколько интерфейсов, вы не говорите, что это расширение этих интерфейсов, но оно будет иметь такое же поведение, и поведение (по крайней мере, на Java) не определяет наследование.

Чтобы Java поддерживала множественное наследование, ему нужно было бы поддерживать что-то вроде

public class MI extends Object, MyOtherClass

Какая Java не может.

Ну, может быть, я не получил бы работу, чтобы называть вопрос интервьюера немым:)

Ответ 10

Ваш ответ абсолютно правильный.

Эти типы вопросов попросили просто проверить, является ли кандидат концептуально сильным или нет.

Ну, самый простой и точный ответ на этот вопрос:

"Классы могут быть получены из классов, которые производны от классов, которые производны от классов и т.д., и в конечном итоге получены из самого верхнего класса Object. Такой класс, как говорят, происходит от всех классов наследования цепочка, растянутая назад к объекту."

Пожалуйста, перейдите по этой ссылке https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html