31/05/2023 - zoro82 ha scritto:
Ma guarda, io non volevo spiegazioni. So la differenza tra un'interfaccia e una classe astratta.
Infatti quello che volevi non era affatto chiaro, e ciò che si poteva supporre con la scarsità delle indicazioni fornite in realtà non era esattamente quello che ti interessava. Definire bene le domande richiede tempo, ma almeno lo fa risparmiare a chi eventualmente vuole rispondere, evitando di commentare quello che non è necessario senza magari risolvere il dubbio reale.
31/05/2023 - zoro82 ha scritto:
Il problema è che le ultime versioni di C# consentono di inserire nelle interfacce anche le proprietà snaturandone quella che è la natura originaria
Che io sappia, le proprietà nelle interfacce esistono già da parecchie versioni di C#.
Le proprietà non vanno a snaturare la natura dell'interfaccia, se sai cosa sono le proprietà e come sono implementate in .NET (vedi la documentazione ufficiale).
31/05/2023 - zoro82 ha scritto:
io ho imparato che la classe è il contentitore di dati, l'interfaccia è un contenitore di metodi comuni che si usa per non portarsi dietro tutto il fardello dell'ereditarietà
Infatti le proprietà non sono un “contenitore” di dati: quelli sono i campi. Prova a inserire un campo in una interfaccia, e vedrai che quanto dici rimane verificato.
Quello che indichi tu è solo uno degli utilizzi più comuni, ma non sono definizioni proprie delle classi astratte e delle interfacce.
In linea più generale, le interfacce potrebbero essere definite come un “contratto”, mentre le classi (che siano astratte o no) sono una implementazione reale di quel “contratto” (se implementano una interfaccia).
La caratteristica di essere “astratta” delinea solo l'impossibilità di implementare un metodo in una classe perché il livello che essa rappresenta nella gerarchia è tale per cui si è consapevoli che quella funzionalità è comune a tutti i discendenti, che ciascuno di essi la implementa in modo diverso, ma che nel “fattore comune” non è possibile indicare una implementazione valida (rappresenta appunto un concetto astratto).
31/05/2023 - zoro82 ha scritto:
Tuttavia, il fatto di poter avere delle interfacce che derivano da altre interfacce e poter mettere nella interfaccia madre delle proprietà …. mi crea dei dubbi e in alcuni casi l'uso delle due soluzioni è indifferente.
Derivare interfacce da interfacce è una comodità per evitare ripetizioni su contratti che sono estensioni di altri.
La questione delle proprietà - ripeto - sapendo cosa sono (vedi approfondimento sopra) non dovrebbe dare luogo ad alcun dubbio.
In alcuni casi è vero che più soluzioni possono essere indifferenti: ciò non significa che lo siano sempre, o che possano non esserlo in futuro.
31/05/2023 - zoro82 ha scritto:
Io infatti potrei dichiarare una <Personaggio> lista o una <IPersonaggi> lista senza che vi sia, in alcuni casi, una grossa differenza.
Dipende, ovviamente. E' un po' come se io dicessi che, dovendo mangiare frutta per la dieta, una mela o un kiwi sono grossomodo equivalenti. Nel contesto che intendo io, lo sono, ma in generale nessuno direbbe mai che una mela è uguale a un kiwi in senso assoluto.
Nel tuo caso infatti, il nome dell'interfaccia IPersonaggio, già denota un uso errato della stessa, in quanto essa dovrebbe definire un contratto comportamentale di ciò che il personaggio deve fare, quindi in genere l'interfaccia esprime come nome una capacità, una interazione, una azione (vedi IDisposable, ICloneable)… il fatto di usare un sostantivo (Personaggio) vuol dire che una interfaccia non serve, o che è stata creata in modo errato (ossia si è usata una interfaccia impropriamente).