如何从基类调用派生类方法?

Posted

技术标签:

【中文标题】如何从基类调用派生类方法?【英文标题】:How do I call a derived class method from the base class? 【发布时间】:2013-04-11 21:54:43 【问题描述】:

我已经阅读了几个类似的问题,但似乎没有一个可以解决我面临的问题。典型的答案是强制转换为派生类,但我不能,因为我不知道派生类的类型。

这是我的例子:

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


class WiFi : WireLessDevice  // derived class
    GPSLoc Loc;

无线设备也可以派生成蓝牙、Wi-Max、蜂窝等设备,因此我不知道哪种类型的无线设备会接收数据。

当基类的 websocket 收到 GPS 数据包时,我需要更新派生设备的位置。

我想也许可以通过队列发送消息或创建事件处理程序并在事件参数中发送位置,但当数据保留在类中时,这些似乎有点笨拙。

语言中是否有内置的东西可以让我在不知道类型的情况下从基类调用派生设备?

【问题讨论】:

看看装饰图案。您的问题似乎是您的错误设计。 不需要装饰器...看看抽象或虚拟方法... 【参考方案1】:

正确的做法是在基类中添加一个方法DoSomeMagic(), 使用默认实现或抽象。 派生类应该重写它来发挥它的魔力。

可能是这样的:

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;

【讨论】:

所以如果我从基类 websocket.parsemessage() 调用 this.setGPSLocation,它会自动调用派生类的 setGPSLocation? 我不会从基类调用 SetGPSLocation,而是在派生类中调用。将更新我的答案以进行演示。 不完全确定,但我认为virtual 方法必须具有声明的主体。只有abstract 方法没有主体。 正确,这应该是带有主体的虚拟或抽象 Omer,您的更新看起来很有希望。我不想使用抽象并将整个 ParseMessage 方法拉入所有派生类 - 需要复制和维护大量代码。你所拥有的看起来很适合我需要做的事情,但你所说的“虚拟身体”是什么意思,或者你是否更新了示例以包含它?【参考方案2】:

Virtual methods 将是一个很好的解决方案。您在基类中创建一个方法ParseMessage,该方法处理每个派生类型共有的所有内容,然后覆盖特定设备。

为了仍然能够处理其他消息类型,您需要酌情调用base.ParseMessage

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;
        
    

如果您的基类不处理任何其他消息,则代码可能会更简单(并使用abstract)。但是,在这种情况下,我会考虑将 Web 套接字代码移至派生类。

【讨论】:

这个解决方案类似于 Omer 的,我相信对我有用。我会试一试并更新回复。谢谢索拉林! @CramerTV 这就是当有人编辑他们的帖子时你得到的回答,但是是的,它几乎是一样的。我更喜欢我的解释,所以我保留了答案。 索拉林效果很好。我将您的返回值修改为枚举类型,其中 GPS 是值之一。通过这种方式,parseMessage 例程将返回一个值,该值告诉已收到什么类型的消息,并且我仅在被解析的消息对应于 GPS 坐标时更新位置(我可能有其他“特殊情况”消息需要稍后操作.) 我还在枚举中包含了一个“错误”类型,这样我就可以识别出像上面的示例一样的失败。感谢您的回答。我对你们俩都投了赞成票,但仅仅因为他是第一个而选择了 Omer 的答案。 伙计们,挑战确实是自动做到这一点。当然,当然,您可以覆盖该函数,然后(如果需要)在派生函数中调用 base.function。我想知道的是:您可以在 BASE 函数中说些什么,这意味着:“好的,如果某些虫子隐藏了这个函数,那么首先运行这个函数,实际上也运行这个派生函数”。有没有办法做到这一点???

以上是关于如何从基类调用派生类方法?的主要内容,如果未能解决你的问题,请参考以下文章

从基类调用派生类的隐藏(非虚拟)方法

从基类c ++的向量中的派生类调用虚拟方法[重复]

派生类不从基类继承重载方法

如何从基类调用派生类函数?

如何从基类调用派生赋值运算符?

从基类类型的向量访问派生类方法