2011-04-10 27 views
2

假设都baseson类有一个方法method_1PHP中是否有任何多态性?

,并有另一种方法的basemethod_2

base::method_2,我怎么可以指向$this->method_1base::method_1无论$thisbaseson一个实例?

+0

什么你说的是不是多态。忽略子类重新实现方法?你为什么想做这个? – meagar 2011-04-10 04:03:57

+0

@meagar,我同意。如果你不希望它被覆盖,它应该是'private'或'final'。 – Matthew 2011-04-10 04:12:59

+0

您应该将问题的标题编辑为“PHP OOP层次结构中的问题”或“如何绕过继承 - PHP OOP”......目前存在误导。 – Dawson 2011-04-10 05:52:58

回答

1

如果我理解正确的话,你想是这样的:

<?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 
0

使函数私营:

<?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() 
+0

虽然这看起来不像是规范的OOP,但是... – 2011-04-10 03:47:00

+0

你说的这个canon是什么,为什么你期待PHP遵守它? – Matthew 2011-04-10 04:01:22

0

是它。它是单数(一位父母)。

son->method_1可以添加或覆盖所有base->method_1功能。

son->method_1可以简单地添加额外的功能,并利用的它的功能,其余的的method_1

父母的实例,以便调用$this->method_1将使用base->method_1,并且son->method_1只要你想从基地ISN使用什么”儿子重写。

0

如果调用子类中不存在的方法,PHP将遍历类层次结构,直到找到实现所需函数的祖类。这意味着如果你的son类没有实现method_2,PHP将自动寻找最近的祖先。在你的情况下,它会根据你的需要调用method_2base

如果你重写method_2son类,并且你想要做自己实现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调用连接在一起,因此如果baseGrandparentClass的子类,则无法执行此类操作:

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();"); 

希望有所帮助。

1

这会做你想做的。示例代码的道具(即使他没有工作)。

<?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 
相关问题