Абстрактные классы и методы в Java, Наследование

У меня есть класс 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 аннотация abstract указывает, что класс не может быть непосредственно создан. Класс может быть объявлен abstract просто потому, что он никогда не должен быть создан (возможно, он содержит только статические методы) или потому, что его подклассы должны быть созданы вместо него.

Это не требование, чтобы классы abstract содержали методы abstract (значение ): класс, содержащий один или несколько методов abstract, должен быть abstract.)

Вопрос о том, следует ли дублировать определение абстрактного метода, можно воспринимать как вопрос стиля, но мне было бы трудно найти аргумент в пользу дублирования определения (единственным аргументом, который я могу придумать, является в случае, когда иерархия классов может изменить семантику или использовать метод, и поэтому вы хотели бы предоставить дополнительный javadoc в классе B.)

Первичный аргумент против повторного определения метода abstract заключается в том, что дублирующий код плохой - он делает реорганизацию более громоздкой и такой (применимы все классические аргументы "не дублировать код".)

Ответ 2

Они функционально равны, но первый предпочтительнее, потому что он короче и не является странным.

Ответ 3

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

Ответ 4

Итак, вопрос: какой из них предпочтительнее, если подкласс классифицирует абстрактный класс в java и не хочет предоставлять реализацию?

a) добавить подкласс как абстрактный тоже

b) маркировать подкласс как абстрактное тоже И переписать подпись метода, помеченную как абстрактную?

Я бы пошел первым:

a) Отметьте также подкласс как абстрактный.

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

Ответ 5

Вы правы, эти два случая эквивалентны. Случай 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 {
  ...
}