繁体   English   中英

PHP调用父类方法

[英]PHP call parent class method

class Foo {
    protected static $a = 1;
    protected $b = 2;

    public function func() { return 'foo' . static::$a . $this->b; }
}
class Bar extends Foo {
    protected static $a = 3;
    protected $b = 4;

    public function func() { return 'bar' . static::$a . $this->b; }
}

$obj = new Bar();
$obj->func(); // returns of course 'bar34'

PHP中是否有任何选项可以从Foo类调用func()? 在C ++中,我会将$ obj转换为Foo并简单地调用func()

Bar* obj = new Bar();
Foo* obj2 = (Bar*) obj;
obj2->func(); // returns 'foo14';

这不是我所说的漂亮,但它的工作原理与您对C ++的描述相似; 它的工作原理是调用get_parent_class()然后滥用PHP从字符串创建对象的能力。

<?php

class Foo {
    public function func() { echo 'foo'; }
}
class Bar extends Foo {
    public function func() { echo 'bar'; }
}

$obj = new Bar();
$obj->func(); // Prints 'bar'

$parentClassString = get_parent_class($obj);
$newObj = new $parentClassString; // Gotta love PHP for magic like this
$newObj->func(); // Prints 'foo'

请参阅此代码段以查看其实际效果。

编辑

这是很多工作,但你可以使用所谓的Late Static Binding ,也许在Jokerius的答案中可以更清楚地解释。 这要求你编写一堆自定义代码,我认为这不是优先考虑的。 总的来说,简短的答案似乎是:它真的不可能。

对我来说,这看起来像是一个设计问题。 但是,如果我以一种易于阅读且不重新思考我的设计的方式处理这个问题,我会这样做:

<?php
class Foo {
    public function func() { return 'foo'; }
}
class Bar extends Foo {
    public function func() { return 'bar'; }
    public function parentFunc() { return parent::func(); }
}

$obj = new Bar();
$obj->parentFunc(); // returns of course 'foo'

Loek的答案也有效,但不会在父对象上调用方法。 它只是在类parent上调用方法。 这一切都取决于您正在寻找的功能。

你也可以这样做:

<?php
class Foo {
    public function func() { return 'foo'; }
}
class Bar extends Foo {
    public function func($parent = false) { 
        if ($parent) {
            return parent::func();
        }
        return 'bar';
    }
}

$obj = new Bar();
$obj->func(true); // returns of course 'foo'

这是类似的,但不需要额外的方法。

就个人而言,我觉得这个问题可能需要重新考虑代码设计而不是编码解决方案。

- 编辑 -

为了详细说明“重新考虑代码设计”,我会问自己“为什么我需要一个具有相同名称但功能不同的两种方法的对象?这不是两个不同对象的工作吗?向后追踪问题直到您会发现设计问题。或者您需要决定框架所需的对象。

如果你想沉迷于反射,那么它是可能的,但我坚决认为这不应该在任何生产代码附近使用。 如果你有一个子类的实例,那么你有一个原因,如果它被覆盖了一个父方法,那么这也是因为一个原因。

假设你已经知道了所有这些,那么在免责声明的情况下,这应该适用于任何远程最新版本的PHP:

class Foo { public function func() { echo 'I am the parent'; } }
class Bar extends Foo { public function func() { echo 'I am the child'; } }

// Create instance of child class
$bar = new Bar;

// Create reflection class
$reflected = new ReflectionClass(get_class($bar));

// Get parent method
$method = $reflected->getParentClass()->getMethod('func');

// Invoke method on child object
$method->invokeArgs($bar, []);

// I am the parent

请参阅https://3v4l.org/NP6j8

我不知道它应该帮助你,但尝试在Bar类中添加此功能

public function callParent($function){
    return parent::$function();
}

并打电话

echo $obj->callParent("func");

[更新]你也可以自己写这样的演员表

public function castAs($newClass) {
    $obj = new $newClass;
    foreach (get_object_vars($this) as $key => $name) {
        $obj->$key = $name;
    }
    return $obj;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM