Абстракция — одна из отличительных черт объектно-ориентированного программирования. В Java абстракция ООП может быть реализована в двух формах: интерфейсы и абстрактные классы. У них слишком много общего и слишком много различий. Многие люди думают, что их можно использовать взаимозаменяемо, когда они впервые изучают, но это не так. Сегодня мы узнаем об интерфейсах и абстрактных классах в Java.
Абстрактный класс
Прежде чем понять абстрактные классы, сначала посмотрите на абстрактные методы. Абстрактный метод — это особый метод: это только утверждение, но не реализация. Абстрактный метод формата оператора выглядит следующим образом:
abstract void fun();
Абстрактные методы должны быть украшены ключевым словом abstract. Если класс содержит абстрактные методы, этот класс называется абстрактным классом, и абстрактный класс должен быть изменен с помощью ключевого слова abstract перед классом. Абстрактный класс нельзя использовать для создания объектов, поскольку абстрактный класс содержит методы, не имеющие конкретной реализации.
Следует обратить внимание на следующую проблему: в книге «JAVA Programming Thought» абстрактный класс определяется как «класс, содержащий абстрактные методы», но позже выясняется, что если класс не содержит абстрактных методов и только модифицируется с абстрактным, это также абстрактный класс. Другими словами, абстрактный класс не обязательно должен содержать абстрактные методы. Лично я считаю, что это серьезная проблема, потому что если абстрактный класс не содержит никаких абстрактных методов, то почему он должен проектироваться как абстрактный класс? Так что имейте в виду эту концепцию сейчас, не вдаваясь в почему.
[public] abstract class ClassName {
abstract void fun();
}
Отсюда видно, что абстрактные классы существуют для наследования, если вы определяете абстрактный класс, но не наследуете его, то это равносильно созданию этого абстрактного класса напрасно, потому что вы не можете использовать его ни для чего. Для родительского класса, если определенный его метод реализован в родительском классе без какого-либо смысла и должен быть реализован по-разному в соответствии с фактическими потребностями подкласса, тогда этот метод может быть объявлен как абстрактный метод. класс также становится абстрактным классом.
Класс, который содержит абстрактные методы, называется абстрактным классом, но это не означает, что абстрактный класс может иметь только абстрактные методы, как и обычные классы, он также может иметь переменные-члены и обычные методы-члены. Обратите внимание, что между абстрактными классами и обычными классами есть три основных отличия:
- Абстрактный метод должен быть общедоступным или защищенным (поскольку, если он частный, он не может быть унаследован подклассами, а подклассы не могут реализовать метод), и по умолчанию он является общедоступным.
- Абстрактный класс нельзя использовать для создания объектов;
- Если класс наследуется от абстрактного класса, подкласс должен реализовать абстрактный метод суперкласса. Если подкласс не реализует абстрактный метод суперкласса, подкласс также должен быть определен как абстрактный класс.
В остальном абстрактные классы ничем не отличаются от обычных классов.
2. Интерфейс
Интерфейс, называемый интерфейсом на английском языке, в разработке программного обеспечения интерфейс обычно относится к методу или функции, которые могут вызывать другие. Отсюда мы можем оценить исходное намерение разработчиков языка Java, которое представляет собой абстракцию поведения. В Java интерфейс определяется следующим образом:
[public] interface InterfaceName {
}
Интерфейс может содержать переменные и методы. Однако следует отметить, что переменные в интерфейсе будут неявно обозначаться как общедоступные статические конечные переменные (и могут быть только общедоступными статическими конечными переменными, об ошибке компиляции будет сообщено при закрытой модификации), а методы будут неявно обозначаться как общедоступные абстрактные методы И это может быть только общедоступный абстрактный метод (модифицированный другими ключевыми словами, такими как private, protected, static, final и т. д., будет сообщено об ошибке компиляции), и все методы в интерфейсе не могут иметь конкретных реализаций, которые то есть методы в интерфейсе должны быть абстрактными методами. Отсюда вы можете смутно увидеть разницу между интерфейсом и абстрактным классом.Интерфейс — это чрезвычайно абстрактный тип, который является более «абстрактным», чем абстрактный класс, и обычно не определяет переменные в интерфейсе.
Чтобы класс соответствовал определенному набору интерфейсов, используйте ключевое слово Implements в следующем формате:
class ClassName implements Interface1,Interface2,[....]{
}
Как видно, классу разрешено соответствовать нескольким конкретным интерфейсам. Если неабстрактный класс соответствует интерфейсу, он должен реализовать все методы этого интерфейса. Для абстрактных классов, следующих за интерфейсом, абстрактные методы в интерфейсе могут быть не реализованы.
Разница между абстрактным классом и интерфейсом
1. Различия на грамматическом уровне
- Абстрактные классы могут предоставлять сведения о реализации методов-членов, в то время как в интерфейсах могут существовать только общедоступные абстрактные методы;
- Переменные-члены в абстрактных классах могут быть разных типов, в то время как переменные-члены в интерфейсах могут иметь только тип public static final;
- Интерфейсы не могут содержать статические блоки кода и статические методы, тогда как абстрактные классы могут иметь статические блоки кода и статические методы;
- Класс может наследоваться только от одного абстрактного класса, но класс может реализовывать несколько интерфейсов.
2. Отличия на уровне дизайна
1) Абстрактный класс — это абстракция вещи, то есть абстракция класса, а интерфейс — это абстракция поведения. Абстрактный класс абстрагирует весь класс, включая атрибуты и поведение, а интерфейс абстрагирует часть класса (поведение). Чтобы привести простой пример, самолеты и птицы — разные вещи, но все они имеют одну общую черту: они оба летают. Затем при проектировании вы можете спроектировать самолет как класс Самолет, а птицу спроектировать как класс Птица, но вы не можете спроектировать функцию полета как класс, поэтому это только поведенческая функция, а не абстрактное описание класса. вещей . В это время полет может быть разработан как интерфейс Fly, включая метод fly(), а затем Airplane и Bird соответственно реализуют интерфейс Fly в соответствии со своими потребностями. Кроме того, существуют различные типы самолетов, такие как истребители, гражданские самолеты и т. д., которые могут напрямую наследовать класс Airplane. Отсюда видно, что наследование — это отношение «есть или нет», тогда как реализация интерфейса — это отношение «есть или нет». Если класс наследует абстрактный класс, подкласс должен быть типом абстрактного класса, а реализация интерфейса зависит от того, есть ли у него отношения, например, может ли птица летать (или есть ли у нее функция полета), можете летать Вы можете реализовать этот интерфейс, но если вы не умеете летать, вы не можете реализовать этот интерфейс.
2) Уровень дизайна другой.Как родительский класс многих подклассов, абстрактный класс является шаблонным дизайном. Интерфейс — это кодекс поведения, это радиальный дизайн. Что такое шаблонный дизайн? Самый простой пример, все использовали шаблоны в ppt.Если шаблон A используется для разработки ppt B и ppt C, общей частью ppt B и ppt C является шаблон A. Если их общие части необходимо изменить, нужно только Шаблон A в порядке, нет необходимости повторно изменять ppt B и ppt C. В радиальной конструкции, например, лифт оборудован какой-либо сигнализацией, и после того, как сигналы тревоги должны быть обновлены, они должны быть обновлены. То есть для абстрактного класса, если вам нужно добавить новый метод, вы можете напрямую добавить конкретную реализацию в абстрактный класс, и подкласс не может ее изменить; но не для интерфейса, если интерфейс изменен , все реализации этого класса интерфейса должны быть соответствующим образом изменены.
Давайте посмотрим на один из самых распространенных примеров в Интернете: пример двери и тревоги: у двери есть два действия, open() и close(). На данный момент мы можем определить это абстрактное понятие через абстрактные классы. и интерфейсы:
abstract class Door {
public abstract void open();
public abstract void close();
}
или:
interface Door {
public abstract void open();
public abstract void close();
}
Но теперь, если нам нужно, чтобы дверь имела функцию alarm(), как это сделать? Вот две идеи:
1) Поместите эти три функции в абстрактный класс, но таким образом все подклассы, которые унаследованы от этого абстрактного класса, имеют функцию будильника, но некоторые двери не обязательно имеют функцию будильника;
2) Поместите эти три функции в интерфейс. Класс, который должен использовать функцию будильника, должен реализовать в этом интерфейсе функции open() и close(). Возможно, этот класс не имеет функций open() и close() на все Две функции, например, пожарная сигнализация.
Из этого видно, что функции open(), close() и alarm() в Door относятся к поведению двух разных категорий: open() и close() относятся к внутренним поведенческим характеристикам самой двери, а alarm( ) относится к расширенному дополнительному поведению. Таким образом, лучшее решение — спроектировать будильник как интерфейс, включая поведение alarm(), и спроектировать Door как отдельный абстрактный класс, включая два поведения открытия и закрытия. Создайте еще одну тревожную дверь, чтобы она наследовала класс Door и реализовывала интерфейс Alarm.
interface Alram {
void alarm();
}
abstract class Door {
void open();
void close();
}
class AlarmDoor extends Door implements Alarm {
void oepn() {
//....
}
void close() {
//....
}
void alarm() {
//....
}
}
Наконец, таблица используется для обобщения различий между абстрактными классами и интерфейсами:
параметр | абстрактный класс | интерфейс |
Реализация метода по умолчанию | Он может иметь реализацию метода по умолчанию | Интерфейсы полностью абстрактны. у него вообще нет реализации метода |
выполнить | Использование подклассовextendsключевое слово для наследования абстрактных классов. Если подкласс не является абстрактным классом, он должен предоставить реализации всех методов, объявленных в абстрактном классе. | Подклассы используют ключевые словаimplementsреализовать интерфейс. Он должен обеспечить реализацию всех объявленных методов в интерфейсе. |
Конструктор | Абстрактные классы могут иметь конструкторы | Интерфейс не может иметь конструктор |
Отличия от обычных классов Java | Он ничем не отличается от обычного класса Java, за исключением того, что вы не можете создать экземпляр абстрактного класса. | Интерфейсы бывают совершенно разных типов |
модификатор доступа | Абстрактные методы могут иметьpublic,protectedиdefaultэти модификаторы | Модификатор по умолчанию для методов интерфейса:public. Вы не можете использовать другие модификаторы. |
основной метод | Абстрактный метод может иметь основной метод, и мы можем его запустить | В интерфейсе нет основного метода, поэтому мы не можем его запустить. |
множественное наследование | Абстрактные методы могут наследоваться от класса и реализовывать несколько интерфейсов. | Интерфейс может наследоваться только от одного или нескольких других интерфейсов. |
скорость | это быстрее, чем интерфейс | Интерфейс немного медленнее, потому что требуется время, чтобы найти методы для реализации в классе. |
добавить новый метод | Если вы добавляете новые методы в абстрактный класс, вы можете предоставить ему реализации по умолчанию. Таким образом, вам не нужно менять текущий код. | Если вы добавляете методы к интерфейсу, вы должны изменить класс, реализующий интерфейс. |