Подтвердить что ты не робот

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

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

Например, с учетом интерфейса:

public interface IAnything {
  void m1();
  void m2();
  void m3();
}

следующий абстрактный класс легко компилируется без предупреждения или ошибки:

public abstract class AbstractThing implements IAnything {
  public void m1() {}
  public void m3() {}
}

Можете ли вы объяснить, почему?

4b9b3361

Ответ 1

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

Следуя примеру кода, попробуйте сделать подкласс AbstractThing без реализации метода m2 и посмотреть, какие ошибки дает вам компилятор. Это заставит вас реализовать этот метод.

Ответ 2

Совершенно прекрасно.
Вы не можете создавать абстрактные классы. Но абстрактные классы могут использоваться для размещения общих реализаций для m1() и m3().
Поэтому, если реализация m2() различна для каждой реализации, но m1 и m3 нет. Вы могли бы создавать различные конкретные реализации IAnything с помощью только разной реализации m2 и выводить из AbstractThing - соблюдая принцип DRY. Проверка корректности интерфейса для абстрактного класса бесполезна.

Обновить. Интересно, что я обнаружил, что С# применяет это как ошибку компиляции. Вы вынуждены копировать подписи метода и префикс их "абстрактной публикой" в абстрактном базовом классе в этом сценарии.. (что-то новое повседневное:)

Ответ 3

Это хорошо. Чтобы понять вышеизложенное, вы должны сначала понять природу абстрактных классов. В этом отношении они аналогичны интерфейсам. Это то, что Oracle говорит об этом здесь.

Абстрактные классы аналогичны интерфейсам. Вы не можете создавать их, и они могут содержать сочетание методов, объявленных с реализацией или без нее.

Итак, вы должны думать о том, что происходит, когда интерфейс расширяет другой интерфейс. Например...

//Filename: Sports.java
public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

//Filename: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

... как вы можете видеть, это также прекрасно компилируется. Просто потому, что, подобно абстрактному классу, интерфейс НЕ может быть создан. Таким образом, не требуется явно указывать методы из своего "родителя". Однако ВСЕ сигнатуры родительского метода DO неявно становятся частью расширяющегося интерфейса или реализуют абстрактный класс. Таким образом, как только правильный класс (тот, который может быть создан), расширяет вышесказанное, требуется, чтобы был реализован каждый абстрактный метод.

Надеюсь, что это поможет... и Аллаху алам!

Ответ 4

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

Ответ 5

Когда абстрактный класс реализует интерфейс

В разделе "Интерфейсы" было отмечено, что класс, который реализует интерфейс, который должен реализовывать все методы интерфейса. Однако можно определить класс, который не реализует все методов интерфейса, при условии, что класс объявлен как Абстрактные. Например,

abstract class X implements Y {   
    // implements all but one method of Y
}

class XX extends X {   
    // implements the remaining method in Y 
} 

В этом случае класс X должен быть абстрактным, потому что он не полностью реализуют Y, но класс XX фактически реализует Y.

Ссылка: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

Ответ 6

Абстрактные классы не требуются для реализации методов. Таким образом, хотя он реализует интерфейс, абстрактные методы интерфейса могут оставаться абстрактными. Если вы попытаетесь реализовать интерфейс в конкретном классе (т.е. Не абстрактный), и вы не реализуете абстрактные методы, которые компилятор вам скажет: либо реализуйте абстрактные методы, либо объявите класс абстрактным.

Ответ 7

С учетом интерфейса:

public interface IAnything {
  int i;
  void m1();
  void m2();
  void m3();
}

Так выглядит Java на самом деле:

public interface IAnything {
  public static final int i;
  public abstract void m1();
  public abstract void m2();
  public abstract void m3();
}

Таким образом, вы можете оставить некоторые (или все) из этих методов abstract нереализованными, как и в случае классов abstract, расширяющих класс abstract.

Когда вы implement a interface, правило, что все методы interface должны быть реализованы в производном class, применяется только к конкретной реализации class (т.е. не самой abstract).

Если вы действительно планируете создать из него abstract class, тогда нет правила, в котором говорится, что вы должны implement использовать все методы interface (обратите внимание, что в таком случае обязательно объявлять полученный class как abstract)