Как вызвать метод производного класса из базового класса?

Я прочитал несколько похожих вопросов по этому поводу, но, похоже, ни один из них не решил проблему, с которой я столкнулся. Типичным ответом является приведение в качестве производного класса, но я не могу, поскольку не знаю тип производного класса.

Вот мой пример:

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

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

Беспроводное устройство также можно использовать для создания устройств Bluetooth, Wi-Max, Cellular и т. Д., И поэтому я не знаю, какой тип беспроводного устройства будет получать данные.

Когда пакет GPS получен на веб-сокете в базовом классе, мне нужно обновить местоположение производного устройства.

Я подумал, возможно, отправив сообщение через очередь или создав обработчик события и отправив местоположение в аргументах события, но они кажутся немного неуклюжими, когда данные остаются в классе.

Есть ли что-то встроенное в язык, которое позволило бы мне вызывать мое производное устройство из базового класса, не зная типа?

2 ответа

Решение

Правильный способ - добавить метод 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;
}

Виртуальные методы были бы хорошим решением. Вы создаете метод 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). Однако в этом случае я хотел бы рассмотреть перемещение кода веб-сокета в производный класс.

Другие вопросы по тегам