8
votes

Pourquoi masqueriez-vous un membre de la classe de base?

Je viens d'apprendre à masquer un membre de la classe de base (en utilisant de nouveau) mais il manque le point de savoir pourquoi je voudrais le faire. Le masquage nous fournit-il un certain niveau de protection, comme c'est le cas dans l'utilisation d'encapsulation? S'il vous plaît conseiller.


2 commentaires

Je ne sais pas que je comprends la question, pouvez-vous donner un exemple de ce que vous signifie en masquant un membre de la classe de base.


Bien qu'une classe dérivée ne puisse supprimer aucun des membres qu'il a hérité, il peut les cacher. 1. Pour masquer un membre hérité, déclarez un nouveau membre du même type et avec le même nom. 2. Vous pouvez également masquer les membres statiques. Quel est l'avantage de cacher?


6 Réponses :


3
votes

Ce n'est pas simplement utilisé pour le masquage. Il casse la chaîne d'héritage, donc si vous appelez la méthode de la classe de base, la méthode de la classe dérivée ne sera pas appelée (juste celle de la classe de base).

Vous créez essentiellement une méthode nouvelle qui n'a rien à voir avec la méthode de la classe de base. D'où le mot-clé "nouveau".

Garder cela à l'esprit que le mot-clé "nouveau" peut être utilisé si vous souhaitez définir une méthode avec la même signature qu'une méthode de type de base, mais avoir un type de retour différent.


3 commentaires

Mais cela n'explique pas vraiment pourquoi vous voudriez faire cela. (C'est-à-dire que tout ce que vous avez fait est dire comment la fonction que vous avez écrite n'est pas appelée - si elle n'est pas appelée, quel est le point?)


Pourquoi? Si vous ne voulez pas que la nouvelle méthode soit faisant partie de la même chaîne d'héritage d'une méthode virtuelle avec le même nom et les mêmes types de paramètres. En tant que effet secondaire, il vous permet de redéclaré une méthode avec la même signature, à l'exception du type de retour. Tant que vous vous rappelez que cela ne sera pas appelé lorsque vous appelez la méthode du type de base.


Votre phrase «comme un effet secondaire» répond à la question. Le reste peut être mieux accompli par a) donnant à la méthode un nom différent, ou b) tout simplement ne pas l'écrire du tout.



3
votes

Vous utiliserez très rarement «Nouveau» pour masquer un membre de la classe de base.

Il est principalement utilisé pour les cas où la classe dérivée avait d'abord le membre, puis il a été ajouté à la classe de base --- le même nom pour un but différent. Le Nouveau est là pour que vous reconnaissez que vous savez que vous l'utilisez différemment. Lorsqu'un membre de base est ajouté en C ++, il fusionne simplement la méthode existante dans la chaîne d'héritage. Dans C #, vous devrez choisir entre Nouveau et de remplacement , pour indiquer que vous savez ce qui se passe.


1 commentaires

+1 C'est probablement l'utilisation la plus courante, mais je n'aime toujours pas le dire parce que le manque de polymorphisme brise l'intention (et qui sait quoi d'autre) du dérivé.



3
votes

Le seul em> Valide Strike> Safe em> Les exemples que j'ai rencontrés sont plus spécifiques avec des types de retour ou fournissant un accesseur défini sur une propriété . Je ne dis pas que ce sont les seuls sont les seuls, mais c'est tout ce que j'ai trouvé.

Par exemple, supposons que vous ayez une base très simple qui ressemble à ceci: p>

Derived d = new Derived(someDerivedInstance);
Base b = d;
var c = b.Child;  // c is of type Base
var e = d.Child;  // e is of type Derived


0 commentaires

0
votes

Ceci est en fait appelé caché des membres. Il y a quelques scénarios communs où cela peut être utilisé de manière appropriée.

  • Il vous permet de contourner les problèmes de versions dans lesquels la base ou l'auteur de la classe dérivée crée involontairement un nom de membre qui collide avec un identifiant existant. LI>
  • Il peut être utilisé pour simuler la covariance sur les types de retour. Li> ul>

    Concernant le premier point ... il est possible qu'un auteur d'une classe de base puisse ajouter ultérieurement un membre avec le même nom qu'un membre exigueur dans une classe dérivée. L'auteur de la classe de base n'a peut-être pas une connaissance des classes dérivées et il n'ya donc aucune espérance qu'elle devrait éviter les collisions de noms. C # prend en charge l'évolution indépendante des hiérarchies de classe à l'aide des mécanismes de cachette. P>

    Concernant le deuxième point ... Vous pouvez souhaiter une classe à mettre en place une interface qui dicte une certaine signature de méthode et vous êtes donc enfermé dans des instances de retour. d'un certain type que pendant le même moment, vous avez sous-classé de type et souhaitez vraiment que les appelants voient le type concret. Considérez cet exemple. P>

    public interface IFoo { }
    
    public class ConcreteFoo { }
    
    public abstract class Base
    {
      private IFoo m_Foo;
    
      public Base(IFoo x) { m_Foo = x; }
    
      public IFoo Foo { get { return m_Foo; } }
    }
    
    public class Derived
    {
      public Derived(ConcreteFoo x) : base(x) { }
    
      public new ConcreteFoo Foo { get { return (ConcreteFoo)base.Foo; } }
    }
    


0 commentaires

1
votes

Ce que vous faites référence s'appelle Nom Cache . C'est surtout une fonctionnalité de commodité. Si vous héritez d'une classe pour laquelle vous ne contrôlez pas la source en utilisant Nouveau vous permettra de modifier le comportement d'une méthode même s'il n'a pas été déclaré comme virtuel (ou modifier complètement la signature si elle est virtuel). Le mot clé nouveau supprime simplement un avertissement de compilateur. Vous informez essentiellement le compilateur que vous avez intentionnellement caché la méthode à partir d'une classe mère.

Delphi avait le réintroduire mot-clé pour la même raison.

Qu'est-ce que cela vous achète autre qu'un avertissement supprimé? Pas beaucoup. Vous ne pouvez pas accéder à la méthode nouvelle d'une classe mère. Vous pouvez y accéder à partir d'une interface si votre classe enfant implémente directement l'interface (comme apposée à la héritage de sa classe mère). Vous pouvez toujours appeler le membre de la classe mère de l'enfant. Tous les descendants supplémentaires de votre classe hériteront du député nouveau plutôt que celui du parent.


0 commentaires

3
votes

Je viens d'apprendre à masquer un membre de la classe de base (en utilisant de nouveau)

FYI Cette fonctionnalité est généralement appelée "cachette" plutôt que "masquage". Je pense à "masquer" comme des bits de compensation dans un tableau de bits.

Il manque le point de savoir pourquoi je voudrais le faire.

Normalement, vous ne voulez pas. Pour certaines raisons d'utiliser et de ne pas utiliser cette fonctionnalité, voir mon article sur le sujet à partir de 2008:

http: // blogs .msdn.com / B / ERICLIPPERT / Archive / 2008/05/12 / Méthode-cache-apologia.aspx

Le masquage nous fournit-il un certain niveau de protection, comme c'est le cas dans l'utilisation d'encapsulation?

Non, ce n'est pas.


0 commentaires