У меня есть класс B, который наследуется от класса A. Суперкласс A абстрактный, содержащий один абстрактный метод. Я не хочу реализовывать абстрактный метод в классе B, поэтому мне также нужно объявить класс B абстрактным. Объявляя абстрактный класс B, у меня работают две вещи (программы компилируются и работают правильно):
1.) Я не объявляю никаких абстрактных методов в классе B, даже если этот класс абстрактный. Я полагаю, это работает, потому что класс наследует абстрактный метод класса A, и этого достаточно, чтобы класс был объявлен как абстрактный: нам не нужны никакие другие абстрактные методы, напрямую объявленные в классе.
2.) Я объявляю тот же абстрактный метод в классе B, как он объявлен в классе A. Это своего рода переопределение (?), Не в том же смысле, что переопределение в java (с использованием того же заголовка, но с другой реализацией. ), здесь я снова использую тот же заголовок метода.
Обе вещи работают, и я не уверен, в порядке ли они оба и предпочтительнее ли одни из них (более правильные), чем другие. Одинаковы ли эти два способа (означают ли они то же самое для Java)?
Здесь я привожу несколько примеров классов, чтобы вам было понятнее то, что я имею в виду:
Дело 1.):
public abstract class A {
public abstract String giveSum();
}
public abstract class B extends A {
}
Случай 2.):
public abstract class A {
public abstract String giveSum();
}
public abstract class B extends A {
public abstract String giveSum();
}
С Уважением




Функционально они равны, но предпочтительнее первый, потому что он короче и не выглядит странным.
Выбери №1. Переписывание объявления метода в дочернем классе сбивает с толку. И вам действительно не нужны абстрактные методы в абстрактном классе, независимо от того, является ли родитель абстрактный или нет.
Но имеет ли смысл объявлять класс абстрактным, если в классе не объявлены абстрактные методы (и класс не наследуется от абстрактного класса?)
Ах, сообщение Джареда ниже отвечает на этот вопрос.
Итак, вопрос: что предпочтительнее при подклассе абстрактного класса в java и не хочет предоставлять реализацию?
a) mark subclass as abstract too
b) mark subclass as abstract too AND re-write the method signature marked as abstract?
Я бы выбрал первый:
a) Mark subclass as abstract too.
В первом уже есть объявление абстрактного метода, повторять его нет смысла.
В Java аннотация класса abstract указывает, что экземпляр класса нельзя создать напрямую. Класс может быть объявлен abstract просто потому, что он никогда не должен создаваться (возможно, он содержит только статические методы), или потому что вместо этого следует создавать экземпляры его подклассов.
нет является требованием, чтобы классы abstract содержали методы abstract (обратное является истинно: класс, содержащий один или несколько методов abstract, должен быть abstract.)
Вопрос о том, следует ли дублировать определение абстрактного метода, может быть воспринят как вопрос стиля, но мне было бы трудно придумать аргумент в пользу дублирования определения (единственный аргумент, который я могу придумать, касается случая где иерархия классов может изменить семантику или использование метода, и поэтому вы хотели бы предоставить дополнительную документацию javadoc в классе B.)
Главный аргумент против повторного определения метода abstract заключается в том, что дублирование кода - это плохо - это делает рефакторинг более громоздким и тому подобное (применяются все классические аргументы «не дублировать код».)
Вы правы, эти два случая эквивалентны. Случай 1) более простой, случай 2) - дублирование кода - избегайте этого. Но для этого может быть одна причина:
Если метод в классе A не возвращает String, но позволяет сказать C, класс B может переопределить его (начиная с Java 5) более конкретным типом возврата, допустим, D (класс расширяет C):
public abstract class A {
public abstract C giveSum();
}
public abstract class B extends A {
public abstract D giveSum();
}
public class C {
...
}
public class D extends C {
...
}
Как насчет того, чтобы «не сбивать с толку читателя, определяется ли новый метод», а не «не странно»? ;-)