【问题标题】:PHP Class calling base class extended class functionPHP类调用基类扩展类功能
【发布时间】:2013-08-09 15:23:26
【问题描述】:

我有这个基类:

class Base
{
    public $extA;
    public $extB;

    function __construct()
    {

    }

    public function Init()
    {
        $this->extA = new ExtA();
        $this->extB = new ExtB( $this );
    }

    public function Test()
    {
        return 'Base Test Here!';
    }
}

扩展基类的ExtA类

class ExtA extends Base
{
    public function Test()
    {
        return 'ExtA Test Here!';
    }
}

ExtB 类也扩展了基类

class ExtB extends Base
{
    private $base;

    public function __construct( $base )
    {
        $this->base = $base;
    }

    public function Test()
    {
        return 'ExtB calling ExtA->Test()::' . $this->base->extA->Test();
    }
}


$base = new Base();
$base->Init();

var_dump( $base->Test() );
var_dump( $base->extA->Test() );
var_dump( $base->extB->Test() );

我尝试从 ExtB 调用 ExtA 类 Test() 函数, ExtA 和 ExtB 都在扩展基类。 我的问题是:这样可以吗,还是有更好、更快的解决方案?

extends 也是必要的吗? 或者像这样就足够了

class ExtA
{
     ...
}
class ExtB
{
     ...
}

谢谢!

【问题讨论】:

  • 这里有一些非常奇怪的依赖关系。你想继承吗?
  • 理论上这在某种程度上是有效的……如果它运行良好,这取决于你想要的行为。 B 类的扩展是必要的,A 类的扩展不是。
  • @Frits van Campen 对不起,我不明白,我应该如何继承?
  • @user2668398 通过使用extendsimplements。查看 PHP 的 OOP 教程。
  • 实现一个没有问题的机制是完全没有意义的。展示你的真正的问题,我们可以为你指出一个解决方案[让它要么是继承,要么是接口......]。尽管如此,你的方法至少是好奇

标签: php class function oop


【解决方案1】:

这是一种奇怪的 OOP 方式。 Base 类不应该知道任何关于它的孩子的事情,所以我们应该走更正确的方法。让我们实现装饰器模式:

interface IExt
{
    public function test();
}

abstract class ExtDecorator implements IExt
{
    protected $instance;

    public function __construct(IExt $ext)
    {
        $this->instance = $ext;
    }
}

class ExtA extends ExtDecorator
{
    public function test()
    {
        return 'ExtA::test here and calling... ' . $this->instance->test();
    }
}


class ExtB extends ExtDecorator
{
    public function test()
    {
        return 'ExtB::test is here and calling... ' . $this->instance->test();
    }
}

class Base implements IExt
{
    public function test()
    {
        return 'Base::test here!';
    }
}

class Printer
{
    public static function doMagic(IExt $ext)
    {
        echo $ext->test()."\n";
    }
}


Printer::doMagic($base = new Base); 
// Base::test here!
Printer::doMagic($extA = new ExtA($base)); 
// ExtA::test here and calling... Base::test here!
Printer::doMagic(new ExtB($extA)); 
// ExtB::test is here and calling... ExtA::test here and calling... Base::test here!

你可以随心所欲地玩下去

【讨论】:

  • 使用装饰器然后扩展它有什么意义?只是扩展基类,你不应该在没有任何具体原因的情况下添加复杂层。
  • 也许你是对的。乍一看,我也想过这个问题,但可能主题启动者想要的不仅仅是调用 parent::test()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-09
  • 1970-01-01
  • 2019-07-09
  • 2015-09-22
  • 2013-08-29
  • 1970-01-01
相关资源
最近更新 更多