天天看點

php方法重載方法重寫_PHP面向對象之旅:方法覆寫

如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆寫(override),也稱為方法的重載。

當對父類的方法進行重寫時,子類中的方法必須和父類中對應的方法具有相同的方法名稱,在PHP5中不限制輸入參數類型、參數數量和傳回值類型。(這點和Java不同)。

子類中的覆寫方法不能使用比父類中被覆寫方法更嚴格的通路權限。

聲明方法時,如果不定義通路權限。預設權限為public。

PHP5重寫方法

先設定一個父類,這個父類是 “Dog”類,這個類描述了dog的特性。

Dog有2個眼睛,會跑,會叫。就這樣描述先。

我養了一直狗,是隻小狗,符合Dog類的特性,但有所不同。

我的小狗有名字,我的小狗太小了,不會大聲的叫,隻會哼哼。

我們用繼承的概念去實作這個設計。

// 狗有兩隻眼睛,會汪汪叫,會跑.

class Dog {

protected $eyeNumber =2; //屬性

//傳回封裝屬性的方法.

public function getEyeNumber(){

return $this->eyeNumber;

}

//狗會叫

public function yaff(){

return "Dog yaff, wang ..wang ..";

}

//狗會跑

public function run(){

return "Dog run..running ...";

}

}

$dog = new Dog();

echo "dog have ".$dog->getEyeNumber()." eyes.

";

echo $dog->yaff() ."

".$dog->run();

echo "

";

//這是我的小狗叫"狗狗",它很小.不會汪汪叫,隻會哼哼哼..

class MyDog extends Dog {

private $name = "狗狗";

public function getName(){

return $this->name;

}

public function yaff(){

return $this->name." yaff, heng...heng ..";

}

}

$myDog = new MyDog();

echo $myDog->getName()." have ".$myDog->getEyeNumber()." eyes.

";

echo $myDog->yaff() ."

".$myDog->run();

?>

程式運作結果:

dog have 2 eyes.

Dog yaff, wang ..wang ..

Dog run..running ...

狗狗 have 2 eyes.

狗狗 yaff, heng...heng ..

Dog run..running ...

重寫方法與通路權限

子類中的覆寫方法不能使用比父類中被覆寫方法更嚴格的通路權限。

父類為public 子類為 private時。

// 簡化dog類和mydog類,示範重寫的通路權限.

class Dog {

protected $eyeNumber =2; //屬性

//傳回封裝屬性的方法.

public function getEyeNumber(){

return $this->eyeNumber;

}

}

class MyDog extends Dog {

protected function getEyeNumber(){

return $this->eyeNumber;

}

}

?>

程式運作結果:

Fatal error: Access level to MyDog::getEyeNumber() must be public (as in class Dog) in E:\PHPProjects\test.php on line 15

父類為public 子類為 protected時。

// 簡化dog類和mydog類,示範重寫的通路權限.

class Dog {

protected $eyeNumber =2; //屬性

//傳回封裝屬性的方法.

public function getEyeNumber(){

return $this->eyeNumber;

}

}

class MyDog extends Dog {

private function getEyeNumber(){

return $this->eyeNumber;

}

}

?>

程式運作結果:

Fatal error: Access level to MyDog::getEyeNumber() must be public (as in class Dog) in E:\PHPProjects\test.php on line 15

重寫時的參數數量

子類可以擁有與父類不同的參數數量。(這點與java不同,PHP是弱類型語言。)

// 簡化dog類和mydog類,示範重寫方法的參數.

class Dog {

protected $eyeNumber =2; //屬性

//傳回封裝屬性的方法.

public function getEyeNumber(){

return $this->eyeNumber;

}

}

class MyDog extends Dog {

//重寫的方法與父類的方法有不同的參數數量.

public function getEyeNumber($eys){

$this->eyeNumber = $eys;

return $this->eyeNumber;

}

}

$myDog = new MyDog();

echo "my dog hava ".$myDog->getEyeNumber(3) ." eyes.";

//嘯天犬..哈..

//下面這句會報一個丢失參數的錯誤.

//echo "my dog hava ".$myDog->getEyeNumber() ." eyes.";

?>

程式運作結果:

my dog hava 3 eyes.

構造函數重寫

下面這個例子中,父類和子類都有自己的構造函數,當子類被執行個體化時,子類的構造函數被調用,而父類的構造函數沒有被調用,請對比第一節的構造函數繼承。

//2-2 / extends1.php

//構造函數繼承的問題.

class Animal{

public $legNum = 0;

public function __construct(){

$this->legNum = 4;

echo "I am an animal

";

}

}

class Dog1 extends Animal {

public function __construct(){

$this->legNum = 4;

echo "I am a Dog .

";

}

}

$dog1 = new Dog1();

echo "

";

echo "legNum is ".$dog1->legNum;

?>

程式運作結果:

I am a Dog .

legNum is 4

注:這點和Java不同,在java中構造函數是不能被繼承的,而且子類執行個體化時,子類的構造函數被調用,父類的構造函數也會調用。

延伸閱讀

此文章所在專題清單如下: