Conception C #: Pourquoi le nouveau / override est-il requis sur les méthodes abstraites mais pas sur les méthodes virtuelles?
Pourquoi est-nouveau/remplacer nécessaires sur les méthodes abstraites, mais pas sur les méthodes virtuelles?
Exemple 1:
abstract class ShapesClass
{
abstract public int Area(); //abstract!
}
class Square : ShapesClass
{
int x, y;
public int Area() //Error: missing 'override' or 'new'
{
return x * y;
}
}
Le compilateur affiche cette erreur:
Pour rendre le membre actuel ignorer que la mise en œuvre, ajoutez le mot-clé override. Sinon, ajouter un nouveau mot-clé
Exemple 2:
class ShapesClass
{
virtual public int Area() { return 0; } //it is virtual now!
}
class Square : ShapesClass
{
int x, y;
public int Area() //no explicit 'override' or 'new' required
{
return x * y;
}
}
Cela permettra de compiler fine, en se cachant la méthode par défaut.
Je comprends pleinement les différences techniques. Cependant je me demande pourquoi le langage a été conçu de cette façon. Ne serait-il pas mieux d'avoir la même restriction en "Exemple 2"? Je veux dire que dans la plupart des cas, si vous créez une méthode avec le même nom que dans la classe parent, vous avez généralement l'intention de le remplacer. Je pense donc qu'en indiquant expressément Override/Nouvelle aurait du sens sur des méthodes virtuelles.
Est là une conception-sage raison de ce comportement?
Mise à jour:
Le 2ème échantillon provoque un avertissement. Le premier exemple montre une erreur, car le sous-classe est nécessaire pour mettre en œuvre la méthode abstraite. Je n'ai pas vu l'avertissement de VS.. fait parfaitement sens pour moi maintenant. Merci.
source d'informationauteur driAn
Vous devez vous connecter pour publier un commentaire.
Utilisant le C# 3.0 compilateur comme livré .NET 3.5 SP1, ou le C# 4.0 compilateur comme livré .NET 4.0, j'ai le erreur pour votre premier exemple:
Et suivants avertissement pour la seconde:
Dans le premier cas c'est une erreur, parce que vous n'êtes pas réellement substitution de la méthode de base, ce qui signifie qu'il n'est pas de mise en œuvre de la méthode abstraite dans une classe concrète. Dans le deuxième cas, c'est un avertissement, car le code est techniquement correct, mais le compilateur soupçonne que ce n'est pas ce que vous voulez dire. C'est l'une des raisons pour laquelle il est généralement une bonne idée d'activer la fonction "traiter les avertissements comme des" erreurs de compilation réglage.
Donc je ne peux pas repro de votre comportement et le comportement du compilateur semble bonne pour moi. La version du compilateur que vous utilisez?
Voici la réponse directement à partir de la C# spec.
La différence est que la méthode abstraite doit être remplacée, mais le virtuel ne fonctionne pas.
C'est une erreur de héritent de la classe abstraite (dans un non-classe abstraite) sans la mise en œuvre de tous les membres abstraits, mais vous obtenez seulement un avertissement lors de la héritant de la classe, sans préciser
override
ounew
pour la méthode virtuelle.Je pense que dans la première méthode, vous obtenez l'erreur de compilation, car la méthode abstraite est caché et non mis en œuvre (si efficacement votre classe est mal, et il serait difficile de comprendre pourquoi). Dans le second cas, vous obtenez seulement un avertissement, parce que la classe est utilisable.
Versioning
Au premier coup d'œil, vous pouvez penser que la méthode de masquage n'apparaît pas particulièrement utile. Il y a une situation
si vous avez besoin de l'utiliser, cependant. Disons que vous souhaitez utiliser une classe nommée
MotorVehicle
quea été écrit par un autre programmeur, et que vous souhaitez utiliser cette classe pour tirer votre propre classe. En outre,
supposons également que vous souhaitez définir un
Accelerate()
méthode dans votre classe dérivée. Par exemple:Ensuite, supposons que l'autre programmeur modifie ultérieurement la MotorVehicle classe et décide
pour ajouter sa propre
virtual Accelerate()
méthode:L'ajout de cette
Accelerate()
méthode par l'autre programmeur à l'origine du problème: L'Accelerate()
méthode dans votreCar
classe cache les héritéAccelerate()
une méthode définie dansleur
MotorVehicle
classe. Plus tard, quand vous venez de compiler votreCar
classe, il n'est pas clair pour le compilateursi vous avez prévu votre méthode pour masquer la méthode héritée. De ce fait, l'
compilateur signale le message d'avertissement suivant lorsque vous essayez de compiler votre Voiture de classe: