Ereditarietà nella programmazione imperativa

2

La mia prima introduzione alla programmazione è stata Java, che è stato orribile, quindi ho appreso Actionscript3 che è stato bello ... "Il punto è" OOP è stata la mia introduzione alla programmazione, dove ho continuato a ottenere una carriera in PHP e mentre posso scrivere con sicurezza programmi / script in lingue imperative non sono così comodo da farlo.

Il motivo principale è perché non riesco a capire come i linguaggi imperativi / procedurali possano essere estesi nello stesso modo in cui le lingue OOP usano il polimorfismo e la sostituzione.

Ora sto cercando di imparare altre lingue e potrei anche avere un crack in C, solo se riuscirò a capire i principi di base per sostituire la funzionalità.

Qualcuno può spiegare i principi di base usati per estendere la funzionalità di una libreria / funzione senza riscrivere quella intera funzione. Perché in OOP dovresti sovrascrivere un metodo di una classe e possibilmente chiamare il metodo super per mantenere un po 'del comportamento originale.

    
posta Flosculus 31.10.2014 - 16:32
fonte

3 risposte

6

Se vuoi un buon esempio di OOP completo in C, dai un'occhiata a GTK + . Per lo più, i costruttori dispongono di molte regole per inizializzare elementi come i vtables e tenere traccia di una gerarchia di tipi. Creare il tuo oggetto per GTK + è un buon modo per imparare ciò che la maggior parte delle lingue OO fa per te dietro le quinte.

Una cosa che imparerai scrivendo del codice reale è che i metodi virtuali non sono così comuni o necessari come penseresti che sarebbero. I programmatori hanno la tendenza a esagerare nell'ereditarietà. La maggior parte delle volte, sai esattamente quale funzione statica devi chiamare e stai solo condividendo una semplice struttura dati tra diverse funzioni. Lo estendi semplicemente creando una nuova funzione che funziona sulla stessa struttura dati. Questo è il modo in cui funziona la maggior parte del codice procedurale.

Quando hai veramente bisogno di metodi virtuali, basta aggiungere i puntatori di funzione a quella struttura dati che passi. Quindi creare una funzione wrapper per incapsulare la brutta sintassi del puntatore di funzione. Vedi qui per un esempio di come è fatto in GObject, la libreria di oggetti di GTK.

Se è necessario aggiungere potenzialmente campi, la struttura dati che si passa in genere ha un void* o qualcosa in cui è possibile memorizzare dati specifici dell'implementazione.

Ancora una volta, scrivi una vera app in GTK + come esercizio di apprendimento, e penso che troverai i modelli un po 'familiari, una volta superata la sintassi.

    
risposta data 31.10.2014 - 21:55
fonte
1

Penso che il modo più semplice per capire questo è guardando un semplice esempio in C: la funzione qsort del libreria C standard . Come utente di tale libreria, puoi fornire una funzione di confronto arbitraria a qsort qui senza toccare o ricompilare la libreria.

Un altro buon esempio è stato mostrato in questo precedente post SO . Esalta come costruire l'equivalente di una classe String in C e come emulare l'ereditarietà.

    
risposta data 01.11.2014 - 07:46
fonte
0

Questo recente post sul blog di Bob Martin è pertinente. In esso, definisce i modi convenienti per implementare il polimorfismo come elemento essenziale di ciò che rende un linguaggio orientato agli oggetti.

Alla luce di ciò, possiamo leggere la tua domanda come "come faccio la programmazione orientata agli oggetti in un linguaggio non orientato agli oggetti?" La risposta a questo è abbastanza semplice: non lo fai se puoi eventualmente aiutarlo. Sì, è possibile implementarlo in molte di queste lingue, ma i risultati sono sempre spiacevoli e difficili da leggere o lavorare. Se il tuo problema comporta la necessità di gestire diversi tipi di dati in modi simili (ad esempio se si tratta essenzialmente di un problema polimorfico), allora usa un linguaggio orientato agli oggetti. Se devi lavorare in una lingua non-oo, prova a unificare i tuoi dati in modo tale che non dovrai mai gestire tipi diversi nello stesso posto nel tuo codice. Impara a non preoccuparti di ripetere te stesso: è molto più difficile da evitare nel codice non-oo. E usa i puntatori di funzione come ultima risorsa, quando ne hai assolutamente bisogno solo.

    
risposta data 29.11.2014 - 15:38
fonte