Любопытная вещь происходит в Java, когда вы используете абстрактный класс для реализации интерфейса: некоторые из методов интерфейса могут полностью отсутствовать (т.е. нет ни абстрактного объявления, ни фактической реализации), но компилятор не жалуется.
Например, учитывая интерфейс:
public interface IAnything {
void m1();
void m2();
void m3();
}
следующий абстрактный класс легко компилируется без предупреждения или ошибки:
public abstract class AbstractThing implements IAnything {
public void m1() {}
public void m3() {}
}
Вы можете объяснить почему?
java
interface
abstract-class
Джулио Пьянкастелли
источник
источник
:w
одного файла.Ответы:
Это потому, что если класс абстрактный, то по определению вам необходимо создать его подклассы для создания экземпляра. Подклассы потребуются (компилятором) для реализации любых методов интерфейса, которые не учитывает абстрактный класс.
Следуя вашему примеру кода, попробуйте создать подкласс
AbstractThing
без реализацииm2
метода и посмотрите, какие ошибки выдает компилятор. Это заставит вас реализовать этот метод.источник
Прекрасно.
Вы не можете создавать экземпляры абстрактных классов .. но абстрактные классы могут использоваться для размещения общих реализаций для m1 () и m3 ().
Итак, если реализация m2 () отличается для каждой реализации, а m1 и m3 - нет. Вы можете создавать разные конкретные реализации IAnything с помощью другой реализации m2 и унаследовать от AbstractThing - соблюдая принцип DRY. Проверять, полностью ли реализован интерфейс для абстрактного класса, бесполезно.
Обновление : что интересно, я обнаружил, что C # применяет это как ошибку компиляции. В этом сценарии вы вынуждены копировать сигнатуры методов и ставить перед ними префикс «abstract public» в абстрактном базовом классе .. (что-то новое каждый день :)
источник
Это хорошо. Чтобы понять вышесказанное, вы должны сначала понять природу абстрактных классов. В этом отношении они похожи на интерфейсы. Вот что Oracle говорит об этом здесь .
Итак, вы должны думать о том, что происходит, когда интерфейс расширяет другой интерфейс. Например ...
... как видите, это тоже прекрасно компилируется. Просто потому, что, как и в случае с абстрактным классом, нельзя создать экземпляр интерфейса. Таким образом, не требуется явного упоминания методов своего «родителя». Однако ВСЕ сигнатуры родительских методов НЕявно становятся частью расширяемого интерфейса или реализации абстрактного класса. Итак, как только правильный класс (тот, который может быть создан) расширяет вышеуказанное, он БУДЕТ необходим для обеспечения реализации каждого отдельного абстрактного метода.
Надеюсь, что это поможет ... и Аллаху алам!
источник
Интерфейс означает класс, у которого нет реализации своего метода, но есть только объявление.
С другой стороны, абстрактный класс - это класс, который может иметь реализацию некоторого метода вместе с некоторым методом с простым объявлением, без реализации.
Когда мы реализуем интерфейс для абстрактного класса, это означает, что абстрактный класс унаследовал все методы интерфейса. Поскольку не важно реализовывать весь метод в абстрактном классе, но это касается абстрактного класса (тоже по наследству), поэтому абстрактный класс может оставить здесь часть метода в интерфейсе без реализации. Но когда этот абстрактный класс будет унаследован каким-то конкретным классом, они должны будут реализовать все эти нереализованные методы в абстрактном классе.
источник
Учитывая интерфейс:
Вот как это на самом деле видит Java:
Таким образом, вы можете оставить некоторые (или все) из этих
abstract
методов нереализованными, как и в случаеabstract
классов, расширяющих другойabstract
класс.Когда вы
implement
используетеinterface
, правило о том, что всеinterface
методы должны быть реализованы в производномclass
, применяется только к конкретнойclass
реализации (т. Е. Котораяabstract
сама по себе не является).Если вы действительно планируете создать
abstract class
из него, то нет правила, которое говорит, что вы коimplement
всемinterface
методам (обратите внимание, что в таком случае обязательно объявить производныйclass
какabstract
)источник
javap IAnything.class
для создания второго фрагмента кода.Ссылка: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
источник
Абстрактные классы не требуются для реализации методов. Таким образом, даже если он реализует интерфейс, абстрактные методы интерфейса могут оставаться абстрактными. Если вы попытаетесь реализовать интерфейс в конкретном классе (т.е. не абстрактном) и не реализуете абстрактные методы, компилятор сообщит вам: либо реализуйте абстрактные методы, либо объявите класс как абстрактный.
источник