#19376 [NEW]: Class inheritance problem
| From: | shamim at poetryunlimited dot com | Date: | Thu, 12 Sep 2002 18:05:53 +0000 |
| Subject: | #19376 [NEW]: Class inheritance problem | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-19253@lists.php.net to get a copy of this message | ||
From: shamim@poetryunlimited.com
Operating system: Linux/Windows NT 4
PHP version: 4.2.2
PHP Bug Type: Scripting Engine problem
Bug description: Class inheritance problem
Should I be able to do the following?
In the example below, class test1 is a base class for test2 which is a
base class for test3.
In an object of type test1, if I call the class method test3::showMe, I
would expect the class method test3::showMe would be called. This class
method (not member function) would would have no class context ($this),
since objects of type test1 do not have a member function test3::showMe.
This call should therefore fail at the debug call.
Instead, the call traverses up to test3, and the recursive parent::showMe
calls reverse the traversal back to the class test1, even though class
test1 has no knowledge of class test3 or class test2. Or so it should be.
And for some reason the $this variable exists at every level. Even though
objects of type test1 do not have any test3 or test2 object contexts.
I think the polymorphism is broken. Thanks.
Code follows.
===========================================================
<?php
Header("Content-Control: no-cache");
Header("Pragma: no-cache");
function debug(&$obj,$msg)
{
echo "$msg<br><pre>";var_dump($obj);echo
"</pre><hr>\n";
}
class test1
{
var $a;
function test1() {$this->a=0;debug($this,"test1->new");}
function setA() {$this->a+=1;debug($this,"test1->setA");}
function display() {debug($this,"test1->display");echo
$this->a."<br>\n";}
function callMe()
{debug($this,"test1->callMe");test3::showMe();}
function showMe()
{debug($this,"test1->showMe");$this->display();}
}
class test2 extends test1
{
function test2()
{debug($this,"test2->new");$p=get_parent_class($this);parent::$p();}
function display()
{debug($this,"test2->display");parent::display();}
function showMe()
{debug($this,"test2->showMe");parent::showMe();}
}
class test3 extends test2
{
function test3()
{debug($this,"test3->new");$p=get_parent_class($this);parent::$p();}
function display()
{debug($this,"test3->display");parent::display();}
function showMe()
{debug($this,"test3->showMe");parent::showMe();}
}
$b=new test2();
$b->setA();
$c=new test1();
$c->setA();
$a=new test1();
$a->showMe();
$a->callMe();
$a->setA();
$a->showMe();
$a->callMe();
$a->setA();
$a->showMe();
$a->callMe();
$a=new test2;
$a->showMe();
$a->callMe();
$a->setA();
$a->showMe();
$a->callMe();
$a->setA();
$a->showMe();
$a->callMe();
/*
Results:
test2->new
object(test2)(1) {
["a"]=>
NULL
}
--------------------------------------------------------------------------------
test1->new
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test1->setA
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test1->new
object(test1)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test1->setA
object(test1)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test1->new
object(test1)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test1->showMe
object(test1)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test1->display
object(test1)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
0
test1->callMe
object(test1)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test3->showMe
object(test1)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test2->showMe
object(test1)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test1->showMe
object(test1)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test1->display
object(test1)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
0
test1->setA
object(test1)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test1->showMe
object(test1)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test1->display
object(test1)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
1
test1->callMe
object(test1)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test3->showMe
object(test1)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test2->showMe
object(test1)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test1->showMe
object(test1)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test1->display
object(test1)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
1
test1->setA
object(test1)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test1->showMe
object(test1)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test1->display
object(test1)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
2
test1->callMe
object(test1)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test3->showMe
object(test1)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test2->showMe
object(test1)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test1->showMe
object(test1)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test1->display
object(test1)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
2
test2->new
object(test2)(1) {
["a"]=>
NULL
}
--------------------------------------------------------------------------------
test1->new
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test2->showMe
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test1->showMe
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test2->display
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test1->display
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
0
test1->callMe
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test3->showMe
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test2->showMe
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test1->showMe
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test2->display
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
test1->display
object(test2)(1) {
["a"]=>
int(0)
}
--------------------------------------------------------------------------------
0
test1->setA
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test2->showMe
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test1->showMe
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test2->display
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test1->display
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
1
test1->callMe
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test3->showMe
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test2->showMe
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test1->showMe
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test2->display
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
test1->display
object(test2)(1) {
["a"]=>
int(1)
}
--------------------------------------------------------------------------------
1
test1->setA
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test2->showMe
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test1->showMe
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test2->display
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test1->display
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
2
test1->callMe
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test3->showMe
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test2->showMe
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test1->showMe
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test2->display
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
test1->display
object(test2)(1) {
["a"]=>
int(2)
}
--------------------------------------------------------------------------------
*/
?>
--
Edit bug report at http://bugs.php.net/?id=19376&edit=1
--
Try a CVS snapshot: http://bugs.php.net/fix.php?id=19376&r=trysnapshot
Fixed in CVS: http://bugs.php.net/fix.php?id=19376&r=fixedcvs
Fixed in release: http://bugs.php.net/fix.php?id=19376&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=19376&r=needtrace
Try newer version: http://bugs.php.net/fix.php?id=19376&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=19376&r=support
Expected behavior: http://bugs.php.net/fix.php?id=19376&r=notwrong
Not enough info: http://bugs.php.net/fix.php?id=19376&r=notenoughinfo
Submitted twice: http://bugs.php.net/fix.php?id=19376&r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=19376&r=globals