2017-03-18 54 views
1

在一起,讓我們假定我們有2個特點(在PHP 7.1測試):性狀衝突解決不斷變化的知名度

<?php 

trait HelloA 
{ 
    private function X() 
    { 
     echo "x"; 
    } 
} 

trait HelloB 
{ 
    private function X() 
    { 
     echo "y"; 
    } 
} 

如果我們想申請任何性狀,使方法X公開,我們可以這樣定義類:

class Summary 
{ 
    use HelloA { 
     HelloA::X as public; 
    } 
} 

,然後我們可以使用沒有任何問題

$s = new Summary(); 
$s->X(); 

和它的作品沒有任何proble米

但是,如果我們想用兩個性狀,並有定義,像這樣總結類:

class Summary 
{ 
    use HelloA, HelloB { 
     HelloA::X as public; 
    } 
} 

我們將得到致命錯誤:

Trait method X has not been applied, because there are collisions with other trait methods on Summary.

我們可以解決定義這樣的類中的衝突:

class Summary 
{ 
    use HelloA, HelloB { 
     HelloA::X insteadof HelloB; 
    } 
} 

,但現在這是不可能運行

$s = new Summary(); 
$s->X(); 

更多,因爲我們會得到致命錯誤:

Fatal error: Uncaught Error: Call to private method Summary::X() from context ''

的問題是 - 有什麼辦法在總結類既解決衝突有關,也改變方法的知名度?

目前,我認爲這是不可能的,建設這樣的例子:

use HelloA, HelloB { 
     HelloA::X insteadof HelloB as public; 
    } 

會導致解析錯誤,但也許它應該在一些其他的方式,使其工作寫?

顯然,作爲解決方法,我們可以用不同的方法名摘要類創建並運行裏面X方法,但它不是我要問:)

回答

3

當然,你可以更改方法的可視性和做解決衝突,只是不在相同的聲明。

class Summary 
{ 
    use HelloA, HelloB { 
     HelloA::X insteadof HelloB; 
     HelloA::X as public; 
    } 
} 

這應該給你正是你期望的。

+0

感謝它似乎工作。我也在嘗試這個,但必須使用'HelloB :: X作爲公共;'然後我得到致命錯誤 –