web-dev-qa-db-fra.com

Java: si A étend B et B étend Object, est-ce que l'héritage multiple

Je viens d'avoir une entrevue et on m'a posé une question. 

Interviewer - Java prend-il en charge l'héritage multiple?

moi - non

Interviewer - Chaque classe en Java étend la classe Object (sauf la classe Object) et si nous étendons de manière externe une classe comme

Class A extends B{
  // some code here
}

vous pouvez alors dire que la classe A étend la classe B et la classe Object, ce qui signifie qu'il s'agit d'un héritage multiple. Alors, comment pouvez-vous dire que Java ne supporte pas l'héritage multiple?

Me - En fait, la classe B étend la classe Object. Ainsi, lorsque vous étendez la classe B en classe A, la classe A étend la classe Object indirectement. Il s'agit d'un héritage à plusieurs niveaux, pas d'un héritage multiple.

Mais ma réponse ne l'a pas satisfait.

Est-ce que ma réponse est correcte? Ou est-ce que je me trompe? Que se passe-t-il en interne?

29
Ankit Sharma

Ma réponse est correcte?

Oui, surtout et certainement dans le contexte que vous décrivez. Ce n'est pas un héritage multiple:

Object ^- ClassA ^- ClassB

C'est ce que vous avez dit: héritage unique à plusieurs niveaux.

Il s’agit d’un héritage multiple: hériter de deux ou plusieurs bases qui n’ont pas de relation "est une" relation entre elles; ce serait hériter de lignes sans relation, ou de lignes qui avaient divergé auparavant (en Java, puisque Object est toujours une base, ce serait la dernière):

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

(Crédits image: http://yuml.me en mode "scruffy")

En interne Que se passe-t-il réellement?

Exactement ce que vous avez dit: il y a plusieurs niveaux. Lorsque le compilateur résout un membre sur une instance:

obj.member

... il cherche à voir si le type de obj (qui dans ce cas est une classe, disons ClassB) a member, soit parce qu'il le fournit directement, soit par héritage. Au moment de l'exécution, la machine virtuelle Java utilise la variable member que possède réellement l'objet.


La raison pour laquelle j'ai dit "principalement" ci-dessus est que Java a des interfaces, et depuis Java 8, il a des "méthodes par défaut" sur les interfaces. Cela complique un peu les choses, mais votre réponse à propos des niveaux est correcte dans le contexte de ce que vous avez décrit comme interview par l'intervieweur à propos de Object, ClassA et ClassB.

Les interfaces ont toujours rendu possible, en Java, d'avoir une relation "est une" avec deux types différents: un type de classe dont il hérite, et n'importe lequel de plusieurs types d'interface, il implémente . Les interfaces sans méthodes par défaut ne sont pas des héritages multiples de manière pratique (la classe doit fournir l'implémentation), mais elles permettent à une classe d'avoir des relations multiples "est une" à partir d'arbres de type non liés. (Je ne suis pas un universitaire, il est possible qu'un universitaire soutienne qu'ils fournissent un héritage multiple de manière académique.)

Avec Java 8, les interfaces peuvent fournir des implémentations par défaut des méthodes qu’elles définissent, ce qui brouille vraiment les lignes, même au niveau pratique. Regardons cela un peu plus en profondeur:

Disons que nous avons ClassA:

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

et Interface1:

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

et enfin ClassB:

class ClassB extends ClassA implements Interface1 {
}

ClassB hérite de l'implémentation de doSomething de ClassA. Mais il aussi obtient la version "par défaut" de doSomethingElse à partir de Interface1. Nous ne l'avons pas implémenté dans ClassB, mais ClassB n'est pas abstrait: il a vraiment doSomethingElse. Il l'obtient à partir de interface . J'ai utilisé le mot "obtient" plutôt que "hérite", mais cela ressemble à un lot ou à l'héritage de la méthode par défaut.

Ceci est fondamentalement un héritage multiple "léger" (comme dans "bière légère"). Il résout les problèmes les plus épineux avec un véritable héritage multiple, comme:

  • Quel devrait être le type de super? (Réponse de Java 8: ClassA)
  • Dans quel ordre exécutez-vous les constructeurs? (Réponse de Java 8: chaînage des constructeurs à lignée unique, les interfaces n'ont pas de constructeurs.)
  • Exécutez-vous des constructeurs dont vous héritez plus d'une fois, plus d'une fois? (Réponse de Java 8: vous ne pouvez pas hériter de constructeurs plus d'une fois, les interfaces n'en ont pas.)
  • Que se passe-t-il si vous héritez de plusieurs méthodes avec la même signature? (Réponse de Java 8: si l’un d’eux appartient à la classe de base, c’est celle qui est utilisée; l’implémentation d’une classe de base peut remplacer la méthode par défaut de plusieurs interfaces. Si vous avez plusieurs méthodes par défaut avec la même signature à partir d’interfaces différentes à la compilation- Si une interface a été modifiée sans que la classe soit recompilée et que la situation se présente à l'exécution, il s'agit d'une exception d'exécution IncompatibleClassChangeError répertoriant les méthodes par défaut en conflit.)
39
T.J. Crowder

vous avez raison 

Tout d'abord, la classe Object est la classe super/base/parent de toutes les classes, y compris les classes définies par l'utilisateur.

Ainsi, même si nous ne le mentionnons pas explicitement, les classes définies par l'utilisateur étend la classe Object par défaut.

c'est comme

class A 
class B extends A

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

prouvé

pour plus de détails, vérifiez ceci Documentation Java sur l'héritage

7
MSR

Ma réponse est correcte?

Vous êtes absolument correct en disant qu'il s'agit d'un héritage à plusieurs niveaux et non d'un héritage multiple.

Seul root de la hiérarchie est Object, toutes les classes non étendent individuellement Object.

Un compteur de l'intervieweur:

Si toutes les classes étendent Object, combien de fois le constructeur de Object sera appelé sur A a = new A();

La réponse n’est donnée qu’une fois, ce sera pour la racine de la hiérarchie.

5
Narendra Pathai

Oui, vous avez raison ... comme beaucoup d'autres l'ont fait remarquer. Je voulais juste dire que les entretiens ne portent pas seulement sur des connaissances techniques, mais aussi sur le fait de rester fidèles à vos armes. Certains intervieweurs vont interroger votre réponse, non pas parce qu'ils veulent savoir si vous êtes sûr de vos convictions, mais aussi pour vérifier si vous pouvez bien enseigner aux autres et comment vous gérez un personnage faisant autorité.

Pour le premier point, si vous ne pouvez pas enseigner aux autres, vous ne pouvez pas être un mentor. De nos jours, il est crucial de recruter quelqu'un qui puisse encadrer les développeurs juniors ... parce que c'est logique du point de vue économique.

Pour le deuxième point, car ils ne veulent pas que vous changiez d’aspects techniques simplement parce que votre patron vous l’a demandé. Si votre patron vous demande de supprimer tous les index de la base de données car ils prennent trop de place, le feriez-vous? Souhaitez-vous essayer de convaincre votre patron autrement? Comment?

3
Alexandre Santos
Does Java support multiple inheritance?

Oui pour les interfaces mais pas pour les classes. 

La classe et l'interface peuvent implémenter beaucoup d'interfaces mais n'allonge qu'une classe

2
mohamed sulibi

Votre réponse est correcte!

class Object //for illustration purpose
{
}

class B
{
}

class A extends B
{
}

Lorsque vous créez un objet de classe A, constructeur chaînant se produit. I.e. le constructeur de la classe A appelle implicitement super() et, par conséquent, le constructeur de la classe B est appelé, qui appelle alors implicitement sa super classe qui est la classe Object. 

En Java, une classe n'étend qu'une seule classe car le constructeur de cette classe n'appelle qu'un seul constructeur de super classe. Ce n'est pas vrai dans le cas des interfaces car elles n'ont pas de constructeur.

De même, lorsqu'un objet de classe A est créé, et supposons que vous avez défini les constructeurs des classes A et B, le constructeur de la classe B est exécuté en premier, puis le constructeur de la classe A.

2
Santosh Pavate

Quelle question idiote.

Bien entendu, Java ne prend pas en charge l'héritage multiple et les interfaces ne sont pas héritées.

L'héritage ne se produit que via "extend", pas via "implements". Lorsque vous définissez une classe qui implémente plusieurs interfaces, vous ne dites pas qu'il s'agira d'une extension de ces interfaces, mais que ce comportement aura le même comportement et qu'un comportement (du moins en Java) ne définit pas l'héritage.

Pour que Java prenne en charge les héritages multiples, il doit prendre en charge des éléments tels que

public class MI extends Object, MyOtherClass

Quel Java ne peut pas.

Eh bien, peut-être que je n'aurais pas le poste pour avoir appelé la question idiote de l'intervieweur :)

1
Cindy Langdon

Votre réponse est correcte, car Java ne prend pas en charge l'héritage multiple de classes. Java prend en charge plusieurs héritages d'interfaces et il n'y a pas d'autre héritage. Mais vous pouvez utiliser la composition de classes, mais c'est une autre histoire.

1
FruitDealer

Votre réponse est parfaitement correcte. Vous pouvez expliquer la prise en charge de l'héritage multiniveau à partir de la classe Object en Java.

1

Votre réponse est absolument correcte.

Ces types de questions ont simplement pour but de vérifier si un candidat est conceptuellement fort ou non.

Eh bien, la réponse la plus simple et précise à cette question est la suivante:

" Les classes peuvent être dérivées de classes dérivées de classes dérivées de classes, etc., et finalement dérivées de la classe la plus haute, Object. Une telle classe est dite descendante de toutes les classes de l'héritage. chaîne qui retourne à l'objet. "

Veuillez vous référer à ce lien https://docs.Oracle.com/javase/tutorial/Java/IandI/subclasses.html

0
rags147

La réponse que vous avez donnée est correcte. L'intervieweur s'est trompé:

Processus interne

if suppose Class A Doesn't extends any other class 
then ---> Class B extends Java.lang.Object 
then ---> Class A extends B
then class A also inherited the property of Java 'Object' class...

alors, Java ne supporte pas l'héritage multiple.

Si vous souhaitez vérifier ce processus, générez simplement 'javadoc' pour votre classe A et vérifiez les résultats.

0
Nithiyananthan Mgp