Domanda

Ho sentito che esiste un modo per ingannare l'ereditarietà singola e implementare l'ereditarietà multipla in Java.Qualcuno sa come implementarlo (senza utilizzare l'interfaccia)?

Solo per curiosità ;-)

È stato utile?

Soluzione

Certo che puoi, ma è complicato e dovresti davvero considerare se è questa la strada che vuoi seguire.
L'idea è di utilizzare l'ereditarietà basata sull'ambito abbinata a quella basata sul tipo.Che è un discorso tipografico per dire che per scopi interni, le classi interne "ereditano" metodi e campi della classe esterna.È un po' come i mixin, in cui la classe esterna è mescolata alla classe interna, ma non è così sicura, poiché puoi modificare lo stato della classe esterna e usare i suoi metodi.
Gilad Bracha (uno dei principali progettisti del linguaggio Java) ha scritto a carta discutendone.Quindi, supponiamo che tu voglia condividere alcuni metodi per uso interno tra alcune classi non correlate (ad esempio, per la manipolazione delle stringhe), puoi crearne sottoclassi come classi interne di una classe che ha tutti i metodi necessari e le sottoclassi potrebbero usare metodi sia dalle loro superclassi che dalla classe esterna.

Ad ogni modo, è complicato per le classi complesse e potresti ottenere la maggior parte delle funzionalità utilizzando importazioni statiche (da Java 5 in poi).Ottima domanda per colloqui di lavoro e quiz da pub, però ;-)

Altri suggerimenti

SeparareL'ereditarietà multipla non è supportata da Java, invece dispone di interfacce per servire allo stesso scopo.Nel caso in cui sei irremovibile nell'usare l'ereditarietà multipla, dovrebbe essere fatto in C++.

L'uso della composizione anziché dell'ereditarietà tende ad aggirare questo problema.Questo in realtà aiuta molto anche con la testabilità, quindi è una buona pratica in generale.

Se vuoi semplicemente che il tuo tipo "si comporti" come molti altri tipi, puoi comunque ereditare da tutte le interfacce che desideri;ovviamente non puoi "prendere in prestito" i dettagli di implementazione da questi.

Credo che la ragione fondamentale per cui Java non supporta l'ereditarietà multipla sia la stessa di C#;tutti gli oggetti alla fine derivano da Object e avere più percorsi per la stessa classe base è ambiguo per il compilatore.Ambiguo == Cattivo, quindi il compilatore non lo consente.

È invece possibile simulare l'ereditarietà multipla tramite delega.Vedere Questo articolo per un esempio.

Puoi imbrogliare un po' (e sottolineo un po') utilizzando le istanze java.lang.reflect.Proxy.

Questo in realtà ti consente solo di aggiungere interfacce extra e delegare le loro chiamate a un'altra istanza in fase di runtime.

Come persona che guida e tutora i nuovi sviluppatori, sarei inorridito se qualcuno mi mostrasse il codice che fa questo.Reflection è uno di quegli strumenti che devi davvero comprendere e avere una buona conoscenza di Java prima di iniziare.Personalmente l'ho fatto solo una volta, ed è stato per creare del codice su cui non avevo il controllo e implementare alcune interfacce che si aspettava un altro codice su cui non avevo alcun controllo (è stato un trucco veloce quindi non ho dovuto scrivere e mantenere troppo codice adesivo).

Utilizzo interfaceS.Puoi implementarne quante ne desideri.Di solito puoi usare qualche variante su Modello composito (GoF) per poter riutilizzare il codice di implementazione se lo si desidera.

È necessario fare attenzione a distinguere l'ereditarietà dell'interfaccia (essenzialmente l'ereditarietà di un contratto per fornire particolari servizi) dall'ereditarietà dell'implementazione (ereditarietà dei meccanismi di implementazione).

Java fornisce l'ereditarietà dell'interfaccia da parte di implementa meccanismo e tu Potere hanno ereditarietà di più interfacce.

L'ereditarietà dell'implementazione è il si estende meccanismo e ne hai solo una versione.Fai Veramente è necessaria l'ereditarietà di implementazioni multiple?Scommetto di no, è pieno zeppo di conseguenze spiacevoli, a meno che tu non sia comunque un programmatore Eiffel.

Probabilmente potresti "simularlo" gestendo esplicitamente l'insieme di superclassi e utilizzando la riflessione per cercare in tutte le superclassi il metodo di destinazione.Non vorrei farlo in produzione, ma potrebbe essere un interessante programma giocattolo.Probabilmente potresti fare un sacco di cose strane sfruttando la riflessione, creando classi al volo e invocando il compilatore in modo programmatico.

JAVA non supporta l'ereditarietà multipla.

Puoi farlo implementare più interfacce e alcuni lo vedono come un modo per aggirare il problema.Personalmente devo ancora utilizzare l'ereditarietà multipla, quindi non riesco davvero a capirne il fascino.

Normalmente quando qualcuno suggerisce l'ereditarietà multipla in C# o JAVA è dovuto al fatto che "potrebbero" in C++.Sono un fan del "solo perché puoi non significa che dovresti".Dato che C# e JAVA non lo supportano, perché provare a forzarlo a fare qualcosa per cui non è stato progettato.Questo non vuol dire che ci siano casi unici in cui l'empoly è una tecnica valida, solo che il codice può essere solitamente sottoposto a refactoring per non averne bisogno.

Ci stavo pensando un po' di più e mi sono reso conto che mentre i proxy dinamici funzionano (è così che funziona l'RMI (usato?)), se vuoi davvero questo tipo di funzionalità faresti meglio a guardare la programmazione orientata agli aspetti (AOP) usando qualcosa come AspectJ (eclipse.org/aspectj).

In questo modo puoi inserire diversi aspetti diversi in una classe, dandoti un'eredità pseudo mixin, senza le gerarchie di ereditarietà orribilmente fragili.

Come tutti gli altri hanno sottolineato, volere/avere bisogno di ereditarietà multipla generalmente indica che non stai affrontando il problema dalla giusta prospettiva.Per cominciare, ricorda il principio GoF di "preferire la composizione all'ereditarietà"!

C'è stato uno sforzo per portare i mixin in Java.Dai un'occhiata a questo link: http://www.disi.unige.it/person/LagorioG/jam/

Utilizzando le classi interne, questo è ciò che a volte preferisce anche il C++: Idioma della classe interiore.

Sì, puoi dire che è un trucco ed è molto interessante non puoi ereditare più classi in una singola classe ma è possibile implementare più interfacce in una classe come

public class parents implements first, second{

}

ma ricorda, devi sovrascrivere i metodi dichiarati nelle interfacce.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top