Ответы:
Ты не поверишь... Они нужны именно для абстракции. Пример: Ты разрабатываешь IDE с расчетом поддержки нескольких языков программирования. По сути, ты с любым кодом можешь выполнять действия типа check syntax, build, run, refuctor и прочее. Для каждого языка эти методы будут реализованы по-своему, но они будут присутствовать у всех. Тут то и появляется абстрактный класс. Допустим он называется AbstructLang, а все его потомки типа CLang, JavaLang,... Так вот, при помощи абстрактного класса тебе будет все равно на каком языке написан код, ты к нему будешь обращаться через абстрактный класс:
AbstructLang absLang = new CLang(); //Для C
AbstructLang absLang = new JavaLang(); //Для Java
А так как общие методы наследуемы, то и вызывать их можно будет не заморачиваясь на том код на каком языке мы обрабатываем (absLang.build(), absLang.run()).
Надеюсь, идею уловил? При помощи абстрактного класса будет также проще расширять функционал, например, добавление нового языка, при этом изменения существующего кода практически не будет (ну только в case добавить вариант нового языка).
Если без привязок конкретно к php, то абстрактный класс -- это класс, в котором есть неопределённые функции. Это как бы недоделанный класс, который нужно дописать, чтобы он заработал (т.е. реализовать недостающие методы).
Например, какой-то класс что-то сложное рассчитывает, но перед этим он должен откуда-то взять исходные данные. Можно данные брать из разных источников, там из файла, с клавиатуры, из инета, из БД, форматы представления могут быть разными и т.п. Поэтому можно сделать общий класс, который будет всё считать, и оставить одну функцию неопределённой. Программист, который будет использовать класс, должен будет ознакомиться с документацией и сам реализовать нужный метод загрузки данных.
Назначение абстрактных классов понятно. Но для того, чтобы оправдать их использование в PHP, нужна очень высокая абстракция в проекте и точная организация. Я у себя в проектах использую обычные классы вместо абстрактных, просто некоторые методы снабжаю "дефолтовым" кодом. В наследниках эти методы потом переопределяются и получаются в итоге полностью законченные рабочие классы. А делать некоторые методы "несуществующими", чтобы потом нарваться на error... помоему в этом меньше смысла.
На примере. Есть задача сделать систему кеширования. Проанализировав возможные хранилища для кеширования данных(например мемкеш, файлы, еакслератор и.д.д) вы выявили некий общий функционал у всех кешеров. Вы ставите себе задачу создать универсальное средство для кеширования на своих проектах. Одним из наиболее оптимальных способов является создание некого универсального интерфейса описывающего базовый функционал для всех систем кешировния. Таким образом описываем интерфейс, создаем абстрактный класс реализующий этот интерфейс. В данном абстрактном классе реализуем методы общие для всех систем кешированя, например механизм сериализации объектов. На основе этого абстрактного класса, реализуем конкретные классы адаптеры для конкретных систем кеширования.
Если у вас имеется иерархия классов, и есть некий общий метод, который проходит сковзняком через всю иерархию, то совершенно очевидно что этот метод надо вынести в самого первого родителя, от которого иерархия начинается.
В чем отличие?
- Потомки абстрактного класса ОБЯЗАНЫ реализовать ВСЕ методы объявленные в этом классе.
14 лет назад