dougao1542 2015-09-25 21:08
浏览 67
已采纳

OOP-继承:子类Y中的$ this(从X继承)当从Y调用Y的方法时指向X

I have huge project and in some point of extending it I want to do something $this in subclass Y (which inherits from X) pointing to X when method from Y called from X :) I can't interfere to much in class structure and I want to do it NICELY without any "helpers", additional constructor parameters with "controller path" or something like that.

So the problem is: when I instantiate ControllerGallery it calls constructor which calls parent contructor (from ControllerResource which is parent of ControllerGallery). But in parent constructor (ControllerResource), variable $this is pointing to ControllerGallery, not ControllerResource.

I know that when I instantiate class, there is only one object which is created (only "ControllerGallery", not: "ControllerGallery and it's parent ControllerResource"), and that's the problem. My question is: how to achieve the result which is shown below? Any suggestions?

<?php

abstract class Controller {
    function getParentController()
    {
        return null;
    }

    function getController(){
        return $this;
    }
}

class ControllerResource extends Controller
{
    protected $CONTROLLER_PATH = 'Resource';
    protected $scripts;

    function __construct(){
        $this->addScript($this->CONTROLLER_PATH.DIRECTORY_SEPARATOR.'general_resource_support_script.js');
    }

    function addScript($name){
        $this->scripts[] = $name;
    }

    function getParentController()
    {
        return parent::getController();
    }

    function getScriptPaths(){
        return $this->scripts;
    }
}

class ControllerProduct extends ControllerResource
{
    protected $CONTROLLER_PATH = 'Product';
    function __construct(){
        parent::__construct();
        $this->addScript($this->CONTROLLER_PATH.DIRECTORY_SEPARATOR.'product_support_scripts.js');
    }
}

class ControllerGallery extends ControllerResource
{
    protected $CONTROLLER_PATH = 'Gallery';
    function __construct(){
        parent::__construct();
        $this->addScript($this->CONTROLLER_PATH.DIRECTORY_SEPARATOR.'gallery_scripts.js');
    }
}



$controllerProduct = new ControllerProduct();
$controllerGallery = new ControllerGallery();

echo('<pre>');
print_r($controllerProduct->getScriptPaths());
print_r($controllerGallery->getScriptPaths());
echo('</pre>');

echo('
<pre>
<b>SHOULD BE:</b>
Array
(
    [0] => <b>Resource</b>\general_resource_support_script.js
    [1] => Product\product_support_scripts.js
)
Array
(
    [0] => <b>Resource</b>\general_resource_support_script.js
    [1] => Gallery\gallery_scripts.js
)
</pre>
');


?>

And we get the result:

Array
(
    [0] => Product\general_resource_support_script.js
    [1] => Product\product_support_scripts.js
)
Array
(
    [0] => Gallery\general_resource_support_script.js
    [1] => Gallery\gallery_scripts.js
)

But it should be:

Array
(
    [0] => Resource\general_resource_support_script.js
    [1] => Product\product_support_scripts.js
)
Array
(
    [0] => Resource\general_resource_support_script.js
    [1] => Gallery\gallery_scripts.js
)
  • 写回答

1条回答 默认 最新

  • douzhi2988 2015-09-25 21:47
    关注

    protected $CONTROLLER_PATH is declared in both, ControllerResource and ControllerProduct classes. In PHP you can redeclare public and protected method, but since ControllerProduct extends ControllerResource value of that variable will be the value in derived class. If you change the visibility of $CONTROLLER_PATH property to private it will belong to that class only and will not be overridden.

    PHP Visibility

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?