Статический метод наследования - PullRequest
1 голос
/ 14 декабря 2010

У меня есть родительский класс с методами для записи и чтения из БД.Проблема в том, что у меня есть статический метод, который я хочу обобщить.Какова лучшая практика для этого?Я придумал несколько решений, но все они не работают со статическим методом.

Есть ли способ заставить дочерний объект реализовать абстрактный метод?

Родительский класс:

public class Data_object  {

    public byte[] toByteArray() throws IOException  {
        return null;
    }
    public static Data_object fromByteArray(byte[] data){
        return null
    }
}

Детский класс:

public class ModelObject extends Data_object {

    public static Data_object fromByteArray(byte[] data){
        ModelObject result = new ModelObject();
        //set data from byte arrray
        return result;
    }
}

спасибо

Ответы [ 3 ]

4 голосов
/ 14 декабря 2010

Статический метод в Java не может быть abstract, и вы не можете его переопределить.Таким образом, вы не можете заставить подкласс реализовать определенный статический метод.

Единственный выход - требовать статический метод по соглашению (как примечание в сопутствующем JavaDoc) и использовать отражение для обеспечения во время выполнения (или во время сборки), что подкласс реализует требуемый статический метод.


Кстати - это распространенный «шаблон».Serializable не определяет какие-либо методы, но в документации упоминаются три метода:

private void writeObject(java.io.ObjectOutputStream out)
   throws IOException
private void readObject(java.io.ObjectInputStream in)
   throws IOException, ClassNotFoundException;
private void readObjectNoData() 
   throws ObjectStreamException;

«Инфраструктура сериализации объектов» теперь использует отражение, чтобы проверить, реализованы ли эти методы классом, и, если да,вызывает эти методы.

Но я рекомендую поискать другие решения до с использованием этой стратегии.

2 голосов
/ 14 декабря 2010

Статические методы не могут быть переопределены. Вы можете только скрыть методы суперкласса, определив метод с тем же именем и сигнатурой в подклассе, но это довольно запутанно и поэтому обычно не рекомендуется. К исходному методу суперкласса по-прежнему можно получить доступ, например, ((SuperClassName) subClassInstance).staticMethod().

В вашем случае, вероятно, лучше сделать метод нестатичным.

1 голос
/ 14 декабря 2010

Наследование не распространяется на статические методы таким образом.Вы вызываете статический метод для определенного класса, например так:

MonkeyModelObject.fromByteArray(data)

Даже если вы делаете это «изнутри» класса, вы за кадром все еще вызываете этот конкретный метод для этого конкретногоучебный класс.Поэтому, если вы «переопределяете» статический метод, вы просто создаете новый метод с тем же именем в другом классе (дочернем классе).Выбор статических методов во время выполнения отсутствует.

В конкретном случае, над которым вы работаете, создается впечатление, что вы выполняете сериализацию из / в байтовые массивы.Возможно, вы сериализуете сообщения из сетевого потока или что-то в этом роде?Я бы порекомендовал следующий подход, возможно, этот псевдокод может вдохновить вас:

abstract class Message
{
    void write(stream)
    {
        stream.write(getMessageTypeCode());
        writeParameters(stream);
    }
    abstract int getMessageTypeCode();
    abstract void writeParameters(stream);
    abstract void readParamters(stream);
}
class ChatMessage
{
    String text;
    int getMessageTypeCode() { return 1; }
    void writeParameters(stream)
    {
        stream.write(text);
    }
    void readParameters(stream)
    {
        text = stream.read();
    }
}
class MessageDecoder
{
    Message decode(stream)
    {
        int type = stream.read();
        message = createMessage(type);
        message.readParameters(stream);
        return message;
    }
    Message createMessage(int type)
    {
        if (type == 1)
        {
            return new ChatMessage();
        }
        throw new error;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...