PHP中是否存在多态性?

PHP中是否存在多态性?,php,oop,polymorphism,Php,Oop,Polymorphism,假设base和son类都有一个方法method_1 还有另一种方法method\u2的base 在base::method_2内部,我如何将$this->method_1指向base::method_1,无论$this是base还是son的一个实例 <?php class base { public function method1() { echo "base:method1\n"; } public function method2() { if(get_

假设
base
son
类都有一个方法
method_1

还有另一种方法
method\u2
base


base::method_2
内部,我如何将
$this->method_1
指向
base::method_1
,无论
$this
base
还是
son
的一个实例

<?php

class base {
  public function method1() {
    echo "base:method1\n";
  }
  public function method2() {
    if(get_class($this) == 'base') {
      $this->method1();
    }
    else {
      parent::method1();
    }
    echo "base:method2\n";
  }
}



class son extends base {
  public function method1() {
    echo "son:method1\n";
  }
}


$obj = new son();

$obj->method2();
parent::parent::method_2(); // trying to call grandparent::method_2
                            // but this call will fail

将函数设置为私有:

<?php
class A
{
  public function __construct()
  {
    $this->foo();
    $this->bar();    
  }

  private function foo() { echo "A::foo()\n"; }
  public function bar() { echo "A::bar()\n"; }
}

class B extends A
{
  public function foo() { echo "B::foo()\n"; }
  public function bar() { echo "B::bar()\n"; }
}

new B();
?>

是的。它是单数的(单亲)

son->method_1
可以添加或覆盖所有
base->method_1
功能

son->method_1
只需添加一个附加函数,并利用其父实例
method_1


因此调用
$this->method\u 1
将使用
base->method\u 1
,并且
son->method\u 1
,只要您希望从base使用的内容在子类中没有被覆盖。

如果您调用子类中不存在的方法,PHP将遍历类层次结构,直到找到实现所需函数的祖先类。这意味着,如果您的
son
类没有实现
方法2
,PHP将自动查找最近的祖先。在您的情况下,它将根据需要调用
base
method_2

如果您在您的
子类中重写
方法2
,并且您希望自己实现
方法2
,同时调用
基::方法2
实现,那么您可以使用
父类
关键字:

class son extends base {
  public function method_2() {
    parent::method_2();
    //do son::method_2()-specific stuff here
  }
}
您不能将
parent
调用链接在一起,因此,如果
base
祖父母类的子类,则无法执行以下操作:

<?php

class base {
  public function method1() {
    echo "base:method1\n";
  }
  public function method2() {
    if(get_class($this) == 'base') {
      $this->method1();
    }
    else {
      parent::method1();
    }
    echo "base:method2\n";
  }
}



class son extends base {
  public function method1() {
    echo "son:method1\n";
  }
}


$obj = new son();

$obj->method2();
parent::parent::method_2(); // trying to call grandparent::method_2
                            // but this call will fail
但您可以通过名称直接引用祖先类,因此这将起作用:

GrandparentClass::method_2();
更进一步说,还有一个名为
class\u parents()
的函数,它返回类继承自的每个祖先类的数组。如果您想返回(例如)两个祖先,但由于某种原因不知道其具体名称,这可能会有所帮助,您仍然可以使用
eval()
调用该函数

例如,此代码将调用
grandrentclass::method_2()
,而无需在代码中按名称直接引用类:

$parents = class_parents($this);
eval(end($parents) . "::method_2();");

希望有帮助

这将满足您的需求。为dbers提供示例代码的道具(即使他的代码不太有效)


你说的这个经典是什么?为什么你希望PHP遵守它?你说的不是多态性。忽略子类对方法的重新实现?你为什么要这么做?@meagar,我同意。如果您不想覆盖它,它应该是
private
final
。您应该将问题的标题编辑为“PHP OOP层次结构问题”或“如何绕过继承-PHP OOP”。。。目前的情况令人误解。
<?php

class base {
  public function method1() {
    echo "base::method1\n";
  }
  public function method2() {
    if (get_parent_class($this) === FALSE) {
      echo get_class($this)." has no parent\n";
      $this->method1();
    } else {
      echo get_class($this)." has parent\n";
      call_user_func(array(get_parent_class($this), 'method1'));
    }
  }
}

class son extends base {
  public function method1() {
    echo "son::method1\n";
  }
}

$b = new base();
$b->method2();

$s = new son();
$s->method2();

?>
base has no parent
base::method1
son has parent
base::method1