Domanda

Sto cercando di capire se la risposta alla domanda è la stessa in tutti i principali linguaggi orientati agli oggetti;e se non, quindi, come tali lingue diverse.

Supponiamo di avere classe A che definisce i metodi act e jump;metodo act chiamate di metodo jump. A's sottoclasse B esegue l'override del metodo jump (cioè, la sintassi appropriata viene utilizzato per garantire che ogni volta che jump è chiamato, l'attuazione in classe B è utilizzato).

Mi sono oggetto b di classe B.Voglio che si comporti esattamente come se fosse di classe A.In altre parole, voglio il jump per essere eseguita mediante l'attuazione in A.Quali sono le mie opzioni in diverse lingue?

Ad esempio, è possibile raggiungere questo obiettivo con una qualche forma di downcast?O, forse, con la creazione di un oggetto proxy che sa quali sono i metodi per chiamare?

Vorrei evitare di creare un nuovo oggetto di classe A e attenzione a impostare la condivisione dello stato interno tra a e b perché ovviamente non è a prova di futuro, e complicato.Ho anche voler evitare di copiare lo stato di b in un nuovo oggetto di classe A perché ci potrebbe essere un sacco di dati da copiare.

AGGIORNAMENTO

Ho chiesto questa domanda in particolare su Python, ma sembra che questo è impossibile da raggiungere in Python e tecnicamente si può fare...un pò..

Sembra che, a prescindere dalla fattibilità tecnica, c'è un forte argomento contro facendo questo da un punto di vista progettuale.Mi sto chiedendo che in una questione a parte.

È stato utile?

Soluzione

I commenti hanno ribadito: preferisci la composizione rispetto all'eredità.

L'eredità funziona bene quando le sottoclassi hanno differenze comportamentali ben definite dalla loro superclasse, ma spesso raggiungerai un punto in cui quel modello diventa imbarazzante o smette di avere un senso. A quel punto, devi riconsiderare il tuo design.

La composizione è di solito la soluzione migliore. Delegare il comportamento variabile del tuo oggetto a un oggetto (o oggetti) diverso può ridurre o eliminare la necessità di sottoclasse.

Nel tuo caso, le differenze comportamentali tra classe A e classe B potrebbero essere incapsulate nel modello di strategia. È quindi possibile modificare il comportamento della classe A (e della classe B, se ancora necessario) a livello di istanza, semplicemente assegnando una nuova strategia.

Il modello di strategia potrebbe richiedere più codice a breve termine, ma è pulito e mantenebile. Metodo Swizzling, patching di scimmie e tutte quelle cose interessanti che ci consentono di fare il giro nella nostra specifica implementazione del linguaggio sono divertenti, ma il potenziale per effetti collaterali inaspettati è elevato e il codice tende a essere difficile da mantenere.

Altri suggerimenti

Quello che stai chiedendo è completamente non correlato/non supportato dalla programmazione OOP.

Se sottoclassi un oggetto A con classe B e sovrascrivere i suoi metodi, quando un'istanza concreta di B viene creato quindi tutta la nuova implementazione dei metodi di base è associata ad essa (o parliamo di Java o C ++ con tabelle virtuali ecc.).

Hai un oggetto istanziato B.
Perché ti aspetteresti di poter/dovresti/dovresti essere in grado di chiamare il metodo della superclasse se hai superato quel metodo?

Potresti chiamarlo esplicitamente ovviamente ad es. super All'interno del metodo, ma non puoi farlo automaticamente e il casting non ti aiuterà neanche a farlo.

Non riesco a immaginare perché vorresti farlo.
Se è necessario utilizzare la classe A Quindi usa la classe A.
Se è necessario sovrascrivere la sua funzionalità, usa la sua sottoclasse B.

La maggior parte dei linguaggi di programmazione va in qualche problema per supportare la spedizione dinamica delle funzioni virtuali (il caso di chiamare il metodo sovrascritto jump In una sottoclasse anziché l'implementazione della classe madre) - nella misura in cui ci sta aggirando o evitarla è difficile. In generale, la specializzazione/polimorfismo è una caratteristica desiderabile, probabilmente un obiettivo di OOP in primo luogo.

Dai un'occhiata all'articolo di Wikipedia su Funzioni virtuali, che fornisce un'utile panoramica del supporto per le funzioni virtuali in molti linguaggi di programmazione. Ti darà un posto da iniziare quando si considera un linguaggio specifico, nonché i compromessi da pesare quando si guarda a un linguaggio in cui il programmatore può controllare come si comporta la spedizione (vedere la sezione su C ++, per esempio).

Così vagamente, la risposta alla tua domanda è: "No, il comportamento non è lo stesso in tutti i linguaggi di programmazione". Inoltre, non esiste una soluzione indipendente dalla lingua. C ++ potrebbe essere la soluzione migliore se tu bisogno il comportamento.

Si può effettivamente fare questo con Python (una specie), con alcuni terribili hack.Si richiede di implementare qualcosa di simile il wrapper abbiamo discusso nel primo Python-domanda specifica, ma come una sottoclasse di B.È quindi necessario implementare la scrittura di inoltro (l'oggetto wrapper non dovrebbe contenere, lo stato normalmente associati con la gerarchia di classi, è necessario reindirizzare tutti attributo di accesso al sottostante istanza di B.

Ma invece di redirigere il metodo di ricerca per Una e poi chiamare il metodo con il avvolta esempio, si potrebbe chiamare il metodo passando l'oggetto wrapper come self.Questo è legale perché la classe wrapper è una sottoclasse di B, in modo che il wrapper di esempio è un esempio delle classi i cui metodi si sta chiamando.

Questo sarebbe molto strano codice, che richiede di generare dinamicamente le classi di utilizzo di entrambi È-ed È-UNA delle relazioni al tempo stesso.Probabilmente sarebbe anche abbastanza fragili e con risultati bizzarri in un sacco di casi di angolo (in genere non può scrivere 100% perfetta classi wrapper Python esattamente perché questa sorta di strana cosa è possibile).

Io sono completamente lasciando da parte il meteo questa è una buona idea o meno.

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