2016-03-20 12 views
0

私はPHPを学んでいます。以下は、クラス階層である -PHPで引数を取らない多値継承の関数のオーバーロード

FamilyTree 
    | 
    | 
Grandparents 
    | 
    | 
Parents 

Parents$dob残りと呼ばれる余分な宿泊施設では、引数の数が異なっていたので、私は​​をオーバーロードすることができましたGrandparents

から継承されてきたが、どのように私はdisplay_values()に過負荷をかけませんそれは何の引数を取っていないので?

これはコードで:署名とメソッド名をオーバーロードする方法について

<?php 

class FamilyTree { 

    protected $name; 
    protected $sex; 
    protected $married; 
    protected $number_of_kids; 

    public function display_values() { 
     echo $this->name   . "<br />"; 
     echo $this->sex    . "<br />"; 
     echo $this->married   . "<br />"; 
     echo $this->number_of_kids . "<br />"; 
    } 
} 

class Grandparents extends FamilyTree { 

    public function set_values($name, $sex, $married, $number_of_kids) { 
     $this->name   = $name; 
     $this->sex   = $sex; 
     $this->married  = $married; 
     $this->number_of_kids = $number_of_kids; 
    }  
} 

class Parents extends Grandparents { 

    private $dob; 

    public function __call($function_name, $arguments) { 
     if($function_name == 'set_values' && count($arguments) == 5) { 
      $this->$name   = $name; 
      $this->sex   = $sex; 
      $this->married  = $married; 
      $this->number_of_kids = $number_of_kids; 
      $this->dob   = $dob; 
     } 
    } 
} 

$gp = new Grandparents(); 
$gp->set_values("James", "Male", 'yes', 5); 

$p = new Parents(); 
$p->set_values("Samuel", "Male", 'yes', 2, '2/5/1974'); 

$gp->display_values(); 
+1

'Parents'クラスに' public function display_values() 'を追加するとどうなりますか? –

+0

@u_mulder、もし私がそれをしたら、それは** $ this-> dob **のために何も印刷されません。 –

答えて

2

あなたを失望させても、そのメソッドを "オーバーロード"できませんでした。

__call場合は、あなたの実装を詳しく見てみた場合:

public function __call($function_name, $arguments) { 
    if($function_name == 'set_values' && count($arguments) == 5) { 
     $this->$name   = $name; 
     $this->sex   = $sex; 
     $this->married  = $married; 
     $this->number_of_kids = $number_of_kids; 
     $this->dob   = $dob; 
    } 
} 

あなたは

  • $this->$nameでなければなりません$this->name
  • $name$sex$married$number_of_kids$dobがあることがわかりますすべて未定義で、代わりに$arguments[0]$arguments[4]

PHP simply discards too many arguments to user-defined functionsのように、__call実装が全く呼び出されません。あなたの代わりに何ができるか

、関数をオーバーライドし、parent::と親の実装を呼び出すです:

public function set_values($name, $sex, $married, $number_of_kids, $dob = '') { 
    parent::set_values($name, $sex, $married, $number_of_kids); 
    $this->dob = $dob; 
} 

それ以外NULLをデフォルトとなるので、私はちょうど空の文字列に$dobを初期化しています。

その後、3のいずれかで呼び出すことができ
public function set_values($name, $sex, $married, $number_of_kids = 0) { 
    parent::set_values($name, $sex, $married, $number_of_kids); 
} 

を:あなたは、元のものより少ないの引数を取る新しい実装を提供したい場合、あなたはまた、デフォルトの引数を持つことを行うことができますサイドノートとして
、または4つの引数。

もっと複雑な組み合わせの場合は、新しい実装をすべてのパラメータのデフォルト引数(親実装と互換性を持たせるため)で宣言し、func_get_argsを使用して呼び出しを処理またはリダイレクトします。引数の数がちょうど同じであるため、display_valuesをオーバーライド

は、しかし単純です:私はあなたを誤解していない限り

<?php 

class FamilyTree { 

    protected $name; 
    protected $sex; 
    protected $married; 
    protected $number_of_kids; 

    public function display_values() { 
     echo $this->name   . "<br />"; 
     echo $this->sex    . "<br />"; 
     echo $this->married   . "<br />"; 
     echo $this->number_of_kids . "<br />"; 
    } 
} 

class Grandparents extends FamilyTree { 

    public function set_values($name, $sex, $married, $number_of_kids) { 
     $this->name   = $name; 
     $this->sex   = $sex; 
     $this->married  = $married; 
     $this->number_of_kids = $number_of_kids; 
    } 
} 

class Parents extends Grandparents { 

    private $dob; 

    public function set_values($name, $sex, $married, $number_of_kids, $dob = '') { 
     parent::set_values($name, $sex, $married, $number_of_kids); 
     $this->dob = $dob; 
    } 

    public function display_values() { 
     parent::display_values(); 
     echo $this->dob . "<br />"; 
    } 
} 

$gp = new Grandparents(); 
$gp->set_values("James", "Male", 'yes', 5); 

$p = new Parents(); 
$p->set_values("Samuel", "Male", 'yes', 2, '2/5/1974'); 

$gp->display_values(); 
$p->display_values(); 
0

同じでなければならないべきです。これらの2つがなければ、メソッドのオーバーロードとはみなされません。この場合、isはオーバーロードではなく、別のメソッドです。このdisplay_values($ name、$ sex、$ married、$ number_of_kids)で単純にオーバーロードしてすべての値を設定することができます。

+0

それは私がそれを言及した引数を取ることはありません。 –

0

public function display_values() { 
    parent::display_values(); 
    echo $this->dob . "<br />"; 
} 

だからフルで、あなたのコードは次のようになります。この例では、クラスparentの__callを介してset_valuesをオーバーロードしていません。オーバーロードするには、メソッドにアクセスできないようにする必要があります。これは、$ p型> SET_VALUES( "サミュエル"、 "男性"、 'はい'、2 '1974年2月5日')のために 'と呼ばれる' 印刷されません

class Parents extends Grandparents { 

private $dob; 

public function __call($function_name, $arguments) { 
    echo 'called'; 
    if($function_name == 'set_values' && count($arguments) == 5) { 
     $this->$name   = $name; 
     $this->sex   = $sex; 
     $this->married  = $married; 
     $this->number_of_kids = $number_of_kids; 
     $this->dob   = $dob; 
    } 
} 

} ;.親メソッドがアクセス不可能でなければならないメソッドをオーバーライドする

、それはこの例を参照して、引数の数については問題ではありません:

<?php 

class FamilyTree { 

    protected $name; 
    protected $sex; 
    protected $married; 
    protected $number_of_kids; 

    private function display_values() { 
     echo $this->name   . "<br />"; 
     echo $this->sex    . "<br />"; 
     echo $this->married   . "<br />"; 
     echo $this->number_of_kids . "<br />"; 
    } 
} 

class Grandparents extends FamilyTree { 

    private function set_values($name, $sex, $married, $number_of_kids) { 
     $this->name   = $name; 
     $this->sex   = $sex; 
     $this->married  = $married; 
     $this->number_of_kids = $number_of_kids; 
    } 

    private function drawMe($a) 
    {} 

} 

class Parents extends Grandparents { 

    private $dob; 

    public function __call($function_name, $arguments) { 
     echo 'Args: ' . count($arguments); 
     echo ' | Function name: ' . $function_name; 
     if($function_name == 'set_values' && count($arguments) == 5) { 
      $this->$name   = $name; 
      $this->sex   = $sex; 
      $this->married  = $married; 
      $this->number_of_kids = $number_of_kids; 
      $this->dob   = $dob; 
     } 
    } 
} 


$p = new Parents(); 
$p->display_values(); 
echo '<br><br>'; 
$p->set_values("Samuel", "Male", 'yes', 2, '2/5/1974'); 

はこれが印刷されます。

のArgs:0 |関数名:display_values

引数:5 |関数名:set_values

関連する問題