假設都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