О чем речь? Абстрактный класс – инструмент абстрагирования, то есть на его основе нельзя создать новый объект. Используют для объединения свойств и методов. Чтобы не повторять код несколько раз, его выносят в отдельный класс, который дублируют.
На что обратить внимание? Существуют еще абстрактные методы, которые похожи на классы, но обладают своей спецификой. В программировании действуют правила, в которых указано, когда и что использовать уместней.
В статье рассказывается:
- Что такое абстрактные классы и методы
- Примеры абстрактных классов и методов
- Различия между абстрактными и конкретными классами
- Когда использовать абстрактные классы
- Правила и ограничения при работе с абстрактными методами
- 5 советов по эффективному использованию абстрактных классов и методов
- Часто задаваемые вопросы об абстрактных классах
-
Пройди тест и узнай, какая сфера тебе подходит:
айти, дизайн или маркетинг.Бесплатно от Geekbrains
Что такое абстрактные классы и методы
Процесс, когда показываются только самые важные моменты реализации, а мелкие детали скрываются, называется абстрагированием. Это помогает сконцентрировать внимание на конечном результате, а не процессе.
В программировании на Java абстрактные методы и классы – это самые важные инструменты для создания и реализации таких отвлеченностей. Они похожи на чертежи, которые описывают поведение субклассов и служат образцами для их создания. Если вы только начинаете работать в Java или хотите вспомнить материал об отличиях абстрактных классов или интерфейсов, то вам подойдёт руководство Difference Between Interface and Abstract class in Java.
Примеры абстрактных классов и методов
Абстрактность класса упоминается при описании его самого. Это значит, что перед командой class должен следовать оператор abstract.
входят в ТОП-30 с доходом
от 210 000 ₽/мес
Скачивайте и используйте уже сегодня:
Топ-30 самых востребованных и высокооплачиваемых профессий 2023
Поможет разобраться в актуальной ситуации на рынке труда
Подборка 50+ бесплатных нейросетей для упрощения работы и увеличения заработка
Только проверенные нейросети с доступом из России и свободным использованием
ТОП-100 площадок для поиска работы от GeekBrains
Список проверенных ресурсов реальных вакансий с доходом от 210 000 ₽
Например, это может выглядеть так:
1
2 3 4 5 |
public abstract class GraphicObject {
// объявление полей // объявление не абстрактных методов abstract void draw(); } |
Следующий код выдаст ошибку компиляции:
1 | GraphicObject object = new GraphicObject(); |
А вот пример класса, наследующего от абстрактного класса:
1
2 3 4 5 |
public class Circle extends GraphicObject {
void draw() { System.out.println(“Нарисовали круг.”); } } |
Абстрактный метод Java – это: не реализован, но объявлен, а логика не описана вообще. В этом случае не пишутся фигурные скобки, а после объявления метода сразу идёт точка с запятой. К примеру, так:
1 | abstract void moveTo(double deltaX, double deltaY); |
Тем не менее, отвлеченные методы абстрактный класс содержит далеко не всегда. Однако в случае их использования они должны быть объявлены и должны быть абстрактными. Следующий код выдаст ошибку компиляции:
1
2 3 |
public class GraphicObject {
abstract void draw(); } |
В случае, когда класс наследуется от абстрактного, то нужно добавить описание всех отвлеченных методов родительского класса. Если же некоторые из его таких методов не реализованы, то наследный класс тоже будет абстрактным.
Читайте также!
Методы интерфейсов, не объявленные статистическими или не являющиеся таковыми по умолчанию (оператор static и default соответственно), тоже являются отвлеченными. Но у методов интерфейса обычно не пишут abstract, чтобы нужно было делать меньше кода. Получается, что они абстрактные, но показывается это не явно. Тем не менее, добавить abstract можно, и это не вызовет ошибки компиляции.
Различия между абстрактными и конкретными классами
Для первых невозможно создать экземпляры (для конкретных классов – можно). Расширение других классов, реализация отвлеченных методов и последующее наследование – это основное предназначение абстрактных классов.
Также у конкретных моделей нет конструкторов, а у абстрактных они могут быть – при условии, что их вызывают из субклассов напрямую. Более того, конструктор последнего должен вызывать конструктор соответствующего суперкласса.
Когда использовать абстрактные классы
Например, если нужно создать и определить общий интерфейс и поведение, которое будет использоваться несколькими классами одновременно. Рассмотрим на конкретном примере. Допустим, вы создаёте игру, в которой участвуют разнообразные геометрические фигуры: круги, квадраты, треугольники. У них всех есть как общие параметры (периметр и площадь), так и уникальные (радиус, длины диагоналей, количество сторон). Для представления этих фигур в игре можно использовать абстрактный класс Shape, определяющий общее для всех фигур поведение. Получится так:
publicabstractclassShape {
protectedint x, y;
publicShape(int x, int y) {
this.x = x;
this.y = y;
}
publicabstractdoublegetArea();
publicabstractdoublegetPerimeter();
}
Здесь Shape содержит переменные для координат х и у каждой фигуры и абстрактные методы для вычисления площади и периметра. Благодаря тому, что они отвлеченные, каждый конкретный субкласс может реализовать их по-своему.
К примеру, мы можем создать субкласс Circle, который расширяет основной класс и реализует свои версии методов getArea() и getPerimeter():
publicclassCircleextendsShape {
privatedouble radius;
publicCircle(int x, int y, double radius) {
super(x, y);
this.radius = radius;
}
publicdoublegetArea() {
return Math.PI * radius * radius;
}
publicdoublegetPerimeter() {
return 2 * Math.PI * radius;
}
}
Правила и ограничения при работе с абстрактными методами
Стоит знать, что есть несколько правил, ограничивающих работу с абстрактными методами в Java:
- абстрактный метод нельзя объявить как final или private;
- он обязательно должен быть объявлен внутри отвлеченного класса;
- конкретный субкласс, который расширяет абстрактный класс, должен предоставлять реализацию для всех его унаследованных отвлеченных методов.
на обучение «Python-разработчик» до 29 декабря
Абстрактные методы и абстрактные классы часто используются вместе – это даёт возможность создать общий интерфейс для группы взаимосвязанных классов.
Продолжим разбираться в этом с помощью нашей игры с фигурами и выясним, как можно использовать абстрактные методы для определения общего интерфейса, вычисляющего периметр и площадь фигур. Итак, у нас уже есть абстрактный класс Shape, в котором содержатся отвлеченные методы для определения нужных нам параметров фигур:
publicabstractclassShape {
protectedint x, y;
publicShape(int x, int y) {
this.x = x;
this.y = y;
}
publicabstractdoublegetArea();
publicabstractdoublegetPerimeter();
}
Для создания уже конкретного субкласса Shape нужно реализовать такие абстрактные методы:
publicclassCircleextendsShape {
privatedouble radius;
publicCircle(int x, int y, double radius) {
super(x, y);
this.radius = radius;
}
publicdoublegetArea() {
return Math.PI * radius * radius;
}
publicdoublegetPerimeter() {
return 2 * Math.PI * radius;
}
}
Здесь класс класс Circle реализует методы getArea() и getPerimeter() по собственным формулам для определения параметров фигуры (периметра окружности и площади круга). По тому же принципу можно было поработать и с субклассами Square и Triangle, которые реализовали бы свои версии методов getArea() и getPerimeter().
Так, с использованием абстрактных методов и классов одновременно, мы можем предоставить общий интерфейс для вычисления параметров фигур, но каждый субкласс при этом будет решать поставленную задачу и реализовывать эти методы по-своему.
5 советов по эффективному использованию абстрактных классов и методов
Существует несколько наиболее удобных способов работы с абстрактными методами в Java, которые стоит помнить. Ниже приведены несколько таких практик, которые упростят действия с данными инструментами:
- Применяйте абстрактные классы, если нужно создать несколько взаимосвязанных с общими функциями. Так сможете избежать дублирования и облегчить работу с кодом, его поддержку.
- Если нужно определить единое поведение, как было сказано ранее, абстрактные классы прекрасно подойдут в качестве основного инструмента для работы. Каждый субкласс в вашем коде будет уникально реализовывать это общее функционирование, сохраняя суть.
- Абстрактные классы нужно использовать в меру, только тогда, когда есть явная причина. Иначе код вместо облегчения, наоборот, усложнится, его будет сложнее поддерживать.
- Следуйте правилам наименования. Абстрактные методы зовут глаголами (например, «draw», а такие же классы – отвлеченными существительными (как в случае с нашей игрой «Shape»).
- Документирование чрезвычайно важно для слаженной и четкой работы с кодом. Важно оставлять комментарии к нему, пояснять смысл методов, классов и прочих элементов. Так с вашим кодом смогут работать и другие.
Благодаря нашим практикам, используя метод абстрагирования вы сможете создать идеальный понятный код, который удобно поддерживать.
Часто задаваемые вопросы об абстрактных классах
У абстрактных классов могут быть конструкторы?
Да, но их обычно вызывают конструкторами субклассов: их нельзя инстанцировать напрямую.
С помощью абстрактных классов можно реализовывать интерфейсы?
Да, как и с помощью всех иных. Именно абстрактные пригодятся, если вы хотите предоставить общее поведение для нескольких классов и реализовать один интерфейс.
Абстрактные классы бывают финальными?
Не бывают: от этого теряется смысл их использования. Они нужны, чтобы их расширяли субклассы, а у финального класса такое расширение невозможно.
Читайте также!
Когда нужно использовать абстрактные классы вместо интерфейсов?
Повторимся: абстрактные классы нужны для предоставления общего функционала для нескольких классов в одной иерархии. Интерфейсы же подойдут, если каждый класс будет реализовать методы независимо. Исходя из этого, мы понимаем следующее: абстрактные классы следует использовать, когда нужна общая реализация иерархически объединенных. А интерфейсы подойдут для разрозненных.
Вывод: абстрактные классы и методы – это очень мощные инструменты, которыми действительно стоит научиться пользоваться. С их помощью вы сможете создать модульный и понятный код, который смогут понять и оценить другие разработчики. При создании группы взаимосвязанных классов с общими функциями стоит обратиться именно к этим инструментам.
Норм, спасибо. Стало понятнее.