Soll ich markieren Sie alle Methoden virtuell?
In Java können Sie mark-Methode als final zu machen unmöglich zu überschreiben.
In C# haben, um eine Methode als virtuell zu machen möglich zu überschreiben.
Heißt es, dass in C# markieren Sie alle Methoden, die virtuelle (außer ein paar diejenigen, die Sie wollen nicht überschrieben werden), da die meisten wahrscheinlich, dass Sie nicht wissen, auf welche Weise Sie Ihre Klasse kann geerbt werden?
- Ich mag zu denken, dass in C#, wenn Sie etwas tun, das fühlt sich anspruchsvoll, du machst es falsch.
- Das Gegenteil ist wahr: viele Java-gurus beraten, dass alle Methoden
final
standardmäßig. - Jon Skeet auf die Erbschaftssteuer obwohl, das war fast sieben Jahre alt und Meinungen ändern.
- Zitat/Quelle bitte!
- Wenn ich ein handy hätte ich es gepostet. Jedoch, Joshua Bloch hat immer wieder geraten, und ich bin mir ziemlich sicher, Effektiv Java erwähnt es irgendwo.
- Sie Fehler final-Felder w - / final-Methoden.
- Nein, ich definitiv nicht. Final Felder sind völlig unabhängig.
- Ich verstehe, Sie erkennen den Unterschied zwischen Ihnen. Doch, was Herr Bloch berät, ist die Verwendung von "final" Felder. Er berät für Komposition und statische Fabriken, aber nicht für final Klassen/Methoden
- Vergessen Sie
final
Felder, ich weiß, dass er spricht über Sie. Aber ich denke, er spricht auch über endgültige Methoden in effiziente Java. Aber ich kann misremember diese. Ich bin mir aber sicher, dass er erwähnte es an anderer Stelle dann – vielleicht in einem seiner Vorträge. - Recht. Ich hatte das Buch vor mir, wenn ich schrieb den Kommentar; es gibt fast keine final-Methoden gibt es, auch weniger endgültige Klassen - ThreadLocal gezeigt
final
, während in Wirklichkeit es nicht ist. Einige werden verwendet, um zu zeigen, dass auchfinal
nicht helfen, Unveränderlichkeit (berüchtigten j.u.Datum), einigefinal
als "schrecklich Kandidat für die standardmäßige serialisierte form" - StringList und so weiter.Keine Klasse in der collection framework ist endgültig, entweder.Zugegeben, ich bin kein großer fan von ihm, ich habe nicht gefolgt, seinen Gesprächen, aber es sei denn, Sie haben eine Quelle für Java-guru Befürwortung von "final Methoden standardmäßig" würde ich nicht akzeptieren. - Ich bin überrascht von Ihrer Stimmung. Warum sollte Java-gurus im Allgemeinen nicht umarmen diese Ansicht? Es ist sicherlich die vorherrschende Stimmung bei .NET Programmierer (wenn Eric unten ist nicht genug für Sie, Suche nach Jon Skeet Blick auf die Sache), warum sollten die, die sich für Java?
- lassen Sie uns weiter, diese Diskussion im chat
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nicht. Wenn die Sprache, die Designer gedacht, die virtuelle haben sollte, wurde der Standard dann wäre es gewesen, die Standard -.
Overridablility ist ein Funktion, und wie alle features, die es hat Kosten. Die Kosten für eine überschreibbar Methode sind beachtlich: es sind große design, die Implementierung und die Tests Kosten, vor allem wenn es eine "Sensibilität" für die Klasse, die virtuelle Methoden sind Möglichkeiten, die der Einführung ungeprüfter third-party-code in ein system und das hat Auswirkungen auf die Sicherheit.
Wenn Sie nicht wissen, wie Sie beabsichtigen, Ihre Klasse geerbt werden dann nicht veröffentlichen Ihre Klasse weil Sie noch nicht fertig Gestaltung es noch. Ihr erweiterungsmodell ist definitiv etwas, das Sie wissen sollten, vor der Zeit; er sollte einen starken Einfluss auf Ihre design-und Test-Strategie.
Ich es befürworte, dass alle Klassen werden versiegelt und alle Methoden werden nicht-virtuellen, bis Sie ein real-Welt-Kunde-fokussierte Grund zu unseal oder um eine virtuelle Methode.
Grundsätzlich ist deine Frage "ich bin unwissend, wie meine Kunden wollen zu konsumieren, meine Klasse; soll ich also machen Sie es beliebig erweiterbar?" Nein, Sie sollten werden kenntnisreich! Sie würde nicht Fragen, "ich weiß nicht, wie meine Kunden nutzen meine Klasse, also sollte ich all meine Eigenschaften, die Lesen und schreiben? Und sollte ich alle meine Methoden, die Lesen und schreiben Eigenschaften des Delegaten-Typ, so dass meine Benutzer können ersetzen jede Methode mit Ihren eigenen Implementierung?" Nein, nicht tun alle diese Dinge, bis Sie Beweise, dass ein Benutzer auch tatsächlich braucht, der Fähigkeit! Verbringen Sie Ihre wertvolle Zeit zum entwerfen, testen und implementieren von Funktionen, die Nutzer wirklich wollen und brauchen, und Sie tun dies aus einer position des Wissens.
sealed
standardmäßig, was Sie nicht sind.SerialPort
schränkt unterstütztEncoding
s für diejenigen definiert, die inmscorlib.dll
)).System.Web
's sorry state ist aufgrund der Tatsache, dass die Klassen sind versiegelt, und dass nicht mit Ihnen geschlossenen (und nicht zu ändern alles andere) würden sich all diese Probleme beheben. Das ist einfach eine grundlose Behauptung, und als solche, können abgelehnt werden. Andere web-Frameworks verfolgen grundsätzlich unterschiedliche Ansätze. (Beachten Sie nochmals, dass ich spreche nicht über die Schnittstellen, hier auf alle.)non-virtual
(und versiegelt) standardmäßig ist gerechtfertigt (da die meisten alt langs nicht enfoce es). Das eigentliche problem in der Praxis ist nicht in der Lage, erweitern/überschreiben, built-in/3rd-Party-Verhalten. Wie Java ist aktiviert-Ausnahmen, glaube ich nicht-virtuellen ist gut in der Theorie, aber in der Praxis versagt.public virtual void Foo() { Bar(); }
Sie schreiben könntepublic Action Foo = () => { Bar(); }
. Wenn nun ein Benutzer der Klasse Wünschex.Foo()
zu nennenBlah()
Sie nicht brauchen, um das überschreiben der Klasse; Sie nur sagenx.Foo = ()=> { Blah(); }
. Virtuelle Methoden werden einen Mechanismus für die Anpassung eine Klasse durch Unterklassen. Wenn die Anpassung durch die Nutzer ist das Ziel dann, warum Sie benötigen, um zu verwenden Unterklassen? Das ist eine völlig unnötige zusätzliche Komplikationen. Mein Punkt ist, dass Leute, die sagen, alles zu machen, dass virtuelle für maximale Flexibilität auf einem Punkt bei weitem nicht das maximum.Meiner Meinung nach der derzeit anerkannten Antwort ist unnötig dogmatisch.
Tatsache ist, dass, wenn Sie nicht, markieren Sie eine Methode als
virtual
, andere nicht ändern können, Ihr Verhalten und wenn Sie daneben eine Klasse alssealed
andere nicht können, Erben von der Klasse. Dies kann zu erheblichen Schmerzen. Ich weiß nicht, wie viele Male verfluchte ich eine API für die Kennzeichnung der Klassensealed
oder nicht-Kennzeichnung Methodenvirtual
einfach weil Sie nicht rechnen meine.Theoretisch wäre der richtige Ansatz, um nur erlauben, überschreiben von Methoden und erbenden Klassen überschrieben werden sollen und vererbt werden, aber in der Praxis ist es unmöglich vorauszusehen, jedes mögliche Szenario und es gibt wirklich nicht einen guten Grund so verschlossen.
sealed
.virtual
.Eins Weg, um den Anruf zu betrachten, der den Namen der Methode oder Eigenschaft. Ein GetLength() Methode, die auf einer Liste genau das tut, was der name schon sagt und es nicht ermöglicht, viel von interpretation. Änderung seiner Umsetzung wäre wahrscheinlich nicht sehr transparent, so dass die Kennzeichnung als
virtual
ist wohl unnötig. Die Kennzeichnung derAdd
Methode als virtual ist weit mehr nützlich, als jemand schaffen könnte, eine spezielle Liste, die akzeptiert nur einige Objekte über die Add-Methode etc. Ein weiteres Beispiel sind benutzerdefinierte Steuerelemente. Würden Sie wollen, um die Haupt-Zeichnung-Methodevirtual
also können andere die Verwendung der bulk-Verhalten und nur das Aussehen ändern, aber Sie würde wahrscheinlich nicht überschreiben Sie die X-und Y-Eigenschaften.Am Ende Sie oft gar nicht haben, diese Entscheidung sofort. In einem internen Projekt, wo können Sie leicht ändern Sie den code trotzdem würde ich nicht über diese Dinge zu kümmern. Wenn eine Methode muss überschrieben werden, können Sie immer machen es virtuelle, wenn dies geschieht.
Im Gegenteil, wenn das Projekt eine API oder Bibliothek, die verbraucht wird, von anderen und langsam zu aktualisieren, es zahlt sich sicherlich aus, um zu überlegen, welche Klassen und Methoden die nützlich sein könnten. In diesem Fall denke ich ist es besser, offen zu sein, anstatt streng geschlossen.
Nein! Weil Sie nicht wissen, wie Ihre Klasse geerbt werden, sollten Sie nur daneben eine Methode wie
virtual
wenn Sie wissen, dass Sie wollen, dass es außer Kraft gesetzt werden.Nicht. Nur Methoden, die Sie wollen, die von abgeleiteten Klassen angeben, sollte virtuell sein.
Virtual ist nicht mit final.
Um zu verhindern, dass das überschreiben einer virtuellen Methode in c# verwenden Sie
sealed
final
auf einer Methode bedeutetnot virtual
.Wir zaubern können Gründe für/wieder entweder camp, aber das ist völlig nutzlos.
In Java gibt es Millionen von unbeabsichtigten nicht-final-public-Methoden, aber wir hören nur sehr wenige horror-Geschichten.
In C# gibt es Millionen von versiegelten öffentlichen Methoden, und wir hören nur sehr wenige horror-Geschichten.
So ist es nicht eine große Sache - das überschreiben müssen eine öffentliche Methode ist selten, so ist es strittig oder so.
Dazu fällt mir ein weiteres argument - ob eine lokale variable sein sollte-Finale standardmäßig. Es ist eine ziemlich gute Idee, aber wir dürfen nicht übertreiben, wie wertvoll es ist. Es gibt Milliarden von lokalen Variablen, das könnte sein, aber sind nicht final, aber es hat sich gezeigt, um eine tatsächliche problem.
Machen eine virtuelle Methode wird in der Regel langsamer code zu nennen. Diese Verlangsamung wird unbedeutend sein, kann aber in einigen Fällen ziemlich groß sein (unter anderem, weil nicht-virtuelle Methoden-Aufrufe können in-ausgekleidet, die wiederum ermöglichen, die der Optimierer zur Beseitigung unnötiger Operationen). Es ist nicht immer möglich vorherzusagen, inwieweit die virtuelle Anrufe können Einfluss auf die Ausführungsgeschwindigkeit, und man sollte in der Regel nichtig, Dinge zu tun, die den code langsamer werden, außer wenn es einen erkennbaren nutzen für Sie dabei.
Den performance-Vorteil, die Methoden nicht virtuell ist wohl in vielen Fällen ausreichend, um zu rechtfertigen, dass die Methoden werden nicht standardmäßig virtuell, aber als Klassen werden geerbt, die meisten Methoden sollten virtuelle und entsiegelt; die primäre Verwendung für nicht-virtuellen oder versiegelt, sollten Methoden sein, die als Wrapper für andere (möglicherweise geschützte) virtuelle Methoden (code, der das ändern will, ist das zugrunde liegende Verhalten sollten, überschreiben Sie die entsprechenden virtuellen anstatt der wrapper).
Gibt es Häufig auch nicht-leistungsbezogene Gründe für die Markierung von Klassen als
sealed
oder Beschränkung der Vererbung auf andere Klassen innerhalb der assembly. Unter anderem, wenn eine Klasse extern vererbbar, alle Mitglieder mitprotected
Umfang wirksam sind, Hinzugefügt, um seine öffentliche API und alle änderungen an Ihrem Verhalten in der Basis-Klasse kann brechen und alle abgeleiteten Klassen, die sich auf das Verhalten. Auf der anderen Seite, wenn eine Klasse vererbbar ist, macht seine Methodenvirtual
nicht wirklich erhöhen Sie Ihre Exposition. Wenn überhaupt, kann es reduzieren-Klasse abgeleitete Klasse im Vertrauen auf die base-Klasse Einbauten, indem Sie Sie komplett "begraben" Aspekte die Implementierung der Basisklasse, die nicht länger relevant sind, in der abgeleiteten Klasse [z.B. wenn die MitgliederList<T>
waren virtuelle, eine abgeleitete Klasse, die überschrieb Sie alle könnten verwenden Sie ein array von arrays zu halten (Vermeidung von large-object-heap-Probleme), und würde nicht haben, um zu versuchen zu halten, der private Bereich verwendetList<T>
im Einklang mit dem array-von-arrays.Nein, Sie sollten nicht, markieren Sie alle Methoden, die als virtuelle. Sie sollten berücksichtigen, wie Ihre Klasse vererbt werden könnte. Wenn die Klasse nicht vererbt werden, dann markieren Sie es versiegelt und natürlich sollten die Mitglieder nicht virtuell sein. Wenn Ihre Klasse ist wahrscheinlich vererbt zu werden, sollten Sie wirklich zu maximieren die Fähigkeit, zu überschreiben Verhalten. Daher großzügig verwenden virtuelle überall in solchen Klassen, es sei denn, Sie haben einen Grund, nicht zu.