2013-04-18 4 views
14

J'ai lu plusieurs questions similaires à ce sujet mais aucune ne semble résoudre le problème auquel je suis confronté. La réponse typique est de lancer en tant que classe dérivée mais je ne peux pas puisque je ne connais pas le type de classe dérivé.Comment appeler une méthode de classe dérivée à partir de la classe de base?

Voici mon exemple:

class WireLessDevice { // base class 
    void websocket.parsemessage(); // inserts data into the wireless device object 
} 

class WiFi : WireLessDevice { // derived class 
    GPSLoc Loc; 
} 

dispositif sans fil peut également être dérivé pour rendre Bluetooth, Wi-Max, cellulaire, appareils, etc., et donc je ne sais pas quel type de wirelessdevice va recevoir les données .

Lorsqu'un paquet GPS est reçu sur la socket Web dans la classe de base, j'ai besoin de mettre à jour l'emplacement du périphérique dérivé. Je pensais peut-être envoyer un message via une file d'attente ou créer un gestionnaire d'événements et envoyer l'emplacement dans les arguments d'événement, mais ceux-ci semblent un peu maladroit lorsque les données restent dans la classe.

Y at-il quelque chose de intégré dans le langage qui me permettrait d'appeler mon périphérique dérivé de la classe de base sans connaître le type?

+0

Jetez un coup d'œil au motif de décoration. Votre problème semble être votre mauvais design. –

+4

Pas besoin de décorateur ... Jetez un coup d'œil aux méthodes abstraites ou virtuelles ... – Crisfole

Répondre

31

La méthode correcte consiste à ajouter une méthode DoSomeMagic() dans la classe de base, avec l'implémentation par défaut, ou abstract. La classe dérivée devrait remplacer celle-ci pour faire sa magie.

Quelque chose comme ça peut-être:

public class WireLessDevice 
{ // base class 
    protected virtual void ParseMessage() 
    { 
     // Do common stuff in here 
    } 
} 

public class WiFi : WireLessDevice 
{ // derived class 
    override void ParseMessage() 
    { 
     base.ParseMessage();//Call this if you need some operations from base impl. 
     DoGPSStuff(); 
    } 
    private void DoGPSStuff() 
    { 
     //some gps stuff 
    } 
    GPSLoc Loc; 
} 
+4

+1 pour Magic ... – CSharpie

+0

Donc, si j'appelle this.setGPSLocation de la classe de base websocket.parsemessage(), il appellera automagiquement le classe dérivée 'setGPSLocation? – CramerTV

+0

Je n'appellerais pas SetGPSLocation de la classe de base, mais dans la classe dérivée. Mettra à jour ma réponse pour démontrer. –

2

Virtual methods serait une bonne solution. Vous créez une méthode ParseMessage dans la classe de base qui gère tous les éléments communs à chaque type dérivé, puis redéfinissez pour des périphériques spécifiques.

Afin d'être encore capable de gérer d'autres types de messages, vous devez appeler le base.ParseMessage selon le cas:

class WireLessDevice 
{ 
    protected virtual bool ParseMessage(byte[] message) 
    { 
     // Inspect message and handle the known ones 
     return true; // Only if message parsed, otherwise false 
    } 
} 

class WiFi : WireLessDevice 
{ 
    GPSLoc Loc; 

    protected override bool ParseMessage(byte[] message)  
    { 
     bool messageParsed = base.ParseMessage(message) 
     if (!messageParsed) 
     { 
      // Handle device specific message with GPSLoc 
      Loc = ... 
     } 
     else 
     { 
      return false; 
     } 
    } 
} 

Si votre classe de base ne traite pas d'autres messages, le code pourrait être plus simple (et en utilisant abstract). Cependant, dans ce cas, je considérerais de déplacer le code de socket web vers la classe dérivée.

+1

Cette solution est similaire à celle d'Omer et je crois qu'elle fonctionnera pour moi. Je vais essayer et mettre à jour les réponses. Merci Thorarin! – CramerTV

+0

@CramerTV C'est ce que vous obtenez pour répondre pendant que quelqu'un est en train d'éditer leur message, mais oui c'est presque identique. J'ai mieux aimé mon explication, alors j'ai gardé la réponse. – Thorarin

+0

Cela a bien fonctionné Thorarin. J'ai modifié votre valeur de retour pour être un type énuméré où le GPS était l'une des valeurs. De cette façon, le sous-programme parseMessage retournera une valeur indiquant quel type de message a été reçu et je ne mettrai à jour l'emplacement que si le message analysé correspond aux coordonnées GPS (il se peut que je doive utiliser d'autres messages .) J'ai également inclus un type 'erreur' dans l'énumération afin que je puisse reconnaître un échec comme votre exemple ci-dessus. Merci pour votre réponse. Je vous ai mis sur les deux, mais j'ai choisi la réponse d'Omer simplement parce qu'il était le premier. – CramerTV

Questions connexes