有没有一些关于使用抽象类的真实世界的简单示例呢?我正在尝试学习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
}
}
Image
类,是抽象的
。好的,假设你想要加载脚本配置。这个配置可以存储在数据库/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
属性和get($key, $default = null)
方法,并且它将成为DatabaseConfiguration
和FileConfiguration
的父类。
interface Image
并让Image_Gd implements Image
就足够了? - Kirzilla