C'est l'une d'une mini-série qui couvre les différences de surcharges, d'ombres et de remplacements dans VB.NET. Cet article couvre les remplacements. Les articles qui couvrent les autres sont ici:
-> Surcharges
-> Ombres
Ces techniques peut être extrêmement déroutant; il existe de nombreuses combinaisons de ces mots clés et des options d'héritage sous-jacentes. La propre documentation de Microsoft ne commence pas à rendre justice au sujet et il y a beaucoup d'informations mauvaises ou obsolètes sur le Web. Le meilleur conseil pour être sûr que votre programme est correctement codé est «Testez, testez et testez à nouveau». Dans cette série, nous les examinerons un à la fois en mettant l'accent sur les différences.
Remplace
La chose que les ombres, les surcharges et les remplacements ont tous en commun est qu'ils réutilisent le nom des éléments tout en changeant ce qui se passe. Les ombres et les surcharges peuvent fonctionner à la fois dans la même classe ou lorsqu'un la classe hérite une autre classe. Toutefois, les remplacements ne peuvent être utilisés que dans une classe dérivée (parfois appelée classe enfant) qui hérite d'un
classe de base (parfois appelée classe parent). Et Overrides est le marteau; il vous permet de remplacer entièrement une méthode (ou une propriété) d'une classe de base.Dans l'article sur les classes et le mot clé Shadows (Voir: Shadows dans VB.NET), une fonction a été ajoutée pour montrer qu'une procédure héritée pouvait être référencée.
Public Class ProfessionalContact. '... code non affiché... Fonction publique HashTheName ( ByVal nm As String) As String. Retour nm. GetHashCode. Fonction de fin. Fin de classe.
Le code qui instancie une classe dérivée de celle-ci (CodedProfessionalContact dans l'exemple) peut appeler cette méthode car elle est héritée.
Dans l'exemple, j'ai utilisé le VB.NET GetHashCode pour garder le code simple et cela a renvoyé un résultat assez inutile, la valeur -520086483. Supposons que je voulais un résultat différent à la place, mais,
-> Je ne peux pas changer la classe de base. (Peut-être que tout ce que j'ai est du code compilé d'un fournisseur.)
... et ...
-> Je ne peux pas changer le code d'appel (Peut-être qu'il y a mille copies et je ne peux pas les mettre à jour.)
Si je peux mettre à jour la classe dérivée, je peux modifier le résultat renvoyé. (Par exemple, le code peut faire partie d'une DLL pouvant être mise à jour.)
Il y a un problème. Parce qu'il est si complet et puissant, vous devez avoir l'autorisation de la classe de base pour utiliser les remplacements. Mais des bibliothèques de code bien conçues le fournissent. (Votre les bibliothèques de code sont toutes bien conçues, non?) Par exemple, la fonction fournie par Microsoft que nous venons d'utiliser est remplaçable. Voici un exemple de la syntaxe.
Fonction publique remplaçable GetHashCode en tant qu'entier
Donc, ce mot clé doit également être présent dans notre exemple de classe de base.
Fonction publique remplaçable HashTheName ( ByVal nm As String) As String.
Remplacer la méthode est désormais aussi simple que d'en fournir un nouveau avec le mot clé Overrides. Visual Studio vous donne à nouveau un bon départ en remplissant le code pour vous avec la saisie semi-automatique. Quand vous entrez ...
Fonction de substitution publique HashTheName (
Visual Studio ajoute automatiquement le reste du code dès que vous tapez la parenthèse ouvrante, y compris l'instruction return qui appelle uniquement la fonction d'origine à partir de la classe de base. (Si vous ajoutez simplement quelque chose, c'est généralement une bonne chose à faire après l'exécution de votre nouveau code.)
Fonction de substitution publique HashTheName ( nm As String) As String. Retournez MyBase. HashTheName (nm) Fonction de fin.
Dans ce cas, cependant, je vais remplacer la méthode par quelque chose d'autre tout aussi inutile juste pour illustrer comment c'est fait: la fonction VB.NET qui inversera la chaîne.
Fonction de substitution publique HashTheName ( nm As String) As String. Renvoyez Microsoft. Visual Basic. StrReverse (nm) Fonction de fin.
Maintenant, le code appelant obtient un résultat entièrement différent. (Comparez avec le résultat dans l'article sur les ombres.)
ContactID: 246. Nom commercial: Villain Defeaters, GmbH. Hachage du nom commercial: HbmG, nialliV sretaefeD.
Vous pouvez également remplacer les propriétés. Supposons que vous ayez décidé que les valeurs ContactID supérieures à 123 ne seraient pas autorisées et devraient par défaut être 111. Vous pouvez simplement remplacer la propriété et la modifier lorsque la propriété est enregistrée:
_ContactID privé comme entier. Public remplace la propriété ContactID en tant qu'entier. Avoir. Renvoie _ContactID. Fin Get. Set (ByVal value As Integer) Si valeur> 123 Then. _ContactID = 111. Autre. _ContactID = valeur. Fin si. Fin du jeu. Propriété de fin.
Ensuite, vous obtenez ce résultat lorsqu'une valeur supérieure est transmise:
ContactID: 111. Nom commercial: Damsel Rescuers, LTD.
Par ailleurs, dans l'exemple de code jusqu'à présent, les valeurs entières sont doublées dans le Nouveau sous-programme (Voir l'article sur les ombres), donc un entier de 123 est changé en 246, puis de nouveau en 111.
VB.NET vous donne encore plus de contrôle en permettant à une classe de base d'exiger ou de refuser spécifiquement une classe dérivée à remplacer à l'aide des mots-clés MustOverride et NotOverridable dans la classe de base. Mais les deux sont utilisés dans des cas assez spécifiques. Tout d'abord, NotOverridable.
Étant donné que la valeur par défaut pour une classe publique est NotOverridable, pourquoi devriez-vous avoir besoin de la spécifier? Si vous l'essayez sur la fonction HashTheName dans la classe de base, vous obtenez une erreur de syntaxe, mais le texte du message d'erreur vous donne un indice:
'NotOverridable' ne peut pas être spécifié pour les méthodes qui ne remplacent pas une autre méthode.
La valeur par défaut pour une méthode substituée est exactement le contraire: Overrideable. Donc, si vous voulez que la substitution s'arrête définitivement là, vous devez spécifier NotOverridable sur cette méthode. Dans notre exemple de code:
NotOverridable public Remplace Fonction HashTheName (...
Ensuite, si la classe CodedProfessionalContact est, à son tour, héritée ...
Classe publique NotOverridableEx. Hérite de CodedProfessionalContact.
... la fonction HashTheName ne peut pas être remplacée dans cette classe. Un élément qui ne peut pas être remplacé est parfois appelé élément scellé.
Un élément fondamental de les .Fondation NET est d'exiger que le but de chaque classe soit explicitement défini pour supprimer toute incertitude. Un problème dans les langues OOP précédentes a été appelé «la classe de base fragile». Cela se produit lorsqu'une base classe ajoute une nouvelle méthode avec le même nom qu'un nom de méthode dans une sous-classe qui hérite d'une base classe. Le programmeur qui écrit la sous-classe n'avait pas l'intention de remplacer la classe de base, mais c'est exactement ce qui se passe de toute façon. On sait que cela a provoqué le cri du programmeur blessé: "Je n'ai rien changé, mais mon programme s'est écrasé de toute façon. "S'il est possible qu'une classe soit mise à jour à l'avenir et crée ce problème, déclarez-la comme NotOverridable.
MustOverride est le plus souvent utilisé dans ce qu'on appelle une classe abstraite. (En C #, la même chose utilise le mot-clé Abstract!) Il s'agit d'une classe qui fournit simplement un modèle et vous êtes censé le remplir avec votre propre code. Microsoft en donne un exemple:
Classe publique MustInherit WashingMachine. Sous nouveau () 'Le code pour instancier la classe va ici. End sub. Sous-lavage public MustOverride. Sous-rinçage public MustOverride (loadSize as Integer) Fonction publique MustOverride Spin (vitesse en nombre entier) aussi longue. Fin de classe.
Pour continuer l'exemple de Microsoft, les machines à laver feront ces choses (Wash, Rinse et Spin) assez différemment, il n'y a donc aucun avantage à définir la fonction dans la classe de base. Mais il y a un avantage à s'assurer que toute classe qui hérite de celle-ci Est-ce que les définir. La solution: une classe abstraite.
Si vous avez besoin de plus d'explications sur les différences entre les surcharges et les remplacements, un exemple complètement différent est développé dans un conseil rapide: surcharges par rapport aux remplacements
VB.NET vous donne encore plus de contrôle en permettant à une classe de base d'exiger ou de refuser spécifiquement une classe dérivée à remplacer à l'aide des mots-clés MustOverride et NotOverridable dans la classe de base. Mais les deux sont utilisés dans des cas assez spécifiques. Tout d'abord, NotOverridable.
Étant donné que la valeur par défaut pour une classe publique est NotOverridable, pourquoi devriez-vous avoir besoin de la spécifier? Si vous l'essayez sur la fonction HashTheName dans la classe de base, vous obtenez une erreur de syntaxe, mais le texte du message d'erreur vous donne un indice:
'NotOverridable' ne peut pas être spécifié pour les méthodes qui ne remplacent pas une autre méthode.
La valeur par défaut pour une méthode substituée est exactement le contraire: Overrideable. Donc, si vous voulez que la substitution s'arrête définitivement là, vous devez spécifier NotOverridable sur cette méthode. Dans notre exemple de code:
NotOverridable public Remplace Fonction HashTheName (...
Ensuite, si la classe CodedProfessionalContact est, à son tour, héritée ...
Classe publique NotOverridableEx. Hérite de CodedProfessionalContact.
... la fonction HashTheName ne peut pas être remplacée dans cette classe. Un élément qui ne peut pas être remplacé est parfois appelé élément scellé.
Une partie fondamentale de .NET Foundation est d'exiger que le but de chaque classe soit explicitement défini pour supprimer toute incertitude. Un problème dans les langues OOP précédentes a été appelé «la classe de base fragile». Cela se produit lorsqu'une base classe ajoute une nouvelle méthode avec le même nom qu'un nom de méthode dans une sous-classe qui hérite d'une base classe. Le programmeur qui écrit la sous-classe n'avait pas l'intention de remplacer la classe de base, mais c'est exactement ce qui se passe de toute façon. On sait que cela a provoqué le cri du programmeur blessé: "Je n'ai rien changé, mais mon programme s'est écrasé de toute façon. "S'il est possible qu'une classe soit mise à jour à l'avenir et crée ce problème, déclarez-la comme NotOverridable.
MustOverride est le plus souvent utilisé dans ce qu'on appelle une classe abstraite. (En C #, la même chose utilise le mot-clé Abstract!) Il s'agit d'une classe qui fournit simplement un modèle et vous êtes censé le remplir avec votre propre code. Microsoft en donne un exemple:
Classe publique MustInherit WashingMachine. Sous nouveau () 'Le code pour instancier la classe va ici. End sub. Sous-lavage public MustOverride. Sous-rinçage public MustOverride (loadSize as Integer) Fonction publique MustOverride Spin (vitesse en nombre entier) aussi longue. Fin de classe.
Pour continuer l'exemple de Microsoft, les machines à laver feront ces choses (Wash, Rinse et Spin) assez différemment, il n'y a donc aucun avantage à définir la fonction dans la classe de base. Mais il y a un avantage à s'assurer que toute classe qui hérite de celle-ci Est-ce que les définir. La solution: une classe abstraite.
Si vous avez besoin de plus d'explications sur les différences entre les surcharges et les remplacements, un exemple complètement différent est développé dans un conseil rapide: surcharges par rapport aux remplacements