Абстрактные классы в Java
В объектно-ориентированных концепциях все объекты описываются через классы, но, наоборот, не все классы используются для описания объектов. Если класс не содержит достаточно информации для описания конкретного объекта, такой класс является абстрактным классом.
Помимо того, что абстрактные классы не могут создавать экземпляры объектов, остальные функции класса всё ещё существуют. Переменные-члены, методы-члены и конструкторы имеют такие же способы доступа, как у обычных классов.
Поскольку абстрактные классы не могут создавать экземпляры объектов, абстрактные классы должны быть унаследованы, чтобы их можно было использовать. По этой причине обычно на этапе проектирования решается, стоит ли проектировать абстрактный класс.
Родительский класс содержит общие методы набора подклассов, но поскольку сам родительский класс является абстрактным, эти методы не могут быть использованы.
В Java абстрактные классы представляют собой отношение наследования. Класс может наследовать только один абстрактный класс, но класс может реализовывать несколько интерфейсов.
Абстрактные классы
В языке Java для определения абстрактного класса используется abstract class. Пример следующий:
Код файла Employee.java:
Обратите внимание, что этот класс Employee ничем не отличается. Хотя этот класс является абстрактным, он всё ещё имеет 3 переменные-члены, 7 методов-членов и 1 конструктор. Теперь, если вы попробуете следующий пример:
код файла AbstractDemo.java:
Когда вы попытаетесь скомпилировать класс AbstractDemo, будет выдана следующая ошибка:
Employee.java:46: Employee is abstract; cannot be instantiated
Employee e = new Employee("George W.", "Houston, TX", 43);
^
1 error
Наследование абстрактных классов
Мы можем наследовать свойства класса Employee следующим образом:
Код файла Salary.java:
Хотя мы не можем создать экземпляр класса Employee, если мы создадим экземпляр объекта класса Salary, этот объект унаследует 7 методов-членов класса Employee, и через эти методы можно задать или получить три переменные-члены.
код файла AbstractDemo.java:
Приведённая выше программа компилируется и выполняется со следующим результатом:
Constructing an Employee Constructing an Employee Call mailCheck using Salary reference -- Within mailCheck of Salary class Mailing check to Mohd Mohtashim with salary 3600.0 Call mailCheck using Employee reference-- Within mailCheck of Salary class Mailing check to John Adams with salary 2400.
Абстрактные методы
Если вы хотите спроектировать такой класс, который содержит специальный метод-член, конкретная реализация которого определяется его подклассами, то вы можете объявить этот метод как абстрактный метод в родительском классе.
Ключевое слово abstract также можно использовать для объявления абстрактных методов. Абстрактный метод содержит только имя метода и не имеет тела метода.
Абстрактный метод не определён; после имени метода сразу следует точка с запятой вместо фигурных скобок.
Объявление абстрактного метода приводит к следующим двум последствиям:
- Если класс содержит абстрактный метод, то класс должен быть абстрактным классом.
- Любой подкласс должен переопределить абстрактный метод родительского класса или объявить себя абстрактным классом.
Подкласс, который наследует абстрактный метод, должен переопределить этот метод. В противном случае подкласс также должен быть объявлен абстрактным классом. В конечном итоге должен существовать подкласс, который реализует абстрактный метод; иначе ни один из них — от исходного родительского класса до конечного подкласса — не может использоваться для создания объектов.
Если класс Salary наследует класс Employee, то он должен реализовать метод computePay():
Код файла Salary.java:
Сводные правила абстрактных классов
1. Абстрактные классы нельзя инстанцировать (ошибка, которую часто совершают начинающие). При попытке создания экземпляра будет выдана ошибка, и компиляция завершится неудачно. Только неабстрактные подклассы абстрактного класса могут создавать объекты.
2. Абстрактный класс не обязательно содержит абстрактные методы, но класс с абстрактными методами должен быть абстрактным классом.
3. Абстрактные методы в абстрактном классе являются только объявлениями и не содержат тела метода, то есть конкретная реализация метода, а именно конкретная функциональность метода, не предоставляется.
4. Конструкторы и методы класса (методы, изменённые с помощью static) не могут быть объявлены абстрактными методами.
5. Подкласс абстрактного класса должен предоставить конкретные реализации абстрактных методов в абстрактном классе, если только подкласс также не является абстрактным классом.