Переопределение метода экземпляра статическими - PullRequest
1 голос
/ 12 января 2010

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

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

Глупый пример:

  • Изображение { абстрактная строка getExtension (); ...

  • RGBImage расширяет изображение { static String getExtension () {return "RGB"}; ..

  • PNGImage extends Image { static String getExtension () {return "PNG"}; ...

Ответы [ 9 ]

1 голос
/ 12 января 2010

Как уже говорили другие, Java не поддерживает переопределение или abstract для статических методов.Тем не менее, я не совсем понимаю, чего бы вы достигли с помощью «абстрактного» статического метода.

Обычное использование абстрактного метода - заставить каждый подкласс реализовывать метод с одинаковой сигнатурой.Но почему это даже имеет значение для статического (следовательно, не полиморфного) метода?Если вы забыли предоставить метод для одного из подклассов, ЛИБО это не имеет значения, потому что вы его не вызываете, ИЛИ это имеет значение, но вы получите ошибку компиляции в тот момент, когда вы попытаетесь вызвать отсутствующий метод.

Единственный вариант использования, который я могу придумать, где это может иметь значение, - это если вы вызываете метод рефлексивно псевдополиморфным способом.Но если вы делаете это, вам лучше использовать реальный полиморфизм и методы экземпляров.

1 голос
/ 12 января 2010

Посмотрите на это объяснение . Вы можете использовать шаблон Builder для своих целей.

0 голосов
/ 12 января 2010

Да, спасибо, это то, что я делаю, перенастройте статический констат. В любом случае он возвращает объект класса внутреннего перечисления, в котором перечислены имена разделов заданного формата файла: формат файла подкласса.

Но вы очень ясно изложили это в своем примере:

public String getExtension () {

return STATIC_CONSTANT;

}

Я ожидал, что смогу поставить "static" перед String ...

0 голосов
/ 12 января 2010

как уже говорили другие, static не полиморфен ... это означает, что он одинаков для класса, не специфичен для экземпляра. я не уверен, чего бы вы достигли, используя статический метод ... но вы могли бы заставить свою расширенную реализацию метода возвращать статическое значение:

public String getExtension() {
  return STATIC_CONSTANT;
}

Полагаю, это зависит от того, чего вы пытаетесь достичь статическим методом. Из вашего поста: «Позвольте мне сказать, что все работает нормально, реализуя метод getExtension () экземпляра в каждом подклассе. Но дело в том, что метод фактически является статическим в подклассе, не зависит от экземпляра. Я просто говорю, что это не такая уж странная идея для меня. "

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

0 голосов
/ 12 января 2010

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

Проще говоря, даже пример не имеет смысла:

Image{

abstract String getExtension();

int process(){

   return getExtension().length

}

Алгоритм в process() является общим для всех подклассов XXXImage из Image, поэтому его правильное место - суперкласс.

Позвольте мне сказать, что все работает нормально, реализуя метод экземпляра getExtension() в каждом подклассе. Но дело в том, что метод на самом деле статичен в подклассе, не зависит от экземпляра.

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

0 голосов
/ 12 января 2010

Невозможно переопределить статические методы, так как они относятся к классу, а не к экземпляру.

Кроме того, метод экземпляра нельзя сделать статическим в подклассах, как вы предлагаете в своем примере.

Можете ли вы предоставить дополнительную информацию о том, почему все подклассы должны иметь одинаковый статический метод?

0 голосов
/ 12 января 2010

Вы хотите переопределить метод экземпляра статическим методом? Это бессмысленно. Статические методы не являются полиморфными. Как бы вы хотели это назвать? В Java невозможно заставить класс иметь статический метод с заданной сигнатурой.

0 голосов
/ 12 января 2010

К сожалению, это невозможно в Java. Вы должны сделать их экземплярами методов, чтобы иметь возможность определять их как абстрактные.

0 голосов
/ 12 января 2010

Я не очень много работаю с Java, но (используя логику C ++) вы могли бы сделать реализацию базового класса фиктивной реализацией, которую невозможно выполнить.

static void DoStuff(arg_type arg)
{
    std::cerr << "Method DoStuff() must be overriden\n";
    ::abort();
}

Это не так хорошо, как абстракцияметод, но он достигнет некоторых из тех же результатов.

...