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

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

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

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

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

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

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

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

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

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

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

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

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

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

 //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); } 

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

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

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

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

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

 abstract class X implements Y { // implements all but one method of Y } 
 class XX extends X { // implements the remaining method in Y } 

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

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

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

Учитывая интерфейс:

 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 classов, расширяющих еще один abstract class.

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

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

  • Почему мы используем интерфейс? Это только для стандартизации?
  • Найти Java-classы, реализующие интерфейс
  • Когда нужно использовать интерфейсы?
  • Как узнать, когда создавать интерфейс?
  • Может ли метод интерфейса иметь тело?
  • Как один интерфейс может использоваться для различных фоновых задач андроида?
  • интерфейс как параметр метода в Java
  • Есть ли готовый календарь для iPhone приложений?
  • Интерфейсы C #. Неявная реализация по сравнению с явной реализацией
  • Как написать тесты junit для интерфейсов?
  • Что такое интерфейс в Java?
  • Давайте будем гением компьютера.