php5支持多态吗?
如果支持最好能上代码说明.
如果不支持请说明原因.

解决方案 »

  1.   

    网上很多讲义PHP面向对象:PHP中的多态2010-07-07多态这个概念,在Java中指的是变量可以指向的对象的类型,可是变量声明类型的子类。对象一旦创建,它的类型是不变的,多态的是变量。在PHP5中,变量的类型是不确定的,一个变量可以指向任何类型的数值、字符串、对象、资源等。我们无法说PHP5中多态的是变量。我们只能说在PHP5中,多态应用在方法参数的类型提示位置。一个类的任何子类对象都可以满足以当前类型作为类型提示的类型要求。所有实现这个接口的类,都可以满足以接口类型作为类型提示的方法参数要求。简单的说,一个类拥有其父类、和已实现接口的身份。
    通过实现接口实现多态下面的例子中,UserAdmin类的静态方法,要求一个User类型的参数。在后面的使用中,传递了一个实现了User接口的类NormalUser的实例。代码成功运行。<?
    interface User{ // User接口
    public function  getName();
    public function setName($_name);
    }class NormalUser implements User { // 实现接口的类.
    private $name;
    public function getName(){
    return $this->name;
    }
    public function setName($_name){
    $this->name = $_name;
    }
    }class UserAdmin{ //操作.
    public static function  ChangeUserName(User $_user,$_userName){
    $_user->setName($_userName);
    }
    }$normalUser = new NormalUser();
    UserAdmin::ChangeUserName($normalUser,"Tom");//这里传入的是 NormalUser的实例.
    echo $normalUser->getName();
    ?>程序运行结果:Tom通过继承关系实现多态下面是类和子类的关系。<?
    class User{ // User接口
    public function  getName(){}
    }class NormalUser extends User { // 继承自User类
    private $name;
    public function getName(){
    return $this->name;
    }
    public function setName($_name){
    $this->name = $_name;
    }
    }class UserAdmin{ //操作.
    public static function  ChangeUserName(User $_user,$_userName){
    $_user->setName($_userName);
    }
    }$normalUser = new NormalUser();
    UserAdmin::ChangeUserName($normalUser,"Tom");//这里传入的是 NormalUser的实例.
    echo $normalUser->getName();
    ?>程序运行结果:Tom
      

  2.   


    第二个例子有点疑惑,假如改一下代码
    NormalUser 增加一个方法sayhelloclass NormalUser extends User { // 继承自User类
    private $name;
    public function getName(){
    return $this->name;
    }
    public function setName($_name){
    $this->name = $_name;
    }
    /*此处为测试新增*/
    public function sayHello($_name) {
    echo 'hello: ' . $_name;
    }
    }在UserAdmin的ChangeUserName方法中加入一句$_user->sayHello($_userName),请问sayHello方法可以正确调用吗?class UserAdmin{ //操作.
    public static function ChangeUserName(User $_user,$_userName){
    $_user->setName($_userName);
    $_user->sayHello($_userName);
    }
    }
      

  3.   

    另外弱弱的问一句,php支持重写吗?如果支持那没问题,如果不支持, 多态又体现在哪里?
      

  4.   

    当然可以, $_user对象有 sayHello()这个方法,而且是public的
      

  5.   

    支持
    http://www.soft6.com/tech/16/169232.html
    http://www.cnblogs.com/ihacklog/archive/2011/08/02/understanding-and-applying-polymorphism-in-php.html
      

  6.   

    看看.谁有PHP开发的学校网络故障报修系统
      

  7.   


    怎么放狗,是指google的意思吗? (汗)
      

  8.   

    在面向对象语言中,接口的多种不同的实现方式即为多态
    它使用了 interface (接口),肯定是多态了
    其实不使用接口,也一样实现多态
      

  9.   

    这篇文章我看了,但是用Rect和Circular自己的引用,调用自己的方法,这叫多态吗?
      

  10.   

    转  
       多态是除封装和继承之外的另一个面向对象的三大特性之一,我个人看来PHP 中虽然可以实现多态,但和C++还有Java 这些面向对象的语言相比,多态性并不是那么突出    多态的应用 
        多态是除封装和继承之外的另一个面向对象的三大特性之一,我个人看来PHP 中虽然可以实现多态,但和C++还有Java 这些面向对象的语言相比,多态性并不是那么突出,因为PHP本身就是一种弱类型的语言,不存在父类对象转化为子类对象或者是子类对象转化为父类对象的问题,所以多态的应用并不是那么的明显;所谓多态性是指一段程序能够处理多种类型对象的能力,比如说在公司上班,每个月财务发放工资,同一个发工资的方法,在公司内不同的员工或是不同职位的员工,都是通过这个方法发放的,但是所发的工资都是不相同的。 所以同一个发工资的方法就出现了多种形态。对于面向对象的程序来说,多态就是把子类对象赋值给父类引用,然后调用父类的方法,去执行子类覆盖父类的那个方法,但在PHP 里是弱类型的,对象引用都是一样的不分父类引用,还是子类引用。 
        我们现在来看一个例子,首先还是要使用多态就要有父类对象和子类对象的关系。做一个形状的接口或是抽象类做为父类,里面有两个抽象方法,一个求周长的方法,另一个是求面积的方法;这接口的子类是多种不同的形状,每个形状又都有周长和面积,又因为父类是一个接口,所以子类里面就必须要实现父类的这两个周长和面积的抽象方法,这样做的目的是每种不同形状的子类都遵守父类接口的规范,都要有求周长和求面积的方法。     代码如下:<? 
    //定义了一个形状的接口,里面有两个抽象方法让子类去实现 
    interface Shape{ 
    function area(); 
    function perimeter(); 

    //定义了一个矩形子类实现了形状接口中的周长和面积 
    class Rect implements Shape{ 
    private $width; 
    private $height; 
    function __construct($width, $height){ 
    $this->width=$width; 
    $this->height=$height; 

    function area(){ 
    return "矩形的面积是:".($this->width*$this->height); 

    function perimeter(){ 
    return "矩形的周长是:".(2*($this->width+$this->height)); 


    //定义了一个圆形子类实现了形状接口中的周长和面积 
    class Circular implements Shape{ 
    private $radius; 
    function __construct($radius){ 
    $this->radius=$radius; 

    function area(){ 
    return "圆形的面积是:".(3.14*$this->radius*$this->radius); 

    function perimeter(){ 
    return "圆形的周长是:".(2*3.14*$this->radius); 


    //把子类矩形对象赋给形状的一个引用 
    $shape=new Rect(5, 10); 
    echo $shape->area()."<br>"; 
    echo $shape->perimeter()."<br>"; 
    //把子类圆形对象赋给形状的一个引用 
    $shape=new Circular(10); 
    echo $shape->area()."<br>"; 
    echo $shape->perimeter()."<br>"; 
    ?> 上例执行结果: 
    执行结果 
    矩形的面积是:50 
    矩形的周长是:30 
    圆形的面积是:314 
    圆形的周长是:62.8 通过上例我们看到,把矩形对象和圆形对象分别赋给了变量$shape,调用$shape 引用中的面积和周长的方法,出现了不同的结果,这就是一种多态的应用,其实在我们PHP 这种弱类形的面向对象的语言里面,多态的特性并不是特别的明显,其实就是对象类型变量的变项应用。
      

  11.   

    php5 引入接口(interface)一是为了与其他语言保持一致
    二是从语法上保证作为接口的方法一定会被定义,当不使用 interface 时,就需要自行保证了
      

  12.   

    知道你什么意思, 
    但是,$shape这个变量, 他=new Rect之后,
    你一样可以看作它interface Shape的一个引用啊在c++里,只不过一个指针变量显式地定义了它指向了父类,你就觉得它一直指向父类的引用,
    但实际上在运行时,它一样是指向了某个子类啊换句话说,你把$shape这个变量看作一个interface Shape的指针,然后它在运行时指向了该interface的不同实现,那不就一样了吗?欢迎继续讨论
      

  13.   


    怎么能看成是interface Shape的指针呢,"看成",不能是看成啊,代码怎么实现?
      

  14.   

    多重继承 是儿子可以有多个老子,同时继承多个血统目前 php 不支持这种乱伦的继承
      

  15.   

    现在讨论的是php是否支持多态!
      

  16.   

    讨论之前你首先得告诉我们你对多态是怎么理解的,怎么算支持,怎么算不支持,在我看来php天生就是多态型选手。
    我这里对多态的理解基本是基于wiki百科上的描述
    http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
    这篇科普文有概念描述,有设计目的,有举例,比如c++的操作符重载,+号碰到integer类型的就是数学概念上的相加,碰到chars类型的就是字符串拼接,这就是同一个符号+表现出多种操作形态。下面还有java,python的例子,php怎么就算不支持呢?
      

  17.   

    下面是百度百科的解释:
    多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态性在Object Pascal和C++中都是通过虚函数(Virtual Function) 实现的。你仔细看这句话:允许将子类类型的指针赋值给父类类型的指针, php允许吗? php是弱类型的根本不存在这么一说.
      

  18.   

    你要这么说,那php就歇菜,php世界里根本没有指针一说,但是我得说,OO只是一种思想,不应该局限于不同语言的语法或者对同一类型问题的不同解决方式,所谓条条大路通罗马。
    而且我在你引用百度百科解释里还有一句话
    在面向对象语言中,接口的多种不同的实现方式即为多态
    你又怎么看?你认为php不支持接口设计吗?允许将子类类型的指针赋值给父类类型的指针
    你不妨用C++的实现方式写出来,看php能不能做到类似的设计。
      

  19.   


    没说php有指针啊,引用有吧,
    1.php中你可拿到一个接口类型的引用吗?
    2.不用试了,php做不到,只能做到接口的实现类的引用,或者是拿子类的引用
    拿接口的实现类引用或子类的引用 调用自己的方法就叫多态吗?(这跟没有接口的调用有什么区别?)
      

  20.   

    拿接口的实现类引用或子类的引用 调用自己的方法就叫多态吗?(这跟没有接口的调用有什么区别?)
    那就是接口实现方法和方法重载以及方法覆盖的区别了,这对于所有语言都是一样的吧。
    这个我贴的那个wiki页面正好有说到。
    所以你意思是拿父类/接口的引用调用自己的方法才叫多态?
    我给你的维基链接里有个java/python的例子,你认为那个能证明java/python支持多态不?
    还有弱类型语言本身类型就是隐性多态的,所以你在php可以strlen(1)得到结果1.
    你所谓的php拿接口类型引用是个啥意思
    我觉得最好不要陷入语法层来讨论设计层问题。
    或者最好是你写个简单php例子来说明自己的论点,这样大家不会把时间浪费在对语义的理解上,而且中文对于国外技术名词的解释有时候实在不知道怎么理解好,还不如自己去啃英文理解得快。
      

  21.   


    //定义接口InterA  
    interface InterA  
    {  
    void fun();  
    }  
    //实现接口InterA的类B  
    class B implements InterA  
    {  
    public void fun()  
    {      
    System.out.println(“This is B”);  
    }  
    }  
    //实现接口InterA的类C  
    class C implements InterA  
    {  
    public void fun()  
    {      
    System.out.println(“This is C”);  
    }  
    }  
    class Test  
    {  
    public static void main(String[] args)  
    {  
    InterA  a;  
    a= new B();  
    a.fun();   
    a = new C();   
    a.fun();   
    }  
    }  我说的就是InterA  a
      

  22.   

    strlen是多态的?这个体现在哪里?
      

  23.   

    不是strlen是多态,是类型'多态',strlen手册明明写了接收的参数类型是string,为什么传一个integer进去也能得到结果,这就是弱类型的特征,解释器会帮你按照上下文将实参转成正确的类型,这是php实现多态的基础,也应该是弱类型语言实现多态的基础。
    按照你给的java代码,InterA  a;是强类型实现多态的方式,没办法,每个变量都有类型,而且事先就要定义类型,这都没问题,最重要的是这段代码核心的东西我觉得是,a始终是InterA类型,但是可以拥有B的特性,也可以拥有C的特性,同一个物件可以以多种形态出现,这叫多态。但是弱类型的php实现方式不是这样,你赋什么类型给一个变量,那么变量当前就是这个类型。我觉得这个属于"茴"字有几种写法的问题,属于语法层,真正重要的多态可以让你实现什么样的设计,你为什么觉得php满足不了。有人用C都可以OOP呢。
      

  24.   

    JAVA://定义接口Animal  
    interface Animal  
    {  
        void Talk();  
    }  
    //实现接口Animal的Dog  
    class Dog implements Animal  
    {  
        public void Talk()  
        {          
            System.out.println("WongWong");  
        }   
    }  
    //实现接口Animal的类Cat  
    class Cat implements Animal  
    {  
        public void Talk()  
        {          
            System.out.println("Miao");  
        }   
    }  
    class Test  
    {  
        public static void main(String[] args)  
        {   
            Animal  a;  
            a= new Dog();  
            a.Talk();   
            a = new Cat();   
            a.Talk();
        }   
    }  PHP:
    <?php
    //定义接口Animal  
    interface Animal  
    {  
        public function Talk();  
    }  
    //实现接口Animal的Dog  
    class Dog implements Animal  
    {  
        public function Talk()  
        {          
            echo("WongWong");  
        }   
    }  
    //实现接口Animal的类Cat                                                                                                                     
    class Cat implements Animal  
    {  
        public function Talk()  
        {          
            echo("Miao");  
        }   
    }  
    $a = new Dog();  
    $a->Talk();   
    $a = new Cat();   
    $a->Talk();
    ?>
    瞧他们多像啊,不能因为我类型弱就说我不够多态啊。
      

  25.   

    呵呵,最近发觉我喜欢和人争论,不知道为啥,纯粹闲的。
    希望更多人参与进来,咱们群P.
    感觉LZ的帖子,能引起争论的帖子就是好帖子。
      

  26.   

    通过实现接口实现多态
    下面的例子中,UserAdmin类的静态方法,要求一个User类型的参数。
    在后面的使用中,传递了一个实现了User接口的类NormalUser的实例。代码成功运行。
    01
    <?
    02
    interface User{ // User接口
    03
        public function  getName();
    04
        public function setName($_name);
    05
    }
    06
     
    07
    class NormalUser implements User { // 实现接口的类.
    08
        private $name;
    09
        public function getName(){
    10
            return $this->name;
    11
        }
    12
        public function setName($_name){
    13
            $this->name = $_name;
    14
        }
    15
    }
    16
     
    17
    class UserAdmin{ //操作.
    18
        public static function  ChangeUserName(User $_user,$_userName){
    19
            $_user->setName($_userName);
    20
        }
    21
    }
    22
     
    23
    $normalUser = new NormalUser();
    24
    UserAdmin::ChangeUserName($normalUser,"Tom");//这里传入的是 NormalUser的实例.
    25
    echo $normalUser->getName();
    26
    ?>
    程序运行结果:
    1
    Tom
    通过继承关系实现多态
    下面是类和子类的关系。
    01
    <?
    02
    class User{ // User接口
    03
        public function  getName(){}
    04
    }
    05
     
    06
    class NormalUser extends User { // 继承自User类
    07
        private $name;
    08
        public function getName(){
    09
            return $this->name;
    10
        }
    11
        public function setName($_name){
    12
            $this->name = $_name;
    13
        }
    14
    }
    15
     
    16
    class UserAdmin{ //操作.
    17
        public static function  ChangeUserName(User $_user,$_userName){
    18
            $_user->setName($_userName);
    19
        }
    20
    }
    21
     
    22
    $normalUser = new NormalUser();
    23
    UserAdmin::ChangeUserName($normalUser,"Tom");//这里传入的是 NormalUser的实例.
    24
    echo $normalUser->getName();
    25
    ?>
    程序运行结果:
    view sourceprint?
    1
    Tom
      

  27.   

    本帖最后由 PhpNewnew 于 2012-04-28 10:26:13 编辑
      

  28.   

    如果非要将 允许将子类类型的指针赋值给父类类型的指针 作为多态的标准,那么 php 就不能算是支持多态了。因为 $this 不能重新指派,并且 php 也没有指针
    注意到前面还有 多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作
    只要父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作就可以说是支持多态了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();由于不习惯 php5 的格式,采用了 php4 的格式
      

  29.   


    增加一个类//注意没有继承自 Animal 
    class Pig {
      var $voice = '哼';
    }$a = new Animal;  
    $a->Talk();   $a->signal(new Cat);
    $a->Talk();$a->signal(new Dog);
    $a->Talk();
    // 注意这句
    $a->signal(new Pig);
    $a->Talk();
    这算多态吗?
      

  30.   

    http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
    其实这个里面说的很清楚了,Subtype polymorphism is the ability to create a variable, a function, or an object that has more than one form. php能吗? 很显然是可以的
      

  31.   

    不知道楼主还是否纠结....楼上哪吒说得够清楚明白了,46楼的代码也足够有说服力,如果还嫌类型不够清楚,也可以用Type Hinting的方法指明参数类型,这样几乎就可以说和c++里一模一样了. 另外也可以用is_a来测试变量的类型.楼主39楼引用的"引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。"Charlie Calverts说的是前面一句"多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作"后面这个"简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针"是某人的简单化(很C++化)的描述,而且只说出了Charlie Calverts原话的前半句. 实际上更重要的是后半句: "父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作"从他原话来看,php的多态的实现毫无问题. 
    楼主却偏偏用红字突出了简化的不完整的描述....
      

  32.   

    php5 有abstract关键字哦,足以说明多态了吧!
      

  33.   

    ex:
    abstract class A
    {
    abstract function show();
    }class B extends A
    {
    function show(){
    echo 'B';
    }
    }
    $obj = new B();
    $obj->show();
      

  34.   


    多继承过于复杂, 有副作用,
    所以包括Java等语言都是用interface来部分实现...
      

  35.   

    我第一次写PHP,至少PHP5肯定是有多态的,或者是有些人说的弱类型云云,Duck Typing也是多态。
    什么叫多态?基类能调用派生类的方法就是多态,你管它强弱类型呢
      

  36.   

    74楼说的好,基类能调用派生类的方法就是多态,楼主不要纠结php是否有指针的问题了,目的达到就可以,java有java的路,php有php的路,方式不一样,最终结果是一样的
      

  37.   

    明显是可以做到的,那些概念性东西,都不仅仅是拘泥一些特定的语法。只要你的代码逻辑符合了某些概念的理念,就可以说它是支持了。php有class、有继承、有interface、有abstruct,它为什么不能实现多态?就像有些人会可笑的问,xx语言支持MVC吗?问这个问题的人显然不清楚MVC到底是什么。不过有些特性,的确某些语言不原生支持。比如方法重载在php中就不像cpp和java中被原生支持,但却可以用php的魔术方法来模拟,所以我也可以说,php支持方法重载。