Java: se A estende B e B estende Object, è quell’ereditarietà multipla

Ho appena avuto un’intervista e mi è stata fatta una domanda.

Intervistatore : Java supporta l’ereditarietà multipla?

Io – No

Intervistatore – Ogni class in Java estende l’object di class (ad eccezione dell’object di class) e se esternamente estendiamo una class come

Class A extends B{ // some code here } 

allora puoi dire che la class A estende la class B e la class Object, il che significa che è un’eredità multipla. Quindi, come puoi dire che Java non supporta l’ereditarietà multipla?

Io – In realtà la class B estende l’object di class, quindi quando estendi la class B in class A la class A estende indirettamente la class Object. Questa è ereditarietà a più livelli, non eredità multipla.

Ma la mia risposta non lo ha soddisfatto.

La mia risposta è corretta? O dove sbaglio? Cosa succede realmente internamente?

La mia risposta è corretta?

Sì, soprattutto, e certamente nel contesto che descrivi. Questa non è un’eredità multipla:

Oggetto ^ - ClasseA ^ - ClasseB

È quello che hai detto, eredità singola con più livelli.

Questa è un’eredità multipla: Eredita da due o più basi che non hanno alcuna relazione “è una” tra loro; che sarebbe ereditato da linee non correlate o da linee che prima erano divergenti (in Java, poiché Object è sempre una base, sarebbe quest’ultima):

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

(Crediti immagine: http://yuml.me in modalità “scruffy”)

Internamente Cosa succede in realtà?

Proprio quello che hai detto: ci sono più livelli. Quando il compilatore sta risolvendo un membro su un’istanza:

 obj.member 

… guarda se il tipo di obj (che in questo caso è una class, ad esempio ClassB ) ha un member , o perché lo fornisce direttamente o ClassB ha attraverso l’ereditarietà. Al momento dell’esecuzione, la JVM utilizza il member l’object ha effettivamente.


La ragione per cui ho detto “principalmente” sopra è che Java ha interfacce e, a partire da Java 8, ha “metodi predefiniti” sulle interfacce. Ciò complica un po ‘le cose, ma la tua risposta ai livelli è corretta nel contesto di ciò che hai descritto l’intervistatore che dice di Object , ClassA e ClassB .

Le interfacce hanno sempre reso ansible, in Java, che qualcosa abbia una relazione “è una” con due tipi diversi: un tipo di class da cui eredita e uno qualsiasi dei diversi tipi di interfaccia che implementa . Le interfacce prive di metodi predefiniti non sono ereditarietà multipla in modo pratico (la class deve fornire l’implementazione), ma hanno reso ansible che una class abbia più relazioni “is a” da tipi di alberi non correlati. (Non sono un accademico, è ansible che un accademico sostenga che forniscono eredità multiple in modo accademico).

Con Java 8, le interfacce possono fornire implementazioni predefinite dei metodi che definiscono, il che sfoca davvero le linee anche a livello pratico. Diamo un’occhiata a questo un po ‘più profondamente:

Diciamo che abbiamo ClassA :

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

e Interface1 :

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

e infine ClassB :

 class ClassB extends ClassA implements Interface1 { } 

ClassB eredita l’implementazione di doSomething da ClassA . Ma ottiene anche la versione “predefinita” di doSomethingElse da Interface1 . Non l’abbiamo implementato in ClassB , ma ClassB non è astratto: ha davvero doSomethingElse . Lo ottiene dall’interfaccia . Ho usato la parola “ottiene” piuttosto che “eredita” lì, ma questo assomiglia molto ad ereditare il metodo predefinito.

Questo è fondamentalmente “luce” a eredità multipla (come in “birra leggera”). Fa un end-run attorno ai problemi più spinosi con una vera ereditarietà multipla, come:

  • Quale dovrebbe essere il tipo di super ? (Risposta di Java 8: ClassA )
  • In quale ordine esegui i costruttori? (Risposta di Java 8: concatenamento di costruttori a linea singola, le interfacce non hanno costruttori.)
  • Esegui costruttori che erediti più di una volta, più di una volta? (Risposta di Java 8: non è ansible ereditare i costruttori più di una volta, le interfacce non li hanno).
  • Cosa succede se erediti più metodi con la stessa firma? (Risposta di Java 8: se uno di questi è della class base, è quello che viene utilizzato, l’implementazione di una class base può sovrascrivere il metodo predefinito di più interfacce.Se si hanno più metodi predefiniti con la stessa firma da diverse interfacce in fase di compilazione tempo, è un errore in fase di compilazione: se un’interfaccia è stata modificata senza che la class venga ricompilata e la situazione si presenti in fase di runtime, si tratta di un’eccezione IncompatibleClassChangeError runtime che elenca i metodi di conflitto in conflitto.)

hai ragione

Prima di tutto, la class Object è la class super / base / genitore di ogni class, comprese le classi definite dall’utente.

Quindi, anche se non lo menzioniamo esplicitamente, le classi definite dall’utente estendono la class Object per impostazione predefinita.

è come

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

dimostrato

per maggiori dettagli controlla questa documentazione java per l’ereditarietà

La mia risposta è corretta?

Hai assolutamente ragione nel dire che è un’eredità multi-livello e non un’eredità multipla.

Solo la radice della gerarchia è Object , tutte le classi non estendono individualmente l’Oggetto.

Un contatore per l’intervistatore:

Se tutte le classi estendono Object , allora quante volte il costruttore di Object sarà chiamato su A a = new A();

La risposta è una sola volta e ciò sarà per la radice della gerarchia.

  • Multiple ereditarietà e class Object

Sì, hai ragione … come molti altri hanno sottolineato. Volevo solo dire che le interviste non riguardano solo la conoscenza tecnica, ma riguardano anche l’attaccamento alle armi. Alcuni intervistatori metteranno in dubbio la tua risposta, non perché vogliono sapere se sei sicuro delle tue convinzioni, ma anche per testare quanto bene puoi insegnare agli altri e quanto bene gestisci una figura autorevole.

Per il primo punto, se non puoi insegnare agli altri, non puoi essere un mentore. Oggigiorno è fondamentale assumere qualcuno in grado di istruire gli sviluppatori junior …. perché ha senso economicamente.

Per il secondo punto, perché non vogliono che tu cambi aspetti tecnici solo perché il tuo capo ti ha chiesto di farlo. Se il tuo capo ti chiede di rimuovere tutti gli indici dal database perché occupano troppo spazio, lo faresti? Vuoi provare a convincere il tuo capo altrimenti? Come?

 Does java support multiple inheritance? 

Sì per le interfacce ma non per le classi.

La class e l’interfaccia possono implementare molte interfacce ma estendono solo una class

La tua risposta è corretta!

 class Object //for illustration purpose { } class B { } class A extends B { } 

Quando si crea un object di class A, avviene il concatenamento del costruttore . cioè il costruttore della class A chiama in modo implicito super() e quindi viene invocato il costruttore della class B, che quindi chiama implicitamente la sua super class che è la class Object.

In java, una class estende solo una singola class perché il costruttore di quella class chiama solo un costruttore super-class. Questo non è vero nel caso di interfacce poiché non hanno costruttori.

Inoltre, quando viene creato un object di class A e si assume che siano stati definiti i costruttori di entrambe le classi A e B, allora viene eseguito prima il costruttore della class B e successivamente il costruttore della class A.

La tua risposta è perfettamente a posto. Puoi spiegare gli interms del supporto dell’ereditarietà multilivello dalla class Object in java

La tua risposta è giusta, perché java non supporta l’ereditarietà multipla dalle classi. Java supporta l’ereditarietà multipla dalle interfacce e non esiste altra ereditarietà. Ma puoi usare la composizione delle classi, ma questa è un’altra storia.

Che domanda stupida.

Ovviamente Java non supporta l’ereditarietà multipla e le interfacce non sono ereditate.

L’ereditarietà avviene solo tramite “extends”, non tramite “implements”. Quando definisci una class implementa diverse interfacce, non stai dicendo che sarà un’estensione di quelle interfacce, ma avrà lo stesso comportamento e comportamento (almeno in Java), non definirà l’ereditarietà.

Perché Java supporti l’ereditarietà multipla, dovrebbe supportare qualcosa di simile

 public class MI extends Object, MyOtherClass 

Quale Java non può.

Beh, forse non troverei il lavoro per chiamare la domanda dell’intervistatore stupido 🙂

La tua risposta è assolutamente corretta.

Questi tipi di domande vengono poste solo per verificare se un candidato è concettualmente forte o meno.

Bene, la risposta più semplice e precisa a questa domanda è qui:

Le classi possono essere derivate da classi derivate da classi derivate da classi, e così via, e in definitiva derivate dalla class più alta, Object. Tale class si dice che discenda da tutte le classi nella catena di ereditarietà che si estende indietro all’object.

Si prega di fare riferimento a questo link https://docs.oracle.com/javase/tutorial/java/IandI/subclasss.html

La risposta che hai dato è corretta. L’intervistatore ha sbagliato:

Processo interno

 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... 

quindi, Java non supporta l’ereditarietà multipla.

Se si desidera verificare questo processo, generare “javadoc” per la class A e verificare i risultati.