开发者

Is there any polymorphism in PHP?

Suppose both base and son class hav开发者_运维问答e a method method_1,

and there's another method method_2 of base.

inside base::method_2,how can I point $this->method_1 to base::method_1 no matter whether $this is a instance of base or son?


If I understand you correctly, you want something like this:

<?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();

where the call to method2 would always use the base version of the method1.

The best way I could do it is as above, but this code won't work since base has no parent. I'm pretty sure what you're trying to do isn't possible.

This is the error you will get:

PHP Fatal error:  Cannot access parent:: when current class scope has no parent in 


This will do what you want. Props to dbers for the example code (even if his didn't quite work).

<?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();

?>

Outputs:

base has no parent
base::method1
son has parent
base::method1


Make the function private:

<?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();
?>

The output is:

A::foo()
B::bar()


Yes it does. It's singular (one parent).

son->method_1 can add to or override ALL of base->method_1 functionality.

son->method_1 can simply add an additional function, and utilize the rest of the functionality of it's parent's instance of method_1

So calling $this->method_1 would use base->method_1, and son->method_1 as long as what you want to use from base isn't overridden in son.


If you call a method that doesn't exist in your subclass, PHP will traverse the class hierarchy until it finds an ancestor class which implements the function you want. This means that if your son class doesn't implement method_2, PHP will automatically look for the nearest ancestor which does. In your case, it will call method_2 of base as you want.

If you are overriding the method_2 in your son class, and you want to do your own implementation of method_2 and also call the base::method_2 implementation then you can use the parent keyword:

class son extends base {
  public function method_2() {
    parent::method_2();
    //do son::method_2()-specific stuff here
  }
}

You can't chain parent calls together, so if base was a subclass of GrandparentClass you couldn't do something like this:

parent::parent::method_2(); // trying to call grandparent::method_2
                            // but this call will fail

But you can directly refer to ancestor classes by name, so this would work:

GrandparentClass::method_2();

And just to take it a little further, there is also a function called class_parents() which returns an array of every ancestor class your class inherits from. This could help if you wanted to go back, say, two ancestors, but you didn't know its specific name for some reason, you could still call the function using eval().

For example, this code would call GrandparentClass::method_2() without directly referencing the class by name in your code:

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

Hope that helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜