【问题标题】:How to extends this class?如何扩展这个类?
【发布时间】:2011-11-03 09:45:17
【问题描述】:

拥有具有dispayAsXMLdisplayAsHtml 两种显示方法的类证书。 我想创建 2 个新类 BonusCertificateGuaranteeCertificate,它们都有额外的属性。

我应该提取一个包含这些属性并从抽象类 3 新类扩展的抽象类,还是我可以保留这个证书类并从中扩展新类?使用新属性并覆盖新类中的displayAsXML abd displayAsHtml 方法?

   class Certificate {
      private $isin;
      private $tradingMarket;
      private $currency;
      private $issuer;
      private $issuingPrice;
      private $currentPrice;
 }

【问题讨论】:

  • 也许魔术方法 __set 和 __get 值得关注,您可以使用 __set 和 __get 方法来操作变量范围
  • 也许你能更好地解释一下你需要实现什么?
  • 您对自动刷新数据有疑问吗?如果这是问题所在,我会尝试使用 AJAX 每 X 秒更新(新 $object)您的对象。 (谷歌提供了大量关于 AJAX 的信息)如果你想创建价格历史并存储它:使用数据库,或者创建一个以时间为键的巨大数组。您希望用户如何发布此文档?您的服务器必须从哪里获取它?您可能还想添加一些额外的类和方法。 (例如,一个文档类,它告诉您有关您的文档的所有内容)如果它是关于计算所有这些?经济?东西 --> 我不能

标签: php oop


【解决方案1】:

如果您不希望类本身的实例存在,您可以创建一个抽象类。所以你可以像这样创建一个证书类:

abstract class Certificate 
{
    protected $isin;
    protected $tradingMarket;
    protected $currency;
    protected $issuer;
    protected $issuingPrice;
    protected $currentPrice;

    abstract public function displayAsXML();
    abstract public function displayAsHtml();
}

变量必须受到保护,否则类的后代无法访问它们。如果这不是必需的,请将它们保密。 abstract public functions 必须被从这个基类扩展的类覆盖:

class BonusCertificate extends Certificate
{
    protected $bonus;

    public function displayAsXML()
    {
        // Do your thing
    }

    public function displayAsHtml()
    {
        // Do your thing
    }   
}

所以你最终会得到三个类,第三个是 GuaranteeCertificate,看起来像 BonusCertificate。

如果您还需要存在“常规”证书实例,只需从类和函数定义中删除abstract,并在证书类中适当地创建displayAsXMLdisplayAsHtml 函数体。您仍然可以在派生类中覆盖这些函数。

还可以尝试阅读documentation

【讨论】:

  • 您的第一个代码 sn-p 包含错误:非抽象类可能不包含 PHP 中的抽象方法。
【解决方案2】:

你问自己是否会有 Certificate 类的实例。如果允许,则不要使用抽象。如果被阻止,则使用抽象。

还将类重命名为 ICertificate 而不是 Certificate 以表明它是一个接口

【讨论】:

  • 抽象类不是接口,它们是两种不同的工具。抽象类可以有实现,而接口不能。由于这种区别,不需要更改/为类名添加前缀,尽管这可能是提高instanceof 运算符可读性的一个很好的约定。然而,这样的命名约定对 PHP 的功能完全没有影响。另请参阅:Interfaces in PHPAbstraction in PHP
  • 鲍勃叔叔说:如果你在接口前加上 I,问问自己为什么你想让你的消费者知道它是一个接口。为什么这对他们很重要? source
  • @PelletenCate,我明白你的意思了。感谢您的提示
【解决方案3】:

如果一个类是不完整的并且你永远不希望类本身的实例存在,你就将它抽象化。

但首先你要定义证书的接口:

interface Certificate
{
    public function displayAsXML();
    public function displayAsHtml();
}

所以你可以像这样创建一个证书基类:

abstract class BaseCertificate implements Certificate
{
    protected $isin;
    protected $tradingMarket;
    protected $currency;
    protected $issuer;
    protected $issuingPrice;
    protected $currentPrice;
}

变量必须受到保护,否则类的后代无法访问它们(并且抽象类不会使用它们)。如果没有必要,请将它们保密(如果根本不使用,则将其删除)。接口中定义的公共函数必须由从该基类扩展的类实现:

class BonusCertificate extends BaseCertificate
{
    protected $bonus;

    public function displayAsXML()
    {
        // Do your thing
    }

    public function displayAsHtml()
    {
        // Do your thing
    }   
}

所以你最终会得到三个类,第三个是 GuaranteeCertificate,看起来像 BonusCertificate。

如果您还需要存在“常规”证书实例,只需从基类中删除 abstract 并实现函数定义,然后将 displayAsXMLdisplayAsHtml 函数体适当地移动到证书渲染类中,因为显示不属于对象类型本身的数据域。

然后将 type 属性添加到 Certificate 基类,以便您可以区分不同类型的证书。

还可以尝试阅读documentation

【讨论】:

    猜你喜欢
    • 2018-06-11
    • 2010-09-20
    • 2011-07-17
    • 2012-03-08
    • 1970-01-01
    • 2013-01-13
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多