Warum maskieren Sie ein Basisklassenmitglied?

8

Ich habe gerade gelernt, wie man ein Mitglied der Basisklasse maskiert (mit new), aber ich vermisse den Punkt, warum ich das machen möchte. Bietet uns die Maskierung ein gewisses Maß an Schutz, wie es bei der Kapselung der Fall ist? Bitte beraten.

    
Asterix 31.08.2010, 14:43
quelle

6 Antworten

3

Sie werden sehr selten "neu" verwenden, um ein Basisklassenmitglied zu maskieren.

Es wird hauptsächlich für die Fälle verwendet, in denen die abgeleitete Klasse zuerst das Member hatte, und dann wurde es zur Basisklasse hinzugefügt --- derselbe Name für einen anderen Zweck. Der new ist da, dem Sie anerkennen, dass Sie wissen, dass Sie es anders verwenden. Wenn ein Basiselement in C ++ hinzugefügt wird, fügt es die vorhandene Methode nur im Hintergrund in die Vererbungskette ein. In C # müssen Sie zwischen new und override wählen, um Ihnen zu zeigen, was passiert.

    
James Curran 31.08.2010 14:49
quelle
3

Es wird nicht nur zum Maskieren verwendet. Es bricht tatsächlich die Vererbungskette. Wenn Sie also die Basisklassenmethode aufrufen, wird die Methode in der abgeleiteten Klasse nicht aufgerufen (nur die in der Basisklasse).

Sie erstellen im Wesentlichen eine neue -Methode, die nichts mit der Basisklassenmethode zu tun hat. Daher das Schlüsselwort "new".

Das Schlüsselwort "new" kann verwendet werden, wenn Sie eine Methode mit der gleichen Signatur wie eine Basistyp-Methode, aber mit einem anderen Rückgabetyp definieren möchten.

    
Philippe Leybaert 31.08.2010 14:48
quelle
3

Die einzigen gültigen sicheren Beispiele, auf die ich gestoßen bin, sind spezifischer mit Rückgabetypen oder bieten einen Set-Accessor für eine Eigenschaft . Ich sage nicht, dass das die einzigen sind, aber das ist alles, was ich gefunden habe.

Angenommen, Sie haben eine sehr einfache Basis, die wie folgt aussieht:

%Vor%

Sie könnten eine Ableitung haben, die eher so aussieht:

%Vor%

Wenn angenommen wird, dass Geschäftsregeln es einem bestimmten Derived erlauben, einen änderbaren Namen zu haben, glaube ich, dass dies akzeptabel ist. Das Problem mit new besteht darin, dass sich das Verhalten ändert, je nachdem, welcher Typ der Instanz angezeigt wird. Zum Beispiel, wenn ich sagen würde:

%Vor%

In diesem trivialen Beispiel geht es uns gut. Wir überschreiben das Verhalten mit new , aber nicht auf brechende Weise. Das Ändern der Rückgabetypen erfordert etwas mehr Finesse. Wenn Sie nämlich new verwenden, um einen Rückgabetyp für einen abgeleiteten Typ zu ändern, sollten Sie nicht zulassen, dass dieser Typ von der Basis festgelegt wird. Schau dir dieses Beispiel an:

%Vor%

Wenn ich set Child für die Klasse Base hätte, könnte ich ein Casting-Problem in der Klasse Derived haben. Ein anderes Beispiel:

%Vor%

Ich kann keine Geschäftsregeln brechen, indem ich alle meine Derived -Klassen als Bases behandle, es ist einfach praktisch, check und cast nicht einzugeben.

    
Marc 31.08.2010 15:05
quelle
3
  

Ich habe gerade gelernt, wie man ein Basisklassenmitglied maskiert (mit new)

Zu Ihrer Information: Diese Funktion wird normalerweise "Verbergen" und nicht "Maskieren" genannt. Ich denke an "Maskierung" als Clearing-Bits in einem Bit-Array.

  

Ich vermisse den Punkt, warum ich das machen möchte.

Normalerweise möchten Sie nicht. Aus einigen Gründen, um diese Funktion zu verwenden und nicht zu verwenden, siehe meinen Artikel zu diesem Thema von 2008:

Ссылка

  

Bietet uns die Maskierung ein gewisses Maß an Schutz, wie es bei der Kapselung der Fall ist?

Nein, tut es nicht.

    
Eric Lippert 31.08.2010 17:07
quelle
1

Was Sie meinen, heißt Name Verbergen . Es ist hauptsächlich ein Komfortmerkmal. Wenn Sie von einer Klasse erben, für die Sie die Quelle nicht mithilfe von new steuern, können Sie das Verhalten einer Methode ändern, auch wenn sie nicht als virtuell deklariert wurde (oder die Signatur vollständig ändern, wenn sie virtuell ist). Das Schlüsselwort new unterdrückt einfach eine Compiler-Warnung. Sie informieren den Compiler grundsätzlich darüber, dass Sie die Methode absichtlich vor einer übergeordneten Klasse verbergen.

Delphi hatte das Schlüsselwort reintroduce aus dem gleichen Grund.

Was kauft dir das anders als eine unterdrückte Warnung? Nicht viel. Sie können nicht auf die new -Methode von einer übergeordneten Klasse zugreifen. Sie können über eine Schnittstelle darauf zugreifen, wenn Ihre untergeordnete Klasse die Schnittstelle direkt implementiert (so als ob sie sie von ihrer übergeordneten Klasse erben würde). Sie können das Mitglied der übergeordneten Klasse immer noch vom untergeordneten Element aufrufen. Alle zusätzlichen Nachkommen Ihrer Klasse erben das new -Member und nicht dasjenige im übergeordneten Element.

    
Kenneth Cochran 31.08.2010 15:19
quelle
0

Dies wird tatsächlich als Verstecken von Elementen bezeichnet. Es gibt ein paar häufige Szenarien, in denen dies angemessen genutzt werden kann.

  • Damit können Sie Probleme bei der Versionierung umgehen, bei denen der Autor der Basis- oder abgeleiteten Klasse unbeabsichtigt einen Mitgliedsnamen erstellt, der mit einem vorhandenen Bezeichner kollidiert.
  • Es kann verwendet werden, um Kovarianz bei Rückgabetypen zu simulieren.

In Bezug auf den ersten Punkt ... ist es möglich, dass ein Autor einer Basisklasse später ein Mitglied mit demselben Namen wie ein existierendes Mitglied in einer abgeleiteten Klasse hinzufügen kann. Der Basisklassenautor hat möglicherweise keine Kenntnis der abgeleiteten Klassen, und daher wird nicht erwartet, dass sie Namenskollisionen vermeiden sollte. C # unterstützt die unabhängige Entwicklung von Klassenhierarchien mithilfe der Verbergungsmechanismen.

In Bezug auf den zweiten Punkt ... möchten Sie vielleicht, dass eine Klasse eine Schnittstelle implementiert, die eine bestimmte Methodensignatur diktiert, und Sie also nur bestimmte Instanzen eines bestimmten Typs zurückgeben, während Sie gleichzeitig diesen Typ unterklassifiziert haben und dies auch tun würden wirklich wie Anrufer, um den konkreten Typ stattdessen zu sehen. Betrachten Sie dieses Beispiel.

%Vor%     
Brian Gideon 31.08.2010 15:18
quelle

Tags und Links