Re: instantiate derived class objects from within base class?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



php will not have late (runtime) static binding until at least version 6.
this sucks, it has sucked since 2003, welcome to the club of people who think
it sucks :-)

how to hack around this issue:

abstract class A {
protected abstract function foo();
public static function bar($c = null) {
	$x = new $c();
	if ($x instanceof self) {
		$x->foo();
	}
}
}

class B extends A {
public static function bar($c = null) {
	return parent::bar(__CLASS__);
}
protected function foo() {
	echo "hello world";
}
}

...and any number of variations of that hack - all of which are horrid.

D. Dante Lorenso wrote:
Chris wrote:

This gives the problem away..
http://www.php.net/manual/en/language.oop5.abstract.php
Any class that contains at least one abstract method must also be abstract.
Make 'A' abstract:
abstract class A

Sorry for the poor example. I did catch that after submitting my post, but it didn't really matter. Adding abstract to the class doesn't solve the problem. Here I do as you say and still get the error:

---------- 8< -------------------- 8< -------------------- 8< ----------
<?php
// Change to E_ALL for development/debugging
error_reporting(E_ALL | E_NOTICE);
ini_set('display_errors', 'On');

// defines base functions and requires derived classe to replace foo()
abstract class A {
   protected abstract function foo();
   public static function bar() {
       print __CLASS__;
       $x = new self();
       $x->foo();
   }
}
// defines foo() as it should, but base class doesn't know foo exists
// when it references self()
class B extends A {
   protected function foo() {
       echo "hello world";
   }
}

// show how broken things are
B :: bar();
?>
---------- 8< -------------------- 8< -------------------- 8< ----------

Output:
A
*Fatal error*: Cannot instantiate abstract class A in *.../demo.php* on line *11

The problem is that when method bar() is invoked on class B statically, class B is complete ignored. Since bar() is only defined inside class A, the B :: bar() call seems to be translated into a call of A::bar() and class B is no longer addressable.

My expectation is that when I call an object, the search for a method or property should start at the bottom-most derived object and work it's way up the dependency tree. This doesn't happen, though. It appears that any class can only reference base class and inherited methods and never derived methods. Perhaps this is only symptomatic when referenced statically?

Dante
*


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux