PHP面向对象之旅:方法覆盖

让子类拥有更多方法
服务器君一共花费了505.984 ms进行了7次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(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. <br>";
echo $dog->yaff() ."<br>".$dog->run();
echo  "<br><br>";
//这是我的小狗叫"狗狗",它很小.不会汪汪叫,只会哼哼哼..
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. <br>";
echo $myDog->yaff() ."<br>".$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;
	}	
}
/*
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

父类为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<br>";
	}
}
class Dog1 extends Animal {
	public function __construct(){
		$this->legNum = 4;
		echo "I am a Dog .<br>";
	}
}
$dog1 = new Dog1();
echo "<br>";
echo  "legNum is ".$dog1->legNum;
/*
实例化子类时.构造函数被调用了.
*/
?>

程序运行结果:

I am a Dog .
legNum is 4

注:这点和Java不同,在java中构造函数是不能被继承的,而且子类实例化时,子类的构造函数被调用,父类的构造函数也会调用。

延伸阅读

此文章所在专题列表如下:

  1. PHP面向对象之旅:类和对象
  2. PHP面向对象之旅:类的属性
  3. PHP面向对象之旅:类的方法
  4. PHP面向对象之旅:对象的比较
  5. PHP面向对象之旅:构造函数
  6. PHP面向对象之旅:类的继承
  7. PHP面向对象之旅:访问控制
  8. PHP面向对象之旅:方法覆盖
  9. PHP面向对象之旅:this关键字
  10. PHP面向对象之旅:parent::关键字
  11. PHP面向对象之旅:再谈重载
  12. PHP面向对象之旅:获取用户数据
  13. PHP面向对象之旅:用户权限管理类
  14. PHP面向对象之旅:static变量与方法
  15. PHP面向对象之旅:单例模式
  16. PHP面向对象之旅:final类和方法
  17. PHP面向对象之旅:PHP中的常量
  18. PHP面向对象之旅:抽象类
  19. PHP面向对象之旅:抽象方法
  20. PHP面向对象之旅:抽象类继承抽象类
  21. PHP面向对象之旅:静态抽象方法
  22. PHP面向对象之旅:模板模式
  23. PHP面向对象之旅:接口与抽象方法
  24. PHP面向对象之旅:接口的实现
  25. PHP面向对象之旅:接口的继承
  26. PHP面向对象之旅:类型提示
  27. PHP面向对象之旅:PHP的多态
  28. PHP面向对象之旅:instanceof运算符
  29. PHP面向对象之旅:接口与组合模拟多继承
  30. PHP面向对象之旅:一个接口实例
  31. PHP面向对象之旅:简单工厂模式

本文地址:http://www.nowamagic.net/librarys/veda/detail/1089,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/1089

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《敏捷软件开发(原则模式与实践)》 马丁 (作者), 邓辉 (译者)

《敏捷软件开发:原则模式与实践》由享誉全球的软件开发专家和软件工程大师Robert C.Martin将向您展示如何解决软件开发人员、项目经理及软件项目领导们所面临的最棘手的问题。这本综合性、实用性的敏捷开发和极限编程方面的指南,是由敏捷开发的创始人之一所撰写的。1.讲述在预算和实践要求下,软件开发人员和项目经理如何使用敏捷开发完成项目;2.使用真实案例讲解如何用极限编程来设计、测试、重构和结对编程;3.包含了极具价值的可多次使用的C++和JAVA源代码;4.重点讲述了如何使用UML和设计模式解决面向客户系统的问题。

更多计算机宝库...