真实世界抽象类使用简单样本

时间:2010-10-11 08:09:17

标签: php oop

使用抽象类的任何真实世界的简单示例? 我正在尝试使用PHP的OOP,但我仍然无法理解 - 为什么应该使用抽象类?何时(是的,我知道创建抽象类实例是不可能的,只有继承它的类的实例)。

2 个答案:

答案 0 :(得分:1)

也许你有一个图像类,你有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
    } 
}

看看Kohana's source on GitHub。它有一个Imageabstract

答案 1 :(得分:1)

好的,假设您要加载脚本配置。该配置可以存储在database / 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)方法,它将是{{1}的父类}和DatabaseConfiguration