调用父类方法

时间:2010-01-09 03:41:42

标签: php oop class overloading

编辑问题以更好地反映我的需求。


采用以下示例:

class Base
{
    public $Text = null;

    public function __construct()
    {
        $this->Text = new Base_Text();
    }
}

class Base_Text extends Base
{
    public $Is = null;

    public function __construct()
    {
        $this->Is = new Base_Text_Is();
    }

    public function CammelCase($string)
    {
        return trim(str_replace(' ', '', ucwords($string)));
    }
}

class Base_Text_Is extends Base_Text
{
    public function CammelCase($string)
    {
        return ($string === $this->CammelCase($string)); // doesn't work
    }
}

如何修复Base_Text_Is::CammelCase()方法而不静态调用Base_Text类(不使用parent::Base_Text::)?

我为这种情况提出的唯一解决方案是创建一个像这样的单例函数:

function Base()
{
    static $instance = null;

    if (is_null($instance) === true)
    {
        $instance = new Base();
    }

    return $instance;
}

并将Base_Text_Is::CammelCase()方法更改为:

return ($string === Base()->Text->CammelCase($string));

为了避免创建Base类的两个对象实例,而不是执行:

$base = new Base();
$base->Text->Is->CammelCase('MethodOverloading'); // true

我只是这样做:

Base()->Text->Is->CammelCase('MethodOverloading'); // true

这是一个好习惯吗?还有其他解决方案吗?

2 个答案:

答案 0 :(得分:7)

你问题的核心在于:

  

Son :: B()如何调用爸爸:: A()   方法非静态(不使用   父母或爸爸)?

答案很简单,它不可以。您使用Dad::A()覆盖Son::A()。 Son对象现在唯一的A()概念是它自己的A()。您必须静态调用父方法,或者在完全不同的Dad对象实例上调用父方法。

最重要的是,如果您想调用父A()方法,为什么还要先打扰它呢?

你的结构也没有任何意义。为什么您希望拨打$dad->A()来将其传递给$dad->son->A()$dad->son->B()会调用$dad->A(),然后根据您的要求再次拨打$base = new Base(); $base->Text->Is->CammelCase('MethodOverloading'); // true ?这是一个无限循环。

除了确保不实例化多个父对象之外,你的单例方法似乎没有提供任何真正的优势,但事实是你仍然在实例化一个完全独立的对象来执行听起来像它的逻辑应该在课堂内而不是外面。

如果没有看到实际的逻辑和你想要完成的事情,很难知道应该推荐什么来避免这种循环依赖。但是,我想你可能想分析一下你正在尝试用这些方法做些什么,也许还要重新设计继承是如何工作的。

修改

我认为你的遗产继续得太多了。你没有理由这样做:

Base

如果所有功能都在子类中,则不应该实例化$text = new Text(); $text->isCamelCase('someString'); 类。它应该是这样的:

class Base
{
    //don't put anything related to child classes here,
    //unless it is going to provide specific functionality
}

class Text extends Base
{
    public function CamelCase($string)
    {
        return trim(str_replace(' ', '', ucwords($string)));
    }

    public function isCamelCase($string)
    {
        return ($string === $this->CamelCase($string));
    }
}

您的代码可以大大简化,删除了所有循环父/子实例化,并将特定功能推送到子类:

{{1}}

答案 1 :(得分:1)

我认为没有办法从孩子那里调用父方法而不用静态调用它或使用parent::。我可能会误解这个问题。创建Son()的实例不会创建两个对象。儿子延伸了爸爸,但它仍然是一个对象。

如果你打算用Son中的Singleton打电话给Dad()那么为什么要从Son那里扩展它?