假设都base
和son
类有一个方法method_1
,PHP中是否有任何多态性?
,并有另一种方法的base
method_2
。
内base::method_2
,我怎么可以指向$this->method_1
到base::method_1
无论$this
是base
或son
一个实例?
假设都base
和son
类有一个方法method_1
,PHP中是否有任何多态性?
,并有另一种方法的base
method_2
。
内base::method_2
,我怎么可以指向$this->method_1
到base::method_1
无论$this
是base
或son
一个实例?
如果我理解正确的话,你想是这样的:
<?php
class base {
public function method1() {
echo "base:method1\n";
}
public function method2() {
if(get_class($this) == 'base') {
$this->method1();
}
else {
parent::method1();
}
echo "base:method2\n";
}
}
class son extends base {
public function method1() {
echo "son:method1\n";
}
}
$obj = new son();
$obj->method2();
在调用方法2将始终使用方法1的基础版本。
我可以做到这一点的最佳方式就像上面那样,但由于base没有父项,所以这段代码不起作用。我很确定你想做的事情是不可能的。
这是错误,你将得到:
PHP Fatal error: Cannot access parent:: when current class scope has no parent in
使函数私营:
<?php
class A
{
public function __construct()
{
$this->foo();
$this->bar();
}
private function foo() { echo "A::foo()\n"; }
public function bar() { echo "A::bar()\n"; }
}
class B extends A
{
public function foo() { echo "B::foo()\n"; }
public function bar() { echo "B::bar()\n"; }
}
new B();
?>
输出是:
A::foo()
B::bar()
虽然这看起来不像是规范的OOP,但是... – 2011-04-10 03:47:00
你说的这个canon是什么,为什么你期待PHP遵守它? – Matthew 2011-04-10 04:01:22
是它。它是单数(一位父母)。
son->method_1
可以添加或覆盖所有base->method_1
功能。
son->method_1
可以简单地添加额外的功能,并利用的它的功能,其余的的method_1
父母的实例,以便调用$this->method_1
将使用base->method_1
,并且son->method_1
只要你想从基地ISN使用什么”儿子重写。
如果调用子类中不存在的方法,PHP将遍历类层次结构,直到找到实现所需函数的祖类。这意味着如果你的son
类没有实现method_2
,PHP将自动寻找最近的祖先。在你的情况下,它会根据你的需要调用method_2
base
。
如果你是重写method_2
在son
类,并且你想要做自己实现method_2
,也叫base::method_2
实施那么你可以使用parent
关键字:
class son extends base {
public function method_2() {
parent::method_2();
//do son::method_2()-specific stuff here
}
}
您不能将parent
调用连接在一起,因此如果base
是GrandparentClass
的子类,则无法执行此类操作:
parent::parent::method_2(); // trying to call grandparent::method_2
// but this call will fail
但是你可以直接按名称引用的祖先类,所以这会工作:
GrandparentClass::method_2();
而只是把它远一点,还有一个叫class_parents()
函数返回的每一个数组你的类继承的祖先类。如果你想返回两个祖先,这可能会有所帮助,但是由于某种原因你不知道它的具体名称,你仍然可以使用eval()
来调用该函数。
例如,该代码将调用GrandparentClass::method_2()
没有在你的代码按名称直接引用类:
$parents = class_parents($this);
eval(end($parents) . "::method_2();");
希望有所帮助。
这会做你想做的。示例代码的道具(即使他没有工作)。
<?php
class base {
public function method1() {
echo "base::method1\n";
}
public function method2() {
if (get_parent_class($this) === FALSE) {
echo get_class($this)." has no parent\n";
$this->method1();
} else {
echo get_class($this)." has parent\n";
call_user_func(array(get_parent_class($this), 'method1'));
}
}
}
class son extends base {
public function method1() {
echo "son::method1\n";
}
}
$b = new base();
$b->method2();
$s = new son();
$s->method2();
?>
输出:
base has no parent
base::method1
son has parent
base::method1
什么你说的是不是多态。忽略子类重新实现方法?你为什么想做这个? – meagar 2011-04-10 04:03:57
@meagar,我同意。如果你不希望它被覆盖,它应该是'private'或'final'。 – Matthew 2011-04-10 04:12:59
您应该将问题的标题编辑为“PHP OOP层次结构中的问题”或“如何绕过继承 - PHP OOP”......目前存在误导。 – Dawson 2011-04-10 05:52:58