Что такое абстрактный класс в perl?

Что такое абстрактный класс? Чем интерфейс отличается от абстрактного класса. Примеры реализации абстрактного класса и интерфейса в perl. Использование Class::Interface

Абстрактный класс в ООП — это базовый класс, который не предполагает создания своих экземпляров. Абстрактный класс может содержать абстрактные методы и атрибуты.

Абстрактный класс является яркой демонстрацией одного из основных принципов ООП - полиморфизма.

В некоторых языках программирования использование абстрактных классов запрещено. В некоторых - разрешено. Perl, как всегда, посередине. В нем можно реализовать абстрактный класс стандартными возможностями языка. Но в нем нет специальных конструкций для этого, как, например, в PHP или Java.

Абстрактный класс в PHP:

Абстрактный класс в Java:

Не смотря на то, что в Perl нет стандартного определения абстрактных классов, их использование - это интересный и полезный архитектурный прием.

Иногда абстрактные классы путают с интерфейсами. Это не совсем корректно. Хотя интерфейс в Perl часто является абстрактным классом.

Абстрактный класс отличается от интерфейса тем, что интерфейс - это только список методов, которые обязательно должны быть определены в подклассах. Абстрактный класс, во-первых, ни к чему не обязывает подкласс, во-вторых, может содержать полноценные функции и методы.

Обычно говорят, что абстрактный класс расширяется (extends), а интерфейс - реализуется (implements).

Интерфейс в perl, создаваемый с помощью Moose:

Использование абстрактных классов удобно тем, что можно разместить в этом классе все функции и методы, которые будут потом нужны во множестве других классов. Абстрактный класс - это отличное решение, которое спасает от дублирования кода.

Зачем нужны абстрактные классы и интерфейсы

Допустим у вас есть программа, которая скачивает с удаленного сервера файлы и обрабатывает их.

Сначала вы закачиваете простые txt-файлы, читаете данные, сохраняете их в БД, потом переносите файл в директорию с обработанными файлами. Для обработки файлов вы используете специальный класс Document.

Потом приходит ваш клиент и говорит, что через месяц надо будет обрабатывать не только txt-файлы, но и xml. А еще через пару месяцев добавляется doc и pdf. Если txt и xml еще чем-то похожи, то обработка doc и pdf уже сильно выделяется из общего потока. Теперь вы создаете для обработки каждого документа свой класс: DocumentXML.pm , DocumentPDF.pm и т.п. Начинает дублироваться код. Появляется путаница в обработчиках. В конце концов вы вызываете метод для распечатки csv-файла и программа падает, т.к. вы забыли добавить в DocumentCSV.pm метод printer().

Самым разумным в данном случае, будет превратить Document.pm в интерфейс, который будет задавать список методов, обязательных к определению в каждом подклассе. При этом, класс-интерфейс будет являться абстрактным классом, и его экземпляры в процессе работы программы создаваться не будут.

Теперь, если мы забыли указать какой-то метод, это станет ясно при первой же попытке запуска программы.

Более того, если некоторые методы будут общими для всех подклассов, можно определить их в абстрактном классе. Например, методы копирования и переноса файлов по разным директориям, или пересылки по почте и т.п.

Реализация интерфейсов и абстрактных классов в Perl с помощью Class::Interface

Class::Interface - удобный модуль, который помогает сделать реализацию интерфесов и абстрактных классов в perl делом простым и приятным.

Moose, кстати, тоже позволяет упростить реализацию интерфейсов. Пример с Moose уже приводился выше. Но Class::Interface, в отличие от Moose, небольшой и простой модуль, а не сложная и тяжелая система.

Для создания абстрактных классов и интерфейсов, модуль предоставляет 4 подпрограммы:

  • &interface() - превращает вызвавший ее класс в интерфейс.
  • &implements() - загружает интерфейс, имя которого передается в качестве параметра, и проверяет вызвавший класс на наличие всех необходимых методов.
  • &abstract() - превращает вызвавший класс в абстрактный.
  • &extends() - загружает данные указанного абстрактного класса и проверяет вызывающий класс на наличие абстрактных методов.

Для создания интерфейса необходимо, чтобы:

  • было указано use Class::Interface;
  • была вызвана подпрограмма &interface()
  • была объявлена хотя бы одна подпрограмма (англ. routine). Реализация подпрограммы в рамках интерфейса не является обязательной. Объявление подпрограммы допустимо двумя способами:
    • sub routine;
    • sub routine {}

Для создания абстрактного класса необходимо, чтобы:

  • было указано use Class::Interface;
  • была вызвана подпрограмма &abstract()
  • была объявлена хотя бы одна подпрограмма

Реализация интерфейса с помощью Class::Interface

Интерфейс:

Класс, реализующий интерфейс:

Скрипт:

Если в классе, реализующем интерфейс, не все методы определены, при запуске программы мы получим сообщение об ошибке:

Реализация абстрактного класса с помощью Class::Interface

Абстрактный класс:

Класс, расширяющий абстрактный класс:

Скрипт:

Полезные ссылки по теме "Абстрактный класс - Abstract Class - в Perl"

wikipedia.org: Абстрактный класс

AbstractClass

perlmonks.org: Interfaces in Perl

perlmonks.org: AbstractClass

search.cpan.org: Class::Interface

Что такое абстрактный класс в perl?: 1 комментарий

Комментарии запрещены.