2009-06-16 5 views
2

Je passe de PHP à C#.Quels sont les exemples concrets de mots clés abstraits nouveaux/virtuels/overrides/abstraits?

En PHP, il est simple et facile à utiliser des classes abstraites pour créer un motif « cascade override », essentiellement "la méthode de classe de base prendra soin à moins que la classe héritant a une méthode avec la même signature ".

En C#, cependant, je viens de passer environ 20 minutes d'essayer diverses combinaisons des mots-clés nouvelle, virtuel, abstrait et override dans la base et héritant cours jusqu'à ce que je a finalement obtenu la bonne combinaison qui fait ce simple modèle de priorité en cascade.

Donc, même si le code ci-dessous fonctionne comme je le veux, ces mots-clés ajoutés me suggèrent que C# peut faire beaucoup plus avec les classes abstraites. J'ai recherché des exemples de ces mots-clés et comprendre fondamentalement ce qu'ils font, mais je ne peux toujours pas imaginer un scénario réel dans lequel je les utiliserais autre que ce simple modèle de "cascade". Quels sont certains monde réel manières dont vous implémentez ces mots-clés dans votre programmation au jour le jour?

Code

qui fonctionne:

using System; 

namespace TestOverride23433 
{ 
    public class Program 
    { 
     static void Main(string[] args) 
     { 
      string[] dataTypeIdCodes = { "line", "wn" }; 
      for (int index = 0; index < dataTypeIdCodes.Length; index++) 
      { 
       DataType dataType = DataType.Create(dataTypeIdCodes[index]); 
       Console.WriteLine(dataType.GetBuildItemBlock()); 
      } 

      Console.ReadLine(); 
     } 
    } 

    public abstract class DataType 
    { 
     public static DataType Create(string dataTypeIdCode) 
     { 
      switch (dataTypeIdCode) 
      { 
       case "line": 
        return new DataTypeLine(); 
       case "wn": 
        return new DataTypeWholeNumber(); 
       default: 
        return null; 
      } 
     } 

     //must be defined as virtual 
     public virtual string GetBuildItemBlock() 
     { 
      return "GetBuildItemBlock executed in the default datatype class"; 
     } 
    } 

    public class DataTypeLine : DataType 
    { 
     public DataTypeLine() 
     { 
      Console.WriteLine("DataTypeLine just created."); 
     } 
    } 

    public class DataTypeWholeNumber : DataType 
    { 
     public DataTypeWholeNumber() 
     { 
      Console.WriteLine("DataTypeWholeNumber just created."); 
     } 

     //new public override string GetBuildItemBlock() //base method is erroneously executed 
     //public override string GetBuildItemBlock() //gets error "cannot override inherited member because it is not marked virtual, abstract, or override" 
     public override string GetBuildItemBlock() 
     { 
      return "GetBuildItemBlock executed in the WHOLENUMBER class."; 
     } 
    } 

} 
+0

Voici quelques remarques sur les situations (rares) dans lesquelles on pourrait vouloir utiliser "nouveau" pour faire une dissimulation de méthode. http://blogs.msdn.com/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx –

Répondre

8

virtual/override est la paire de polymorphisme de base; semble que vous avez déjà craqué ces

abstract est comme virtual, mais il est aucune implémentation de base sensible; use-cases: peut-être un Stream, où est nécessaire pour que l'implémentation réelle fasse quelque chose avec les octets. Cela force la classe à être abstract

new devrait normalement être évitée; il casse le polymorphisme ... le cas le plus courant est de ré-exposer avec une signature/type de retour plus spécifique (peut-être dans une classe scellée, puisqu'il ne devient pas plus joli dans la chaîne ...) - voir SqlConnection.CreateCommand (vs DbConnection.CreateCommand), ou (peut-être plus notamment) IEnumerator<T>.Current (vs IEnumerator.Current)

4

Il semble que vous avez déjà compris virtual et override de votre exemple, si:

  • 'abstract' peut également être appliqué aux membres au lieu de 'virtual', auquel cas vous ne spécifiez pas d'implémentation pour la méthode ('; 'directement après la signature). Cela force tous les descendants concrets à implémenter la méthode. 'new' n'a rien à voir avec l'héritage, mais peut être utilisé dans une classe descendante sur un membre pour cacher un membre de la classe de base qui a exactement la même signature.

En un mot;)

1

De plus aux autres réponses. Remplacer lorsque vous souhaitez autoriser les classes enfants à effectuer leur propre traitement, aucun traitement ou même simplement appeler le traitement de classe parent pour une fonction. Une substitution ou une fonction virtuelle ne doit pas être implémentée dans les classes descendantes.

Résumé lorsque vous ne souhaitez pas effectuer de traitement dans votre classe de base mais que cette méthode doit être implémentée par une classe héritière. (Meilleur lorsque le comportement de la classe héritière peut différer considérablement). Si une classe ne contient que des méthodes abstraites, il s'agit effectivement d'un type d'interface. Une fonction spécifiée comme abstract DOIT être implémentée dans la classe enfant (le compilateur lancera une erreur sinon).