2011-04-10 28 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 
相關問題