Frage

Wenn ich die verschiedenen Unterklassen von etwas, und ein Algorithmus arbeitet auf Instanzen der Unterklassen, und wenn das Verhalten des Algorithmus variiert leicht je nachdem, welche bestimmten Unterklasse eine Instanz ist, dann sind die meisten üblichen Objekt-orientierten Weg, dies zu tun, ist die Verwendung virtueller Methoden.

Zum Beispiel, wenn die Unterklassen sind DOM-Knoten, und wenn der Algorithmus zum einfügen eines untergeordneten Knoten, der Algorithmus unterscheidet sich abhängig davon, ob der übergeordnete Knoten ist ein DOM-element (die Kinder) oder DOM-text (nicht):und so die insertChildren Verfahren virtuellen (oder abstract) in der DomNode Basisklasse, die implementiert anders in jedem der DomElement und DomText Unterklassen.

Eine andere Möglichkeit geben, die Instanzen eine gemeinsame Eigenschaft, deren Wert gelesen werden kann:zum Beispiel der Algorithmus könnte, Lesen Sie die nodeType Eigenschaft der DomNode base class;oder ein anderes Beispiel, Sie könnte haben verschiedene Arten (Unterklassen) der Netzwerk-Paket, das eine gemeinsame Paket-header, und Sie können Lesen Sie die Paket-header, um zu sehen, welche Art von Paket es ist.

Ich habe nicht verwendet run-time-type-information vieles, darunter:

  • Die is und as keywords in C#
  • Downcasting
  • Das Objekt.GetType-Methode in dot net
  • Die typeid - operator in C++

Wenn ich hinzufügen eines neuen Algorithmus, der abhängig von der Art der Unterklasse, Neige ich dazu, stattdessen fügen Sie eine neue virtuelle Methode der Klasse Hierarchie.

Meine Frage ist, Wann ist es angebracht zu verwenden, run-time-type-information, anstelle von virtuellen Funktionen?

War es hilfreich?

Lösung

Wenn es um keinen anderen Weg. Virtuelle Methoden werden immer bevorzugt, aber manchmal können sie einfach nicht verwendet werden. Es gibt einige Gründe, warum dies geschehen könnte, aber am häufigsten ist, dass Sie nicht Quellcode von Klassen müssen Sie arbeiten möchten, mit oder Sie können sie nicht ändern. Diese oft passiert, wenn Sie mit Legacy-System arbeiten oder mit Closed-Source-kommerzieller Bibliothek.

In .NET könnte es kommt auch vor, dass Sie im laufenden Betrieb neue Baugruppen geladen werden müssen, wie Plugins und Sie in der Regel keine Basisklassen haben aber auf die Verwendung so etwas wie Ente eingeben haben.

Andere Tipps

In C ++, unter einigen anderen obskuren Fällen (die meist mit minderwertigen Design-Entscheidungen befassen), ist RTTI eine Art und Weise zu implementieren, so genannte Multi Methoden .

Diese Konstruktionen ( „ist“ und „wie“) sind sehr vertraut für Delphi-Entwickler seit Event-Handler in der Regel niedergeschlagener Objekte zu einem gemeinsamen Vorfahren. Zum Beispiel Ereignis geht OnClick die einzige argurment Sender: TObject unabhängig von der Art des Objekts, ob es TButton, TListBox oder jede andere ist. Wenn Sie etwas mehr über dieses Objekt wissen wollen, haben Sie Zugriff auf sie durch „wie“, sondern um eine Ausnahme zu vermeiden, können Sie es überprüfen mit vor „ist“. Dies ermöglicht Downcasting Design-Typen von Objekten und Methoden Bindung, die nicht möglich sein könnte, mit strengen Typprüfung Klasse. Stellen Sie sich vor, das Gleiche tun, wenn die Benutzer-Taste oder ListBox klickt, aber wenn sie uns mit verschiedenen Prototypen von Funktionen zur Verfügung stellen, könnte es nicht möglich sein, sie auf die gleiche Weise zu binden.

Im allgemeineren Fall kann ein Objekt eine Funktion aufrufen, die meldet, dass das Objekt zum Beispiel verändert hat. Aber im Voraus läßt es das Ziel die Möglichkeit, ihn zu kennen „persönlich“ (durch so und ist), aber nicht unbedingt. Es tut dies, indem Selbst als die meisten gemeinsamen Vorfahren aller Objekte (TObject in Delphi Fall), die

dynamic_cast<> wenn ich mich richtig erinnere, ist abhängig von RTTI.Einige obskure äußeren Schnittstellen könnte sich auch auf RTTI, wenn ein Objekt übergeben wird, über einen void-Zeiger (für was auch immer Grund dass passieren könnte).

Dass gesagt wird, ich habe nicht gesehen, typeof() in der wildnis, die in 10 Jahren pro-C++ Wartungsarbeiten.(Zum Glück.)

können Sie beziehen sich auf eine noch effektivere C # für einen Fall, in dem Laufzeit-Typprüfung OK ist.

  

Punkt 3. Spezialisieren Allgemeine Algorithmen   Mit Runtime Typprüfung

     

Sie können ganz einfach Generika Wiederverwendung von   Angabe einfach neuen Typparameters.   Eine neue Instanziierung mit neuem Typ   Parameter bedeuten, eine neue Art mit   eine ähnliche Funktionalität.

     

All dies ist groß, weil Sie schreiben   weniger Code. Aber manchmal ist   allgemeineres Mittel nicht unter   Vorteil einer spezifischeren, aber   deutlich überlegen, Algorithmus. Die C #   Sprachregeln berücksichtigen dies.   Alles was man braucht ist für Sie zu erkennen,   dass Ihr Algorithmus kann mehr sein   effizient, wenn die Parameter des Typs   haben größere Fähigkeiten, und dann zu   dass bestimmte Code schreiben. Außerdem,   eine zweite gattungsgemäßen Art zu schaffen, dass   gibt an unterschiedliche Randbedingungen   funktioniert nicht immer. Generisch   instantiations werden auf der Basis   Kompilierung-Typ eines Objekts, und   nicht der Laufzeittyp. Wenn Sie nicht zu   das berücksichtigen, können Sie verpassen   Wirkungsgrad.

Angenommen, Sie eine Klasse schreiben, die auf einer Folge von Elementen eine umgekehrte Ordnung Aufzählung stellt durch IEnumerable dargestellt . Um es aufzuzählen rückwärts können Sie es wiederholen, und kopieren Sie Elemente in eine Zwischen Sammlung mit Indexer-Zugriff wie List und als aufzuzählen, die Indexer-Zugriff rückwärts Sammlung verwenden. Aber wenn Ihre ursprüngliche IEnumerable IList deshalb nicht nutzen es und bieten leistungsfähigere Art und Weise (ohne Zwischen Sammlung zu Kopieren) zu iterieren Artikel zurück. Also im Grunde ist es eine besondere wir nutzen können, aber immer noch das gleiche Verhalten bereitstellt (Sequenz rückwärts iteriert).

Aber im Allgemeinen sollten Sie sorgfältig Laufzeittypprüfung prüfen und sicherzustellen, dass sie nicht verletzt Liskov Substituion Prinzip.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top