php是否支持多态,PHP中关于多态的疑问

本文探讨了面向对象编程中的多态概念,通过代码示例展示了如何在PHP中实现多态。第一个例子使用`instanceof`关键字判断对象类型并调用相应的方法,而第二个例子则通过继承和重写父类方法来实现多态。作者还引用了一个论坛讨论,解释了代码中的动态绑定和对象覆盖现象,并讨论了多态的关键在于相同的接口和不同的实现。
摘要由CSDN通过智能技术生成

维基百科中关于多态有一个定义: 在面向对象语言中,接口的多种不同的实现方式即为多态

文中给出了两个代码示例,其中用流程控制的代码段如下

class painter{ //定义油漆工类 public function paintbrush(){ //定义油漆工动作 echo "油漆工正在刷漆!n"; } } class typist{ //定义打字员类 public function typed(){ //定义打字员工作 echo "打字员正在打字!n"; } } function printworking($obj){ //定义处理类 if($obj instanceof painter){ //若对象是油漆工类,则显示油漆工动作 $obj->paintbrush(); }elseif($obj instanceof typist){ //若对象是打字员类,则显示打字员动作 $obj->typed(); }else{ //若非以上类,则显示出错信息 echo "Error: 对象错误!"; } } printworking(new painter()); //显示员工工作 printworking(new typist()); //显示员工工作

为了展示多态,下文又给出使用多态的代码段:

class employee{//定义员工父类 protected function working(){//定义员工工作,需要在子类的实现 echo "本方法需要在子类中重载!"; }}class painter extends employee{//定义油漆工类 public function working(){//实现继承的工作方法 echo "油漆工正在刷漆!n"; }}class typist extends employee{//定义打字员类 public function working(){ echo "打字员正在打字!n"; }}class manager extends employee{//定义经理类 public function working(){ echo "经理正在开会!"; }}function printworking($obj){//定义处理方法 if($obj instanceof employee){//若是员工对象,则显示其工作状态 $obj->working(); }else{//否则显示错误信息 echo "Error: 对象错误!"; }}printworking(new painter());//显示油漆工的工作printworking(new typist());//显示打字员的工作printworking(new manager());//显示经理的工作

后一个代码是统一了不同子类之间的方法名来实现多态,这是否是个多态的正确示例呢?如果是的,那么是否可以理解为,继承某个抽象类的所有子类相对于抽象父类来说都是多态的?

另外在论坛的另一个讨论贴中(http://bbs.csdn.net/topics/390025104),55L的xuzuning老师给出了一个代码示例:

class Animal { var $voice = '未定义'; var $root; function __construct() { $this->root = $this; } function signal($o) { $this->root = $o; } function Talk() { echo $this->root->voice; }} class Cat extends Animal { var $voice = '喵';} class Dog extends Animal { var $voice = '汪汪';} $a = new Animal; $a->Talk(); $a->signal(new Cat);$a->Talk(); $a->signal(new Dog);$a->Talk();

这段代码中的变量$a最先声明为Animal父类的示例,所以输出是“未定义”,之后又声明为子类Cat和Dog,那么声明Cat时变量$a指向到Cat的实例上去了,所以调用$a->talk()实际上就是调用Cat的talk。同理,$a声明为Dog的实例时又把cat对象覆盖掉了。xuzuning老师在帖中说 父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作,但这段代码看不出$a调用talk方法是经过父类这一步的,而是新的对象覆盖了前一个对象,调用的完全是新对象的方法。那么xuzuning老师的这个代码示例是否是不恰当的呢?

最近一直对多态的具体实践迷惑不解,有的文章中提到需要强制类型定义,有的在示例代码中用到了 instanceof关键字来判断是否继承于某个类。哪位老师能给出一个清晰的定义及代码示例并解答上述代码示例是否是多态的实践呢?

回复讨论(解决方案)

例子都行, 第一个更典型, 父类里最好是虚函数以确保子类实现.

多态的关键是 “相同的接口”, “不同的实现”, 别的细节不要纠结….

例子都行, 第一个更典型, 父类里最好是虚函数以确保子类实现.

多态的关键是 “相同的接口”, “不同的实现”, 别的细节不要纠结….

多谢helloyou0老师,PHP中有虚函数吗?

悟性 悟性 悟性….

这有点像佛经里的东西 看你怎么悟 概念就抽象 用抽象的方法来描述抽象具体行为…嘿嘿

但这段代码看不出$a调用talk方法是经过父类这一步的,而是新的对象覆盖了前一个对象,调用的完全是新对象的方法。 你 print_r($a); 一下就知道谁是谁了

虚函数有人说是静态延迟绑定,我看比较像。抽象函数为什么能保证子类的实现呢?

引用 楼主 chenlong451 的回复:但这段代码看不出$a调用talk方法是经过父类这一步的,而是新的对象覆盖了前一个对象,调用的完全是新对象的方法。你 print_r($a); 一下就知道谁是谁了

xuzuning老师来了,非常感谢你的提示。

print_r后的结果是

Animal Object ( [voice] => 未定义 [root] => Dog Object ( [voice] => 汪汪 [root] => Dog Object *RECURSION* ) )

竟然变成对象数组了,并且保留了父类中的voice静态属性。这是怎么回事呢?为什么不是覆盖呢?

为什么是覆盖呢?

说说你的理由

为什么是覆盖呢?

说说你的理由

明白了,阅读代码不仔细。惭愧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值