Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中的parent::parent_Php_Oop_Parent - Fatal编程技术网

PHP中的parent::parent

PHP中的parent::parent,php,oop,parent,Php,Oop,Parent,我搜索一种方法来访问父类,父类函数而不调用父类。。。嗯,这听起来有点奇怪,所以我举个例子: class myclass { public function test() { return 'level 1'; } } class myclass2 extends myclass { public function test() { return parent::test() . '-level 2'; } } class myclass3 extends myclass2 { pub

我搜索一种方法来访问父类,父类函数而不调用父类。。。嗯,这听起来有点奇怪,所以我举个例子:

class myclass
{
  public function test() { return 'level 1'; }
}
class myclass2 extends myclass
{
  public function test() { return parent::test() . '-level 2'; }
}
class myclass3 extends myclass2
{
  public function test() { return parent::test() . '-level 3'; }
}
$example = new myclass3();
echo $example->test(); // should display "level 1-level 2-level 3"
我想显示“1级-3级”,然后执行类似操作:

class myclass3 extends myclass2
{
  public function test() { return parent::parent::test() . '-level 3'; }
}

你知道我怎么做吗?(我不允许编辑myclass和myclass2,它们是框架的一部分…

不,这是不可能的。不幸的是,不可能直接引用原始类,只能引用它的
self
或它的
父类

您不能链接父类,而是在父类中创建某种GetParent()方法,只返回$this

没有运算符获取根对象。我会这样做:

class myclass
{
  public function getRoot() { return __CLASS__; }
  public function test() { return 'level 1'; }
}
class myclass2 extends myclass
{
  public function getRoot() { return parent::getRoot(); }
}
class myclass3 extends myclass2
{
  public function getRoot() { return parent::getRoot(); }
  public function test() {
    $grandparent = self::getRoot();
    return $grandparent::test() . '-level 3';
  }
}
$example = new myclass3();
echo $example->test(); // should display "level 1-level 2-level 3"

也许您可以将myclass2作为成员对象添加到myclass3中,并尝试编写如下代码:

class myclass3{
myclass2 obj2;
public function test() { return $obj2->callParentTest() . '-level3';}
}
你可以使用

或者您可以使用:


但是,这可能不是一个好主意,这取决于您试图实现的目标。

如果您想直接在class1上使用test函数,则必须从class1进行扩展。请搜索有关polimorphism的信息

当您有class5时,您会尝试“
parent::parent::parent::parent
”吗

我认为您可以在测试方法中添加一个
level
参数。先检查一下

<?php
    class myclass
    {
        public function test($level) 
        { 
            return 'level 1'; 
        }
    }
    class myclass2 extends myclass
    {
        public function test($level) 
        { 

            return $level >= 2 ? parent::test($level) . '-level 2' : parent::test($level); 
        }
    }
    class myclass3 extends myclass2
    {
        public function test() 
        { 
            return parent::test(1) . '-level 3';
        }
    }
    $example = new myclass3();
    echo $example->test(); // should display "level 1-level 3"

简单的解决方案。直接使用根对象myclass:

class myclass3 extends myclass2
{
  public function test() { return myclass::test() . '-level 3'; }
}

如果需要更通用的方法,请查看。

在某些情况下,您可能可以完全重写root的方法。我的意思是,您可以复制父对象的父对象的方法代码并添加您的方法代码,而不是调用父对象的父对象的方法代码。

我的方法: 如果您有代码:
class A {
    protected function method () {
        var_dump('A -> method');
    }
}

class B extends A {
    protected function method () {
        var_dump('B -> method');
    }
}

class C extends B {
    protected function method () {
        var_dump('C -> method');
    }
}
您希望在
类C
中调用方法
类A
(但不是
类B
)将其重构为代码:

<?php

class A {
    protected function method () {
        $this->methodA();
    }

    protected function methodA () {
        var_dump('A -> method');
    }
}

class B extends A {
    protected function method () {
        var_dump('B -> method');
    }
}

class C extends B {
    protected function method () {
        $this->methodA();
    }
}

这个问题受到以下问题的影响。用例是什么?你为什么要这么做?您很有可能以一种不好的方式破坏了对象模型,这种方式可能会使对象处于不一致的状态(这假设父类和祖父母类本身设计良好,并且遵循正确的OO原则,但它们很可能不会)。如果您的myclass3不应该调用myclass2,那么您不应该从myclass2扩展它,而应该从myclass扩展它。除非你能澄清你的问题的用途,否则我会说你做错了。继承在父类和子类之间创建行为作为关系。换句话说,myclass3的行为与myclass2相同。通过让myclass3表现得像myclass1一样,您实际上绕过了3和2之间的关系。为了回答Gordon和其他询问更多细节的人,我需要优化magento框架的某些部分。因此,在扩展类的过程中需要遵循一些规则。另外,我的class3只是覆盖了class2中包含的20个函数中的1个函数。我不想复制粘贴类3中的所有函数,这是没有意义的(这就是OOP存在的原因)。那么我不得不从myclass2而不是myclass进行扩展。@Alexandre:换句话说,您是有意通过扩展类来替换类的行为,而不是直接编辑类。这很公平(虽然有潜在的危险),但是你的改变对其他人有用吗?如果您正在使用社区版,您能否将您的更改贡献给Magento项目?如果是这样的话,从Magento框架更新类而不是扩展它是有意义的。@outis:这个电子商务框架在性能方面有很大的问题,这是众所周知的。当他们开始这个项目时,他们专注于功能而不是性能。所以我得到了一个优化现有网上商店的职位。我不知道是否允许我发布代码。我也不确定Magento是否会接受我正在做的那种优化。为了完成,我迫不及待地更新Magento。为什么我不直接编辑框架的代码。这只是因为我希望能够升级并保持我的模块与此升级。
$此
始终指实例。它不会神奇地将myclass3的实例转换为myclass2或myclass1的实例。调用
$this->getParent()->getParent()->foo()
仍将从myclass3实例的对象上下文调用
foo
。我只是建议这可能是实现类链接的一种方法。但是,通过实例化对象,它确实需要一些额外的工作。但是你是对的,如果没有额外的工作,它不会神奇地解决这个问题。@Trikks:它根本解决不了问题。它甚至不是解决方案的一部分。
self
关键字仅在与范围解析(
)一起使用时有效–它不是值,不能从函数返回。
test()
还存在一些其他问题。outis已经修复了一些问题,但仍然无法正常工作。即使我将test()设为静态。我认为
myclass::test()
更好。我还发现了相同的解决方案,它的概念与get\u granparent相同。。。但是我不知道这是否是一个好方法。我认为使用反射作为
get\u祖父母\u class
did是非常好的,但是对于这个用例,它可能有点过载。如果你有一个4,它也不起作用。级别myclass4扩展了myclass3。@Alexandre我猜您是在尝试扩展Magento网格类中的_prepareCollection()函数时遇到这个问题的。我只是想承认,MaGeto开发人员遵循的逻辑很差,没有考虑到人们是否想要扩展他们的功能。它们应该在每个函数的顶部包括:$collection=$this->getCollection();如果(is_null($collection)){$collection=Mage::getResourceModel('identifier/name');}发生这种情况:myclass::test(),那么该方法不应该定义为
static
?@MagePsycho-nope,这只是奇怪的PHP怪癖。总共
class A {
    protected function method () {
        var_dump('A -> method');
    }
}

class B extends A {
    protected function method () {
        var_dump('B -> method');
    }
}

class C extends B {
    protected function method () {
        var_dump('C -> method');
    }
}
<?php

class A {
    protected function method () {
        $this->methodA();
    }

    protected function methodA () {
        var_dump('A -> method');
    }
}

class B extends A {
    protected function method () {
        var_dump('B -> method');
    }
}

class C extends B {
    protected function method () {
        $this->methodA();
    }
}