Использование простых примеров абстрактного класса в реальном мире

Любые реальные простые образцы использования абстрактного класса? Я пытаюсь войти в ООП PHP, но я все еще не могу понять – зачем использовать абстрактный класс и когда (Да, я знаю, что невозможно создать экземпляр абстрактного класса, только экземпляр класса, наследующий его).

Возможно, у вас есть класс изображений, и у вас есть 2 драйвера, GD и ImageMagick.

Ваш базовый класс может быть

abstract class Image { public function resize($width, $height) { // Some prep code... } } 

Тогда ваш драйвер GD будет похож на

 class Image_Gd extends Image { public function resize($width, $height) { // Actual code } } 

Посмотрите на источник Коханы на GitHub . Он имеет класс Image который является abstract .

ОК, допустим, вы хотите загрузить конфигурацию скрипта. Эта конфигурация может быть сохранена в файле базы данных / XML / INI / YAML. Каждый драйвер должен реализовать некоторый интерфейс, назовем его ConfigurationLoader .

 interface ConfigurationLoader { public function load(); public function get($key, $default = null); } // The final usage of the code: $configuration = new XMLConfiguration('./some/file.xml'); $configuration = new YAMLConfiguration('./some/file.yaml'); $configuration = new DatabaseConfiguration($dbHandler, 'table_name'); $configuration->load(); echo $configuration->get('abc.def.ghi'); 

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

 class DatabaseConfiguration implements ConfigurationLoader { protected $config = array(); protected $pdo, $tableName; public function __construct(PDO $dbHandler, $tableName) { $this->pdo = $pdo; $this->tableName = $tableName; } public function load() { $this->config = /* fetch data from database */; } public function get($key, $default = null) { return array_key_exists($this->config, $key) ? $this->config[$key] : $default; } } 

Теперь нам нужно реализовать драйвер XML, INI и YAML. Все они работают почти одинаково, поэтому … давайте создадим абстрактный класс, который будет обрабатывать общий код:

  abstract class FileConfiguration implements ConfigurationLoader { // Each file-based configuration loader has a constructor that takes file name as first argument protected $filename; public function __construct($filename) { $this->filename = $filename; $this->getFileContents(); } // Each file-based driver has to store file content protected $fileContent; protected function getFileContents() { $this->fileContents = file_get_contents($this->filename); } // Each driver will have to implement its own implementation of load(). // XMLConfiguration will parse XML, INIConfiguration will parse INI etc. abstract public function load(); // However all of them will store parsed configuration in $config array: protected $config = array(); public function get($key, $default = null) { return array_key_exists($this->config, $key) ? $this->config[$key] : $default; } } 

FileConfiguration должен быть абстрактным, потому что он не знает, как разбирать содержимое файла. Только доставленные классы знают, как это сделать:

  class XMLConfiguration extends FileConfiguration { public function load() { $xml = simplexml_load_string($this->fileContents); foreach ($xml->root as $config) { $this->config[(string) $config->key] = (string) $config->value; } } } class YAMLConfiguration extends FileConfiguration { public function load() { $yaml = new SomeYAMLParser($this->fileContents); foreach ($yaml->parse() as $config) { $this->config[$config['key']] = $config['value']; } } } class INIConfiguration extends FileConfiguration { public function load() { ... } } 

Как вы можете видеть в этом примере, может быть еще один абстрактный класс AbstractConfiguration который будет хранить $config property и get($key, $default = null) и это будет родительский класс для DatabaseConfiguration и FileConfiguration .