Абстрактный класс в Java
Данная статья:
- написана командой Vertex Academy.
- это одна из статей из нашего "Самоучителя по Java"
Привет! Это статья про абстрактный класс в Java, а также об абстрактных методах. Это не самая простая тема, потому что она, ну... слегка абстрактная 🙂 Поэтому читайте внимательно!
Что такое абстрактный класс
Вы наверняка уже знакомы с понятием класса. Если нет, почитайте эту статью:
Так вот, классы.
Обычно мы создаем классы для того, чтобы пользоваться их объектами. Например, мы создаем объекты типа String, или Scanner, или FileWriter для дальнейшей работы.
Тем не менее, объекты классов нам нужны не всегда. Иногда нам просто нужен суперкласс (т.е. класс, который мы будем наследовать), в котором будут задаваться какие-то общие для наследников методы и характеристики.
Представим, что у нас есть три типа животных:
1. Cобака (класс Dog)
2. Кошка (класс Cat)
3. Корова (класс Cow)
Все это животные - и поэтому мы можем создать один общий для всех суперкласс Animal, в котором разом задаем общие методы для всех трех подклассов.
Тем не менее, можно сказать что объект именно класса Animal нам не пригодится - более того, логически его не может существовать. Ведь существует животное кошка, животное собака - но животное "животное" не существует.
Или, например, представим что Вы пишете игру, где есть разные навыки и оружие.
По навыкам, допустим, Ваш персонаж может:
1. Красться
2. Бежать
3. Делать двойне сальто
Это все навыки: навык "красться", навык "бежать". Но навыка "навык" не существует. Верно?
По оружию, допустим, в игре есть такие опции:
1. Кинжал
2. Арбалет
3. Двуручный меч
И кинжал, и арбалет, и меч - это оружие. Но оружия "оружие" не существует. Верно?
Я думаю Вы поняли 🙂 Так вот, именно такой класс - т.е. класс "без объектов"- и называется абстрактным.
Как выглядит абстрактный класс
Создать абстрактный класс очень просто. Просто перед словом "class" нужно дописать "abstract":
Давайте посмотрим на примере. Создадим класс MyClass (пока без "abstract"):
1 2 3 |
class MyClass { } |
и попробуем создать его объект:
1 2 3 4 5 6 7 |
public class Test { public static void main(String[] args) { MyClass object = new MyClass(); } } |
Если Вы напишите такой код, никаких ошибок не возникнет. Теперь допишем перед MyClass модификатор "abstract":
1 2 3 |
abstract class MyClass { } |
Теперь в том же самом методе main мы получим ошибку:
Как видите, нам говорят, что класс MyClass абстрактный, и мы не можем создавать его объекты.
Абстрактные классы и абстрактные методы
Но что может находиться в абстрактном классе? В абстрактном классе могут лежать:
- "обычные" методы
- абстрактные методы
Что такое абстрактные методы
Как Вы могли догадаться, абстрактные методы - это методы, перед которыми мы... дописываем слово abstract 🙂 Но это, конечно же, не все. Дело в том, что абстрактный метод коренным образом отличается от "обычного". На самом деле это и не метод вовсе - это только описание метода, без "тела".
Например:
1 2 3 |
abstract class MyClass { abstract void myMethod(); } |
Абстрактные методы мы не реализуем в абстрактном классе, поскольку абстрактный класс может и не знать, как должен работать этот метод, но каждый наследник обязан будет реализовать этот метод.
Характерно то, что абстрактные методы могут лежать только в абстрактном классе. Если убрать слово "abstract" перед классом, получим ошибку:
Зачем нужны абстрактные методы?
Как мы уже говорили, абстрактный метод не реализуется в абстрактном классе, но класс-наследник должен реализовать его. Зачем нам это? Это нужно если метод обязательно должен быть у всех наследников.
Например, каждое оружие наносит урон - без этого оно уже не оружие. Или, еще пример, каждый навык должен применяться... а животные, скажем, подавать голос 🙂 Но каждый наследник будет это делать по-своему, поэтому нам как бы и нет смысла реализовывать его в абстрактном родителе.
Давайте покажем это в коде. Представим, что у нас есть абстрактный класс Animal, в котором лежит абстрактный метод voice():
1 2 3 4 |
abstract class Animal { abstract void voice(); } |
У нас будут три наследника - Cat, Dog и Cow. Как можно догадаться, "голос" у каждого животного разный:
- кошка мяукает
- собака гавкает
- корова мычит
Если мы создаем Cat, который наследует Animal, мы обязаны будем реализовать voice():
Таким образом, давайте пропишем свой метод voice() для каждого класса:
1 2 3 4 5 6 |
public class Cat extends Animal { void voice() { System.out.println("Meow!"); } } |
1 2 3 4 5 |
public class Dog extends Animal { void voice() { System.out.println("Woof!"); } } |
1 2 3 4 5 |
public class Cow extends Animal { void voice() { System.out.println("Mooo!"); } } |
Создадим объекты этих классов и вызовем метод voice():
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Test { public static void main(String[] args) { Cat myCat = new Cat(); Dog myDog = new Dog(); Cow myCow = new Cow(); myCat.voice(); myDog.voice(); myCow.voice(); } } |
Получим:
Таким образом, каждый класс имеет свой метод voice(). Собака гавкает, а кошка мяукает - все как надо 🙂 При этом нам не нужно было прописывать этот метод в классе Animal чтобы потом переопределить его. Мы же с самого начала знаем, что он будет меняться.
Итак, вот мы и применили абстрактный метод. Надеемся Вы поняли суть.
Подведем итог:
- Чтобы создать абстрактный класс, перед словом "class" нужно дописать модификатор "abstract"
- Вы не можете создать объект абстрактного класса
- В абстрактном классе можно создавать абстрактные методы, а можно и "обычные"
- Абстрактные методы могут быть только в абстрактном классе
- "Обычные" методы абстрактного класса наследуются так же, как и для неабстрактных классов
Надеемся, что наша статья была Вам полезна. Можно записаться к нам на курсы по Java на сайте.