0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#статьи</a></p>
1
<p><a>#статьи</a></p>
2
<ul><li>21 мар 2022</li>
2
<ul><li>21 мар 2022</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><p>Смотрим на примерах, что такое абстрактный класс, когда лучше использовать интерфейсы и что такое абстрактные методы.</p>
4
</ul><p>Смотрим на примерах, что такое абстрактный класс, когда лучше использовать интерфейсы и что такое абстрактные методы.</p>
5
<p>Иллюстрация: Dana Moskvina / Skillbox Media</p>
5
<p>Иллюстрация: Dana Moskvina / Skillbox Media</p>
6
<p>Пишет на Java. Верит в Agile. Пьёт много кофе и не любит грязный код.</p>
6
<p>Пишет на Java. Верит в Agile. Пьёт много кофе и не любит грязный код.</p>
7
<p>Абстрактный класс - это<a>класс</a>, который содержит методы без реализации. Но зачем он такой нужен? Давайте разбираться.</p>
7
<p>Абстрактный класс - это<a>класс</a>, который содержит методы без реализации. Но зачем он такой нужен? Давайте разбираться.</p>
8
<p>Представим, что нам нужно описать несколько животных - и у каждого будет свой класс. Мы соберём их характеристики, опишем в полях и методах. У некоторых животных характеристики будут совпадать - например, и у гепарда, и у коня 4 ноги. А у некоторых - не совпадут: кролик ест траву, а тигр - других животных.</p>
8
<p>Представим, что нам нужно описать несколько животных - и у каждого будет свой класс. Мы соберём их характеристики, опишем в полях и методах. У некоторых животных характеристики будут совпадать - например, и у гепарда, и у коня 4 ноги. А у некоторых - не совпадут: кролик ест траву, а тигр - других животных.</p>
9
<p>Однако, несмотря на несовпадение, мы можем выделить шаблонные характеристики: количество лап, издаваемый звук, приём пищи, передвижение. Эти шаблонные характеристики мы можем собрать в одном месте - абстрактном классе "Животное" и указать компилятору, что наполним их конкретными данными и поведением позже - в классах отдельных животных или групп животных.</p>
9
<p>Однако, несмотря на несовпадение, мы можем выделить шаблонные характеристики: количество лап, издаваемый звук, приём пищи, передвижение. Эти шаблонные характеристики мы можем собрать в одном месте - абстрактном классе "Животное" и указать компилятору, что наполним их конкретными данными и поведением позже - в классах отдельных животных или групп животных.</p>
10
<p>Так на практике реализуется абстракция - процесс выделения наиболее важных характеристик объекта и информации об объекте. То есть мы обобщаем основную информацию о свойствах разных предметов или объектов и оставляем только самое важное, а менее важным пренебрегаем.</p>
10
<p>Так на практике реализуется абстракция - процесс выделения наиболее важных характеристик объекта и информации об объекте. То есть мы обобщаем основную информацию о свойствах разных предметов или объектов и оставляем только самое важное, а менее важным пренебрегаем.</p>
11
<p>При этом абстрактным объект класса "Животное" создать нельзя - ведь в природе "просто животного" не существует, есть только волки, лисы, бегемоты и прочие слоны.</p>
11
<p>При этом абстрактным объект класса "Животное" создать нельзя - ведь в природе "просто животного" не существует, есть только волки, лисы, бегемоты и прочие слоны.</p>
12
<p>Простыми словами о том, что такое абстракция, рассказали <a>в одной из статей</a>большого руководства по объектно-ориентированному программированию. Там вы найдете множество примеров использования абстрактных классов и интерфейсов.</p>
12
<p>Простыми словами о том, что такое абстракция, рассказали <a>в одной из статей</a>большого руководства по объектно-ориентированному программированию. Там вы найдете множество примеров использования абстрактных классов и интерфейсов.</p>
13
<p>Давайте рассмотрим пример абстрактного класса в Java.</p>
13
<p>Давайте рассмотрим пример абстрактного класса в Java.</p>
14
public abstract class Animal { Integer countOfLegs; Double weight; String color; public abstract void run(); public void eat() { System.out.println("Animal says nyam-nyam"); } }<p>Как вы видите, абстрактный класс очень похож на обычный класс. Чтобы сделать класс абстрактным, нам нужно добавить ключевое слово abstract в описание класса и в методы, которые мы хотим оставить абстрактными, - то есть определить уже в конкретных классах (медведь, лиса, лягушка).</p>
14
public abstract class Animal { Integer countOfLegs; Double weight; String color; public abstract void run(); public void eat() { System.out.println("Animal says nyam-nyam"); } }<p>Как вы видите, абстрактный класс очень похож на обычный класс. Чтобы сделать класс абстрактным, нам нужно добавить ключевое слово abstract в описание класса и в методы, которые мы хотим оставить абстрактными, - то есть определить уже в конкретных классах (медведь, лиса, лягушка).</p>
15
<p>В абстрактном классе мы можем описать некоторые поля, которые будут отражать определённые свойства объекта или добавить обычный метод с реализацией по умолчанию.</p>
15
<p>В абстрактном классе мы можем описать некоторые поля, которые будут отражать определённые свойства объекта или добавить обычный метод с реализацией по умолчанию.</p>
16
<p>Именно так мы и сделали в примере выше: добавили переменные для веса, цвета и количества ног у животного, а также описали два метода: run ("бежать") и eat ("кушать"). В нашем случае метод run - абстрактный, а у метода eat есть реализация по умолчанию. Это значит, что в классах, которые наследуют от Animal, мы обязаны добавить определение метода run, а переопределять или нет метод eat, зависит от наших задач и желания.</p>
16
<p>Именно так мы и сделали в примере выше: добавили переменные для веса, цвета и количества ног у животного, а также описали два метода: run ("бежать") и eat ("кушать"). В нашем случае метод run - абстрактный, а у метода eat есть реализация по умолчанию. Это значит, что в классах, которые наследуют от Animal, мы обязаны добавить определение метода run, а переопределять или нет метод eat, зависит от наших задач и желания.</p>
17
<p>Теперь давайте попробуем создать класс на основе абстрактного класса. Пусть это будет класс, описывающий собаку.</p>
17
<p>Теперь давайте попробуем создать класс на основе абстрактного класса. Пусть это будет класс, описывающий собаку.</p>
18
public class Dog extends Animal { @Override public void run() { System.out.println("Dog says gaf-gaf"); } }<p>Здесь extends Animal означает, что мы наследуем класс Animal. Как только мы создадим пустой класс Dog, компилятор сразу подсветит его красным и выведет такое сообщение:</p>
18
public class Dog extends Animal { @Override public void run() { System.out.println("Dog says gaf-gaf"); } }<p>Здесь extends Animal означает, что мы наследуем класс Animal. Как только мы создадим пустой класс Dog, компилятор сразу подсветит его красным и выведет такое сообщение:</p>
19
<p><strong>Error: (3, 8) java: com.company.Dog is not abstract and does not override abstract method run () in com.company.Animal</strong></p>
19
<p><strong>Error: (3, 8) java: com.company.Dog is not abstract and does not override abstract method run () in com.company.Animal</strong></p>
20
<p>Это значит, что мы обязаны переопределить метод run() - что мы и сделали с помощью аннотации @Override.</p>
20
<p>Это значит, что мы обязаны переопределить метод run() - что мы и сделали с помощью аннотации @Override.</p>
21
<p>Теперь давайте создадим объект класса Dog. Как мы видим, после его создания нам доступны все переменные и методы из класса Animal. Попробуем вызвать eat и run.</p>
21
<p>Теперь давайте создадим объект класса Dog. Как мы видим, после его создания нам доступны все переменные и методы из класса Animal. Попробуем вызвать eat и run.</p>
22
public static void main(String[] args) { Dog scooby = new Dog(); scooby.eat(); scooby.run(); }<p>Вот что мы увидим в консоли:</p>
22
public static void main(String[] args) { Dog scooby = new Dog(); scooby.eat(); scooby.run(); }<p>Вот что мы увидим в консоли:</p>
23
<p><strong>Animal says nyam-nyam</strong></p>
23
<p><strong>Animal says nyam-nyam</strong></p>
24
<p><strong>Dog says gaf-gaf</strong></p>
24
<p><strong>Dog says gaf-gaf</strong></p>
25
<p>Итак, давайте выделим важные моменты:</p>
25
<p>Итак, давайте выделим важные моменты:</p>
26
<ul><li>Мы не можем создавать объекты абстрактных классов - но в этом и нет смысла.</li>
26
<ul><li>Мы не можем создавать объекты абстрактных классов - но в этом и нет смысла.</li>
27
<li>В абстрактный класс можно добавлять методы с реализацией по умолчанию.</li>
27
<li>В абстрактный класс можно добавлять методы с реализацией по умолчанию.</li>
28
<li>Если мы наследуемся от абстрактного класса, то мы обязаны переопределить все абстрактные методы родительского класса (кроме тех, которые имеют реализацию по умолчанию) или сделать весь дочерний класс абстрактным.</li>
28
<li>Если мы наследуемся от абстрактного класса, то мы обязаны переопределить все абстрактные методы родительского класса (кроме тех, которые имеют реализацию по умолчанию) или сделать весь дочерний класс абстрактным.</li>
29
<li>Абстрактные методы не имеют тела.</li>
29
<li>Абстрактные методы не имеют тела.</li>
30
</ul><p>На собеседованиях часто задают вопрос, чем отличаются абстрактные классы и интерфейсы. Вот их основные отличия:</p>
30
</ul><p>На собеседованиях часто задают вопрос, чем отличаются абстрактные классы и интерфейсы. Вот их основные отличия:</p>
31
<ul><li>Интерфейсы описывают только часть функциональности объекта - определённые признаки. Абстрактный класс же может описывать целую категорию разных объектов, а его характеристики имеют право наследовать только те объекты, которые являются частью этой категории. Например, собаки и волки - часть общей категории "Животные", а интерфейс, описывающий умение бегать, может реализовать и человек, и робот, и собака.</li>
31
<ul><li>Интерфейсы описывают только часть функциональности объекта - определённые признаки. Абстрактный класс же может описывать целую категорию разных объектов, а его характеристики имеют право наследовать только те объекты, которые являются частью этой категории. Например, собаки и волки - часть общей категории "Животные", а интерфейс, описывающий умение бегать, может реализовать и человек, и робот, и собака.</li>
32
<li>Интерфейс описывает только поведение (методы), и у него нет полей. Точнее, есть возможность их объявить, но они будут public static final. В то же время абстрактный класс может содержать классические поля, которые будут принадлежать разным объектам.</li>
32
<li>Интерфейс описывает только поведение (методы), и у него нет полей. Точнее, есть возможность их объявить, но они будут public static final. В то же время абстрактный класс может содержать классические поля, которые будут принадлежать разным объектам.</li>
33
<li>Наследник абстрактного класса обязан наследовать все его составляющие, а интерфейс создан только для реализации (имплементирования). Поэтому в Java мы можем наследовать класс только от одного класса, а на реализацию интерфейсов внутри одного класса ограничений нет.</li>
33
<li>Наследник абстрактного класса обязан наследовать все его составляющие, а интерфейс создан только для реализации (имплементирования). Поэтому в Java мы можем наследовать класс только от одного класса, а на реализацию интерфейсов внутри одного класса ограничений нет.</li>
34
</ul><p>Интерфейсы и абстрактные классы - это разные инструменты, разработанные для разных целей, хотя у них и есть общие черты.</p>
34
</ul><p>Интерфейсы и абстрактные классы - это разные инструменты, разработанные для разных целей, хотя у них и есть общие черты.</p>
35
<p>Когда лучше использовать абстрактные классы:</p>
35
<p>Когда лучше использовать абстрактные классы:</p>
36
<ul><li>Вы хотите избежать дублирования кода, реализуя несколько тесно связанных классов из одной семантической категории.</li>
36
<ul><li>Вы хотите избежать дублирования кода, реализуя несколько тесно связанных классов из одной семантической категории.</li>
37
<li>Классы, которые будут расширять ваш абстрактный класс, имеют много общих свойств и будут реализовывать много похожих методов.</li>
37
<li>Классы, которые будут расширять ваш абстрактный класс, имеют много общих свойств и будут реализовывать много похожих методов.</li>
38
<li>Наследуемый класс используется в отношении IS-A - то есть класс-наследник только расширяет функциональность абстрактного класса.</li>
38
<li>Наследуемый класс используется в отношении IS-A - то есть класс-наследник только расширяет функциональность абстрактного класса.</li>
39
<li>Проект уже частично написан, а вы знаете, что выбранные классы будут часто меняться и дополняться новыми методами и полями. То есть поддерживать абстрактный класс и дополнять его намного проще, чем проектировать интерфейс и добавлять его новые методы во все места в коде, где они должны реализовываться.</li>
39
<li>Проект уже частично написан, а вы знаете, что выбранные классы будут часто меняться и дополняться новыми методами и полями. То есть поддерживать абстрактный класс и дополнять его намного проще, чем проектировать интерфейс и добавлять его новые методы во все места в коде, где они должны реализовываться.</li>
40
</ul><p>Когда лучше использовать интерфейсы:</p>
40
</ul><p>Когда лучше использовать интерфейсы:</p>
41
<ul><li>Вам нужно описать определённую логику, которую должны поддерживать не связанные между собой объекты.</li>
41
<ul><li>Вам нужно описать определённую логику, которую должны поддерживать не связанные между собой объекты.</li>
42
<li>Вам нужно привести к одному типу группу объектов и гарантировать схожую функциональность.</li>
42
<li>Вам нужно привести к одному типу группу объектов и гарантировать схожую функциональность.</li>
43
<li>Вам необходимо добавить какой-то маркер, который будет говорить о том, что выбранные классы поддерживают определённую логику.</li>
43
<li>Вам необходимо добавить какой-то маркер, который будет говорить о том, что выбранные классы поддерживают определённую логику.</li>
44
<li>Вы хотите использовать множественное наследование типа.</li>
44
<li>Вы хотите использовать множественное наследование типа.</li>
45
</ul><p>Это лишь базовые и самые распространённые ситуации. Решая конкретные задачи, лучше советоваться с более опытными разработчиками или принимать самостоятельное решение.</p>
45
</ul><p>Это лишь базовые и самые распространённые ситуации. Решая конкретные задачи, лучше советоваться с более опытными разработчиками или принимать самостоятельное решение.</p>
46
<p>В этой статье мы с вами познакомились с понятием абстрактного класса, разобрались, для чего используются абстрактные классы, научились реализовывать их и проанализировали, в каких ситуациях лучше использовать интерфейсы, а в каких - абстрактные классы.</p>
46
<p>В этой статье мы с вами познакомились с понятием абстрактного класса, разобрались, для чего используются абстрактные классы, научились реализовывать их и проанализировали, в каких ситуациях лучше использовать интерфейсы, а в каких - абстрактные классы.</p>
47
<a>Научитесь: Профессия Java-разработчик + ИИ Узнать больше</a>
47
<a>Научитесь: Профессия Java-разработчик + ИИ Узнать больше</a>