Esistono lingue OO senza ereditarietà?

22

Durante una revisione del codice oggi, un mio collega ha detto qualcosa di interessante:

prototype is only useful when you need inheritance - and when's inheritance ever a good idea?

Ci ho pensato e mi sono reso conto che di solito uso l'ereditarietà per aggirare il codice mal progettato in primo luogo. Lo stile OO moderno predilige la composizione sull'ereditarietà, ma non conosco alcun linguaggio che abbia preso a cuore questo aspetto e in effetti lo impone .

Esistono linguaggi di programmazione generici con classi, oggetti, metodi, interfacce e così via, che non consentono l'ereditarietà basata sulla classe? (Se un'idea del genere non ha senso, perché no?)

    
posta Benjamin Hodgson 06.10.2014 - 20:22
fonte

3 risposte

18

Mettendo da parte la domanda di la definizione di programmazione orientata agli oggetti la domanda diventa una di "ci sono lingue che usano la composizione? solo e non hanno strumenti per l'ereditarietà? "

La risposta a questo è semplicemente "sì". In viaggio, non c'è modo di fare eredità come si pensa classicamente. Un può incorporare un oggetto in un altro oggetto e estenderlo. Da linguaggio oggetto desorientato ( mirror github ):

type Person struct {
        Name string
}

func (p *Person) Intro() string {
        return p.Name
}

type Woman struct {
        Person
}

func (w *Woman) Intro() string {
        return "Mrs. " + w.Person.Intro()
}

Hai una struttura di persona che ha un nome che è una stringa. Ha una funzione pubblica chiamata Intro che restituisce il nome. La struttura Donna ha anche una funzione per Intro che accede al montante incorporato. E così si possono realizzare le intenzioni dell'eredità usando solo la composizione.

Maggiori informazioni su questo argomento sono disponibili su Esercitazioni su GoLang: ereditarietà e sottoclassi in Go - o la sua quasi somiglianza .

Quindi sì, è possibile avere una lingua OO senza ereditarietà e una esiste.

All'interno di go questo è noto come embedding e offre alle strutture che accludono la possibilità di accedere ai campi incorporati e funziona come se ne avesse anche loro - ma non è una sottoclasse. La filosofia di progettazione può essere trovata nella Domande frequenti: Perché non esiste un'eredità di tipo?

    
risposta data 06.10.2014 - 21:20
fonte
7

Are there any general-purpose programming languages with classes, objects, methods, interfaces, and so on, which disallow class-based inheritance?

Si tratta di una descrizione molto simile a VBA - Visual Basic for Applications, incorporata in Microsoft Office e altri host abilitati per VBA (ad esempio AutoCAD, Sage 300 ERP, ecc.) o anche VB6. La "A" di "Basic" sta per "All-purpose" comunque, quindi c'è la parte "general-purpose".

VB6 / VBA ha classi (e quindi oggetti), metodi e interfacce - puoi definire un'interfaccia ISomething in un modulo di classe come questo:

Option Explicit

Public Sub DoSomething()
End Sub

E poi avere un'altra classe che faccia questo:

Option Explicit
Implements ISomething

Private Sub ISomething_DoSomething()
    'implementation here
End Sub

Una tale classe, che non espone nessun membro pubblico, è sempre accessibile tramite la sua interfaccia ISomething - e potrebbero esserci decine e decine di implementazioni diverse di ISomething , quindi il codice VBA OOP è perfettamente in grado di polimorfismo ed è perfettamente legale per una determinata classe implementare anche più interfacce.

VB6 / VBA non consente l'ereditarietà della classe , tuttavia non puoi ereditare un'implementazione da un altro tipo, ma solo la sua interfaccia. Ora, se questo è un incidente, un difetto di progettazione, un colpo di genio o un'enorme supervisione è aperto al dibattito; non è chiaro se VB6 / VBA tenga questo a cuore , ma sicuramente lo impone .

Se Go non esegue l'ereditarietà della classe ed è nondimeno un linguaggio OOP , quindi non vedo perché VB6 / VBA non possa essere considerato un linguaggio OOP. </PreemptiveResponseToVBAHatersThatWillSayItIsNotAnOOPLanguage>

    
risposta data 09.06.2016 - 23:19
fonte
0

Puoi fare in modo che il compilatore applichi l'ereditarietà selettiva attraverso l'uso di privato / protetto e attraverso l'uso moderno delle tecniche "PImpl" o "Implementazione privata".

Molte API espongono solo quei componenti che vorresti ereditare da un utente e nascondono il resto in una classe di implementazione separata. Quindi è possibile scrivere classi le cui interfacce pubbliche sono, in effetti, non inviolabili, utilizzabili solo attraverso la composizione di oggetti e applicate dal compilatore. Questa è spesso una buona pratica, quando usa il compilatore per far rispettare l'intento del software.

Una rapida ricerca delle funzioni dei membri privati in javascript mostra che esiste un principio simile, anche se chiunque può vedere il tuo codice se può usarlo: link

    
risposta data 06.10.2014 - 22:12
fonte

Leggi altre domande sui tag