PHP面向对象:抽象,接口,继承等


PHP Object Oriented: Abstract, Interface, Inheritance, etc

几个星期前,我开始练习OO PHP,我做了一些课程,但我不知道我是否正确理解了这些概念。因此,我想展示一些课程,如果有人能告诉我他们对它的看法并能教我一些东西,我会很高兴。

如果你能解释你的评估和修改背后的原因,我会很感激的,并且记住……我正在学习:$ 我有一个产品目录,我们可以有多种类型的目录。基本上,Catalog是Product类实例的集合…

我已经为目录实现了一个基类,如下所示:

class BaseCatalog
{
    protected $_collection;
    protected $_count;
    public function __construct()
    {
        // some stuff here
    }
    public function getCount()
    {
        return $this->_count;
    }
    public function getProducts()
    {
        return $this->_collection;
    }
}

之后当我要使用目录时我扩展了这个类

class OrganicCatalog extends BaseCatalog implements InterfaceCatalog 
{ 
    protected $_collection;
    protected $_count;
    public function __construct() 
    {
        parent::__construct();
        // some more things here depending catalog type 
    }
    // some more methods specific of this catalog type

最后一个接口:

interface InterfaceCatalog  
{
    public function getCount();
    public function getProducts();
}

关于代码的一些疑问

  • 所有的目录类型都有相同的属性,它们之间的区别是获取此信息的过程。
  • 接口将有方法,所有目录类型将实现,但只有方法的原型(如果我将定义一些行为,我应该使用抽象类)是正确的吗?
  • 我认为基础产品永远不会被直接实例化,我在抽象中思考,但我一直在阅读抽象不能修改属性…也许我可以把construct设为private?
  • 哪是正确的方式来声明属性(集合,计数…)?只在基地?有人能解释一下吗?
  • 它是正确的把访问器(getter和setter)在基类?

我想这就是全部……谢谢大家提前,我知道解决像我这样的初学者的疑问有点无聊。

对不起我的英语:$

以下几点:

  • BaseCatalog定义了InterfaceCatalog使用的所有功能。我会考虑让BaseCatalog实现InterfaceCatalog;根据定义,它的每个子类也将是InterfaceCatalog
  • OrganicCatalog可能不应该有自己的$_count$_collection,因为它们在基类中受到保护(因此对子类可用)。
抽象类可以很好地修改属性,只要这些属性是在抽象类中定义的。理想情况下,抽象基类应该具有您希望子类继承的功能的近乎完整的实现(即"完整"减去您需要子类实现的内容)。必须由子类实现的东西应该标记为抽象。

如果您希望所有目录都扩展BaseCatalog,那么根本不需要这个接口。它的主要用途是,如果你希望有一个目录来管理自己的一切(即:它有自定义的getCountgetProducts方法)。这样做的类应该实现接口,但不扩展基类。如果InterfaceCatalog的实现不能总是像真正的目录那样工作,那么也许应该将接口添加到。

看起来还不错。

所有目录类型将具有相同的属性,区别在于这是获取此信息的过程。

听起来不错。

Interface将具有所有目录类型都将实现的方法只有方法的原型(如果我要定义一些行为)应该使用抽象类)对吗?

对,是这样。

我认为Base产品永远不会被直接实例化我一直在用抽象的方式思考,但我读到抽象不能修改属性……也许我可以把construct设为private ?

这是不对的。抽象类可以很好地修改属性。因此,可以BaseCatalog定义为抽象的。而且,正如cHao已经提到的,我确实也建议你让BaseCatalog实现InterfaceCatalog

哪是正确的方式来声明属性(集合,计数…)?只在基地?有人能解释一下吗?

把访问器(getter和setter)放在基类中是正确的吗?

这实际上取决于您对基类派生的预见需求。如果您认为所有派生都需要这些属性,并且可以为它们使用一些基本方法实现(getter),那么这是完全可以的。我看不出这有什么不对。

如果你不想让衍生函数覆盖这些方法,你可以将它们声明为final