In C# e C++/CLI la parola chiave sealed
(o NotInheritable
in VB) viene utilizzata per proteggere una classe da qualsiasi possibilità di ereditarietà (la classe non sarà ereditabile). So che una caratteristica della programmazione orientata agli oggetti è l'ereditarietà e ritengo che l'uso di sealed
vada contro questa funzione, impedendo l'ereditarietà. C'è un esempio che mostra il vantaggio di sealed
e quando è importante utilizzarlo?Quando e perché sigilleresti una lezione?
risposta
1) Su una classe che implementa funzionalità di sicurezza, in modo che l'oggetto originale non possa essere "impersonato".
2) Più in generale, di recente mi sono scambiato con una persona in Microsoft, che mi ha detto che cercava di limitare l'ereditarietà ai luoghi in cui aveva davvero senso, perché diventa costoso se non curato.
La parola chiave sealed indica al CLR che non esiste una classe più in basso per cercare i metodi e che accelera le cose.
Al giorno d'oggi nella maggior parte degli strumenti di miglioramento delle prestazioni sul mercato, troverete una casella di controllo che sigillerà tutte le vostre classi che non sono ereditate.
Attenzione però, perché se si desidera consentire i plug-in o il rilevamento degli assiemi tramite MEF, si verificheranno dei problemi.
Un addendum alla risposta eccellente del Babbuino:
3) Se una classe non è progettato per l'eredità, le sottoclassi potrebbero rompersi class invariants. Questo si applica in realtà solo se stai creando un'API pubblica, ovviamente, ma come regola generale sigillo qualsiasi classe non esplicitamente progettata per essere sottoclasse.
Su una nota correlata, applicabile solo alle classi non sigillate: qualsiasi metodo creato virtual
è un punto di estensione o, almeno, sembra che dovrebbe essere un punto di estensione. La dichiarazione dei metodi virtual
dovrebbe essere una decisione consapevole. (In C# questa è una decisione consapevole, in Java non è così.)
EDIT: Alcuni link rilevanti:
- Effective Java, 2nd Edition da Joshua Bloch. Vedi punto 17 (richiede sottoscrizione Safari)
- Effective Java Item 17: Design and document for inheritance or else prohibit it (discussione della stessa voce)
Si noti inoltre che Kotlin sigilli classi di default; its open
keyword is the opposite of Java's final
or the sealed
of C#. (Per essere sicuri, there is no universal agreement that this is a good thing.)
Le classi di sigillatura causano più mal di testa che beneficio. Ho trovato continuamente situazioni in cui gli sviluppatori hanno classi sigillate, causandomi ore di difficoltà in ciò che dovrebbe essere semplice. Smetti di frequentare le lezioni, non sei così spiritoso come credi di essere. Sigilla le classi solo se DEVI, e anche allora, riconsiderare. Solo la mia opinione, come il ragazzo che ha a che fare con classi sigillate di altre persone che non posso modificare/annullare. – GantMan
Il commento di @GantMan dovrebbe essere considerato una delle risposte alla domanda dell'OP, perché essenzialmente fornisce una risposta come "Quando? Difficilmente, perché?" Questo è il motivo per cui NON lo fai. " Concedi di postare nuovamente il tuo commento come risposta separata e poi raccogliere voti per questo. :-) – RayLuo
Penso che questo post abbia un buon punto, il caso specifico è stato quando si prova a trasmettere una classe non sigillata a qualsiasi interfaccia casuale, il compilatore non genera errori; ma una volta sigillato viene usato il compilatore genera errore che non può convertire. La classe sigillata offre sicurezza aggiuntiva per l'accesso al codice.
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla
Un collegamento a una soluzione è il benvenuto, ma per favore assicurati che la tua risposta sia utile senza di essa: [aggiungi contesto intorno al link] (// meta.stackexchange.com/a/8259) in modo che i tuoi utenti abbiano qualche idea che cos'è e perché è lì, quindi cita la parte più pertinente della pagina a cui stai collegando nel caso in cui la pagina di destinazione non sia disponibile. [Le risposte che sono poco più di un collegamento possono essere cancellate.] (// stackoverflow.com/help/deleted-answers) –
Scusa se non ho intenzione di postarlo come risposta, ma sembra non correlato ad altre risposte e io non so dove metterlo – strisunshine
Ho modificato il post in base al suggerimento. Inizialmente vorrei solo contribuire con un angolo diverso (forse), ma ho solo ottenuto un downvote e non abbiamo ancora parlato del contenuto, potevamo il -1 gentilmente far sapere il motivo? – strisunshine
- 1. Perché devo ignorare il clone se voglio una lezione clonabile?
- 2. Ottieni una lezione per nome in Ruby?
- 3. Come si scrive una lezione in Javascript?
- 4. Generici Java: ottieni lezione?
- 5. Come riutilizzare una lezione in sass senza usare un mixin?
- 6. Ricevi la prima e l'ultima lezione con jQuery
- 7. Quando smaltire e perché?
- 8. Perché e quando usare __noop?
- 9. quando e perché utilizzare JumboEnumSet
- 10. Quando (e perché) è {} non definito in una console JavaScript?
- 11. Perché bash flag -e esce quando una subshell fallisce?
- 12. spiegazione di D_GNU_SOURCE Perché usarlo e quando?
- 13. Perché e quando usare angular.copy? (Copia profonda)
- 14. JavaScript: proprietà non numerabili: quando e perché?
- 15. cose più importanti su C# generics ... lezione imparata
- 16. cose più importanti su modelli C++ ... lezione imparata
- 17. polimorfico_allocatore: quando e perché dovrei usarlo?
- 18. Spring hibernate template quando usare e perché?
- 19. quando e perché utilizzare più NSManagedObjectContext?
- 20. Quando devo usare un Bigarray e perché?
- 21. Quando e perché vorresti trasmettere un oggetto?
- 22. RxAndroid: quando utilizzare bindActivity e perché?
- 23. Quando e perché utilizzare classi/metodi astratti?
- 24. JQuery su JavaScript Perché e quando utilizzare?
- 25. Come risolvere un percorso in una lezione non di controllo in Symfony2
- 26. Perché Scala costruisce una nuova tupla quando spacchetta una tupla?
- 27. Perché sto ottenendo un errore di tipo in questa sequenza di parser (lezione 8 di Erik Meijer)?
- 28. Quando implementare un'interfaccia e quando estendere una superclasse?
- 29. Quando è Request.Form ["nome"] null e quando una stringa vuota?
- 30. Quando (e quando no) per definire una Monad
perché dovresti avere problemi con MEF se usi la classe sigillata? –
Intendevo fare attenzione con le classi di tenuta nelle librerie riutilizzate, specialmente se sono riutilizzate da terzi e poi reintegrate (tramite MEF) nella base di codici. Il tuo codice base non può ereditare una determinata classe, ma terze parti lo faranno. –
Il motivo # 1 suona vago ma, supponendo che non scriviamo "caratteristiche di sicurezza" il più delle volte, ciò significa che la ragione # 1 non si applica? Il motivo n. 2 riguarda la messa a punto delle prestazioni.Di quale differenza di prestazioni stiamo parlando? Sono abbastanza significativi da giustificare l'alterazione della definizione di una classe non di sicurezza? Anche se la risposta fosse "sì", sarebbe idealmente un'opzione di compilazione, ad esempio "generare codice ottimizzato per tutte le classi non sigillate", piuttosto che far sì che gli sviluppatori modifichino il codice base. – RayLuo