How do I call a derived class method from the base class?

48,804

Solution 1

The correct way is to add a method DoSomeMagic() in the base class, with default implementation, or abstract. The derived class should than override it to do its magic.

Something like this maybe:

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;
}

Solution 2

Virtual methods would be a good solution. You create a method ParseMessage in the base class which handles all the stuff common to each derived type, then override for specific devices.

In order to still be able to handle other message types, you will need to call the base.ParseMessage as appropriate:

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;
        }
    }
}

If your base class is not handling any other messages, the code could be simpler (and using abstract). However, in that case I would consider moving the web socket code to the derived class.

Share:
48,804

Related videos on Youtube

CramerTV
Author by

CramerTV

I'm a hole filler. If there's a hole on a project I do what I can to fill it. Experience Systems Engineering (design, architecture, requirements, test, simulation (MatLab/Simulink)) Digital Hardware design (board level design) Firmware (FPGA coding) Embedded SW (DSPs, microcontrollers, embedded microprocessors - mostly using 'C') Application (C#/.Net, Web (HTML/CSS/Javascript/JQuery/PHP)) Most work has been in wireless communications Pronouns: he, him

Updated on September 08, 2020

Comments

  • CramerTV
    CramerTV almost 4 years

    I have read several similar questions about this but none seem to solve the problem I am facing. The typical answer is to cast as the derived class but I cannot since I do not know the derived class type.

    Here is my example:

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

    Wireless Device can also be derived to make Bluetooth, Wi-Max, Cellular, etc. devices and thus I do not know which type of wirelessdevice will be receiving the data.

    When a GPS packet is received on the websocket in the base class I need to update the derived device's location.

    I thought perhaps sending a message via a queue or creating an event handler and sending the location in the event arguments but those seem a little clunky when the data is staying within the class.

    Is there something built into the language that would allow me to call my derived device from the base class without knowing the type?

    • Reza Owliaei
      Reza Owliaei about 11 years
      Take a look at decoration pattern. Your problem seems to be your wrong design.
    • Chris Pfohl
      Chris Pfohl about 11 years
      No need for a decorator...Take a look at abstract or virtual methods...
  • CramerTV
    CramerTV about 11 years
    So if I call this.setGPSLocation from the base class websocket.parsemessage() it will automagically call the derived class' setGPSLocation?
  • omer schleifer
    omer schleifer about 11 years
    I would not call SetGPSLocation from the base class, but in the derived class. Will update my answer to demonstrate.
  • LightStriker
    LightStriker about 11 years
    Not fully sure, but I think a virtual method must have a declared body. Only abstract method doesn't have a body.
  • omer schleifer
    omer schleifer about 11 years
    correct, this should be either virtual with a body or abstract
  • CramerTV
    CramerTV about 11 years
    Omer, Your update looks promising. I don't want to use abstract and pull the entire ParseMessage method into all the derived classes - it's a lot of code to be replicating and maintaining. What you have looks right for what I need to do but what do you mean by 'virtual with a body' or did you update the example to include that?
  • CramerTV
    CramerTV about 11 years
    This solution is similar to Omer's and I believe will work for me. I'll give it a try and update the responses. Thanks Thorarin!
  • omer schleifer
    omer schleifer about 11 years
    it means that virtual void foo(); is not allowed (nor is void foo();) you either make an abstact method: abstract void foo(); or you add a body: void foo() {//This is a body}. good luck
  • Thorarin
    Thorarin about 11 years
    @CramerTV That's what you get for answering while someone is editing their post, but yeah it's almost identical. I liked my explanation better, so I kept the answer.
  • CramerTV
    CramerTV about 11 years
    That worked great Thorarin. I modified your return value to be an enumerated type where GPS was one of the values. In this way the parseMessage routine would return a value that told what type of message had been received and I only update the location when the message being parsed corresponded to GPS coordinates (I may have other 'special case' messages I need to operate on later.) I also included an 'error' type in the enumeration so I could recognize a failure like your example above. Thanks for your answer. I upvoted you both but selected Omer's answer simply because he was first.
  • Fattie
    Fattie almost 11 years
    Guys, surely the challenge is to do this automatically, as it were. Of course, naturally, you can override the function and then (if you want) call base.function in the derived function. What I'm wondering: is there something you can say, in the BASE function, which means: "ok, if some bugger hides this function, then RUN THIS FUNCTION FIRST, and indeed ALSO!!! run that derived function". Is there a way to do that???