Inheriting static methods/properties

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
routinet
Forum Newbie
Posts: 3
Joined: Tue Jun 05, 2007 5:16 pm

Inheriting static methods/properties

Post by routinet »

feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]


I've read the discussion on this,  but I just think it's wrong.  In the example below, the only you'll see "bar" is if both commented sections are uncommented, which keeps the context completely in class b.  I understand the reasoning behind the behavior.  At the same time, this behavior ignores the concept of reusability.  I'd have to reproduce all of my class a code in class b for 'proper' behavior, which negates the reason for having class a to begin with.  Is there any reconciliation for this?  Last I heard, "this behavior is expected and will not be fixed"...

Code: Select all

<?
class a {
	protected static $var1 = "foo";
	protected static function doit() {
		echo("in a:doit = " . self::$var1) . "<br>";
	}
	public function go() {
		self::doit();
	}
}

class b extends a {
	protected static $var1 = "bar";

/*
// commented section 1
	protected static function doit() {
		echo("in b:doit = " . self::$var1);
	}
*/

/*
// commented section 2
	public function go() {
		self::doit();
	}
*/

}

$d = New a;
$e = New b;
$d->go();
$e->go();
?>

feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

No you wouldn't. That's what constructors are for.
routinet
Forum Newbie
Posts: 3
Joined: Tue Jun 05, 2007 5:16 pm

Post by routinet »

Please elaborate. How would a constructor allow for the behavior I want to see?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Setting of the previously established static. Just as the previously established static could, and likely should, in fact be set in a constructor as well.
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

The problem is that unlike $this, "self" binds early, and means "class, the method is declared in", not "the class, the method is called for". There was a plan to add a new keyword in php6 to support the latter behaviour. Till then, there's not much you can do about that. However, statics are just a fancy form of globals, perhaps the best option would be to avoid them altogether.
User avatar
dbevfat
Forum Contributor
Posts: 126
Joined: Tue Jun 28, 2005 2:47 pm
Location: Ljubljana, Slovenia

Post by dbevfat »

I believe the new keyword stereofrog is referring to will be static; it will refer to the class that uses it, not the class that declares it.

As for the comparison with globals, static variables are only global within the context of a class (and objects of that class) -- they have a limited scope which is not, in fact, truly global. This differs them from the ordinary globals (including singletons) that are truly global in terms of visibility and accessibility.
routinet
Forum Newbie
Posts: 3
Joined: Tue Jun 05, 2007 5:16 pm

Post by routinet »

@feyd:
Setting of the previously established static.
I understand what you're getting at, but that would require me to init the static before every call to any class extending the base parent. I have a single parent extended into multiple classes. One of the static variables I'm using controls the table used by whichever child class is operating at the moment. If I use the class constructor to set the static, that works fine for the first call. Subsequent calls may not work as intended because OTHER child classes have since been initialized, thus changing the parent class's static value. Your suggestion necessitates me managing those static values over and over again, in every child method that utilizes a parent static method or variable.

@stereofrog:
The problem is that unlike $this, "self" binds early, and means "class, the method is declared in", not "the class, the method is called for"
That seems completely counter-intuitive to me. I understand early vs. late binding, but I do not see how the actual implementation is justified. Say I have uncommented only block 2 from my original post. When I reference 'self' from public function go() in class b, I am obviously referring to the scope of class b. There's no way someone just reading that code would think I wanted to reference the scope of class a. But that's exactly what the code does. In this example, I'm calling self from within the class I want to use, and the scope is reverting back to the parent.

I see the point as far as static being bound to the defining class. My point is that by extending a class to form a new one, those inherited statics should be bound to the new extension. I am essentially saying "Take everything in this class here, and pretend I typed it in this class over here so that I don't actually have to", which is how I always understood class extension and inheritance to work.

To put it another way, if I have to reproduce all the work from my parent class inside the child class, what is the purpose of having the parent? This behavior destroys the concept of inheritance.
User avatar
kyberfabrikken
Forum Commoner
Posts: 84
Joined: Tue Jul 20, 2004 10:27 am

Post by kyberfabrikken »

routinet wrote: To put it another way, if I have to reproduce all the work from my parent class inside the child class, what is the purpose of having the parent? This behavior destroys the concept of inheritance.
Yes, but it's a moot point, since there are very few situations where static members are a good solution anyway. Simply create an instance, and use that.
Post Reply