Nella prospettiva del linguaggio di programmazione, cosa si intende per sottotipo? Ho sentito che "L'ereditarietà non è sottotipizzazione". Quindi quali sono le differenze tra eredità e sottotipo?
Nella prospettiva del linguaggio di programmazione, cosa si intende per sottotipo? Ho sentito che "L'ereditarietà non è sottotipizzazione". Quindi quali sono le differenze tra eredità e sottotipo?
Risposte:
[Non ho riflettuto a fondo sui problemi dei sistemi di tipo orientati agli oggetti, ma dirò quello che so per avviare la discussione.]
Diciamo che è un sottotipo di se tutti i valori di tipo possono essere utilizzati in ogni contesto in cui sono previsti valori di tipoOppure, per dirla in altro modo, i valori di tipo possono "mascherarsi" come valori di tipo
Se tale mascheramento non pone problemi con il controllo del tipo, vale a dire, l'inserimento di valori di tipo in cui sono necessari valori di tipo continua a digitare il controllo, lo chiamiamo "sottotipo strutturale" . Se non causa problemi con il comportamento, vale a dire che tale inserimento non altera il comportamento previsto, allora lo chiamiamo "sottotitolo comportamentale" . (Il "comportamento previsto" dovrà essere formalizzato separatamente e sono possibili molte nozioni di comportamento.)
Il sottotipo strutturale non garantisce il sottotipo comportamentale poiché la struttura di un tipo potrebbe corrispondere per motivi accidentali. Tuttavia, definire il comportamento previsto non è facile. Pertanto, molti linguaggi di programmazione utilizzano un punto intermedio, in cui l'utente deve dichiarare quale tipo è un sottotipo di cui. Questo è indicato come "sottotipo nominale" . Vedi la domanda sul sottotipo implicito vs esplicitoper una discussione di questo problema. L'idea è che il programmatore debba garantire il sottotipo comportamentale per tutti i sottotipi dichiarati usando la propria ingegnosità. La lingua non può offrire alcun aiuto. Tuttavia, tutti i sottotipi dichiarati devono essere almeno sottotipi strutturali. Altrimenti, il programma non riuscirebbe a digitare il controllo. La lingua può aiutare a garantire questo. (Alcuni linguaggi di programmazione non dispongono di sistemi di tipi sufficienti per garantire ciò in fase di compilazione. In tal caso, l'errore di tipo verrebbe rilevato in fase di esecuzione o potrebbero essere generati risultati errati. Tali fori di tipo sono ovviamente indesiderabili.)
Quando si definiscono sottoclassi nei programmi orientati agli oggetti, in genere si aggiungono campi (o metodi) visibili pubblicamente. Nella maggior parte dei linguaggi di programmazione, tali sottoclassi sono considerate sottotipi nominali . La domanda è se si tratti anche di sottotipi strutturali . Se non lo sono, vale a dire, il linguaggio di programmazione consente di dichiarare sottotipi nominali che non sono sottotipi strutturali, allora ci sarebbero dei buchi nel linguaggio di programmazione.
In casi semplici, l'aggiunta di campi funziona correttamente. Il tipo di superclasse prevede un numero inferiore di campi rispetto al tipo di sottoclasse. Pertanto, se si inserisce un'istanza di una sottoclasse in cui è prevista un'istanza della propria sottoclasse, il programma ignorerà semplicemente i campi aggiuntivi forniti e nulla andrà storto.
Tuttavia, se la superclasse o sottoclasse ha metodi che accettano argomenti dello stesso tipo di se stesso o restituiscono risultati dello stesso tipo di se stesso, sorgono problemi. Quindi il tipo di interfaccia della sottoclasse non è un sottotipo strutturale di quello della superclasse. I linguaggi di programmazione ampiamente utilizzati di tipo sicuro come Java non consentono tali sottoclassi. Pertanto, limitano la lingua per ottenere la sicurezza del tipo. Si dice che il linguaggio di programmazione Eiffel abbia sacrificato la sicurezza dei tipi per ottenere flessibilità . Se si progetta un sistema di tipo forte che mantiene la flessibilità, si deve rinunciare al principio secondo cui le sottoclassi danno origine a sottotipi. Da qui il titolo dell'articolo "L'ereditarietà non è sottotitolata". Gli autori propongono una diversa nozione di sottotipo di ordine superiore che funziona invece. Kim Bruce ha anche una proposta strettamente correlata chiamata "matching" che ottiene lo stesso effetto. Vedere questo presentazione . Utile anche un position paper di Andrew Black.
La comunità della semantica è probabilmente in errore per aver ignorato in gran parte il problema. Tradizionalmente lo abbiamo considerato un problema pratico di ingegneria dei sistemi di tipo di scarso interesse teorico. Se così non fosse e ci fosse davvero qualche lavoro di semantica nell'area, spero che le altre persone li citino.