Overriding class constants
|
|
Thread rating:  |
Gordon - 03 Jul 2008 14:18 GMT I want to provide a set of static functions in a superclass that work with class constants defined in a decendant of that class. Unfortunately I've run into a snag with this idea. Example:
class SuperClass { const CNST = 'Super class';
public static function getCnst () { return self::CNST; } }
class SubClass extends SuperClass { const CNST = 'Sub class'; }
echo (SubClass::getCnst ());
I'd want the above code tou output "Sub Class", but instead it outputs "Super class".
It would sem that static functions can't work with overridden constants in subclasses, or am I missing something?
Jerry Stuckle - 03 Jul 2008 16:25 GMT > I want to provide a set of static functions in a superclass that work > with class constants defined in a decendant of that class. [quoted text clipped - 22 lines] > It would sem that static functions can't work with overridden > constants in subclasses, or am I missing something? Nope, unfortunately, this is true.
 Signature ================== Remove the "x" from my email address Jerry Stuckle JDS Computer Training Corp. jstucklex@attglobal.net ==================
Michael Fesser - 03 Jul 2008 16:29 GMT .oO(Gordon)
>I want to provide a set of static functions in a superclass that work >with class constants defined in a decendant of that class. [quoted text clipped - 22 lines] >It would sem that static functions can't work with overridden >constants in subclasses, or am I missing something? Currently static references are resolved at compile time. What you need here is called late static binding and scheduled for PHP 5.3.
Micha
Gordon - 04 Jul 2008 09:14 GMT > .oO(Gordon) > [quoted text clipped - 29 lines] > > Micha Thanks.
Is there any kind of a workaround possible in older versions? The only way I've found to get it to work as intended is to "inherit from the clipboard" and cut and paste the methods into all the classes. Maintainence nightmare.
Mathieu Maes - 04 Jul 2008 09:50 GMT > > .oO(Gordon) > [quoted text clipped - 36 lines] > the clipboard" and cut and paste the methods into all the classes. > Maintainence nightmare. Theoratically speaking, a constant that needs to change during execution is not a constant. Could you explain the context a bit more ? I don't really see what you're trying to do in your "simple" example.
Gordon - 04 Jul 2008 14:17 GMT > > > .oO(Gordon) > [quoted text clipped - 41 lines] > Could you explain the context a bit more ? I don't really see what > you're trying to do in your "simple" example. The values don't have to change during execution. They just have to be different for different classes.
What I need is to be able to specify some parameters in a class that describe how it is to be dealt with. For example for creating a new item in the database I have a page that loads a HTML form for the user to populate. However, each different type of item has a different form. For example a document needs a field for content but a folder doesn't as a folder is just a container for other items. I want to specify in a class constant attributes for things such as that. For example, a Folder class could have a NEW_FORM constant set to 'newfolder.php' whereas a Document class could have a NEW_FORM with a value of 'newdoc.php'.
You have to be able to know what these values are before you can instantise a class, however. Of course you can do a switch statement based on the class of the item you intend to create, but that means that, for example, I later want to add a new Blog class, then as well as creating the new class I also have to remember to add Blog as an option in the switch statement. If the Blog class itself can define what makes it different from the other classes the system has to work with then I can elimate the switch statement.
Of course there is only one switch statement in the above example but in the real app there is more than one script that has to deal with different types of object. If I used switch statements in all of those cases then the result would have poor maintainability.
As was stated earlier by another poster the next version of PHP will have a solution to this problem, namely late static binding. I guess it's a common enough problem that they needed to add that feature to the new release. Of course PHP 5.3 could be days off or several months off and was hoping to find a workaround in the meantime.
Jerry Stuckle - 04 Jul 2008 16:19 GMT >>>> .oO(Gordon) >>>>> I want to provide a set of static functions in a superclass that work [quoted text clipped - 63 lines] > the new release. Of course PHP 5.3 could be days off or several > months off and was hoping to find a workaround in the meantime. But in your example, your inheritance hierarchy is incorrect. In folder is not a "typeof" document. And no, physical storage media doesn't count.
Derived classes should always be more specific examples of the base class.
 Signature ================== Remove the "x" from my email address Jerry Stuckle JDS Computer Training Corp. jstucklex@attglobal.net ==================
Gordon - 05 Jul 2008 10:42 GMT > >>>> .oO(Gordon) > >>>>> I want to provide a set of static functions in a superclass that work [quoted text clipped - 76 lines] > jstuck...@attglobal.net > ================== Both Folder and Document inherit from a common ancestor, Item. Everything in the system have some commonality, they all have a numeric ID and numeric parent (though it can be 0 for root items, aka Sites), they all have titles and filesystem names, and they all have metadata for searching. There are other classes that also descend from Item, called Template, and Asset. Folder has a descendant, Site (A Site is a Folder that is always a root item, and when they are created they need to have some system Folders set up). The next edition will be a Survey class, that descends from Document. A Survey behaves like a Document (it's basically a Document that contains a web form in terms of presentation) but it also has to handle data acquisition.
The idea is to define static methods in Item that work on the constants defined in the various descendant classes. Of course until late static binding is available that's not going to work.
Jerry Stuckle - 05 Jul 2008 13:55 GMT >>>>>> .oO(Gordon) >>>>>>> I want to provide a set of static functions in a superclass that work [quoted text clipped - 87 lines] > constants defined in the various descendant classes. Of course until > late static binding is available that's not going to work. It sounds like you're trying to derive everything from Item - which really isn't a good idea. It ties all of your classes more closely togehter, making them more dependent on each other.
Also, a Site is not a "type of" folder, although it can refer to a folder Neither is a Survey a type of a Document. The results generated from the survey, however, could be. Again, the document would be related to the survey.
All in all, I think your hierarchy is going to cause you a lot more problems than you see now.
 Signature ================== Remove the "x" from my email address Jerry Stuckle JDS Computer Training Corp. jstucklex@attglobal.net ==================
Gordon - 05 Jul 2008 22:24 GMT > >>>>>> .oO(Gordon) > >>>>>>> I want to provide a set of static functions in a superclass that work [quoted text clipped - 107 lines] > jstuck...@attglobal.net > ================== Conceptually a Site is a type of Folder, because both are represented in the filesystem by directories and are containers for other items. The Site is essentially a root Folder. The reason for the distinction is that a Site is expected to contain a set of Folders the system uses for storing uploaded files, images, etc, so its CreateItem method creates them as well. As for the Survey, the interface it presents to the outside world is a HTML page with a form in it, in other words a Document (which represents a HTML page) with content appropriate to the task in hand of collecting data. The results collected by the survey are a different matter as they can be viewed different ways, as a table, bar chart, pie chart, CSV file etc, and thus aren't really conceptually Documents.
As for the Item class it handles all the tasks common to everything managed by the system. They all have metadata, they all abstract things that exist on the filesystem, etc. The Item class is the biggest class, but it's not considerably bigger than the classes that descend from it.
And as has already been established, the problem I'm having is down to PHP not implementing functionality that I need for it, and that said missing functionality will be in a future version.
Jerry Stuckle - 06 Jul 2008 01:48 GMT >>>>>>>> .oO(Gordon) >>>>>>>>> I want to provide a set of static functions in a superclass that work [quoted text clipped - 115 lines] > a table, bar chart, pie chart, CSV file etc, and thus aren't really > conceptually Documents. Not so. The file system is only the way the data is stored. What if you had a site which was entirely database driven? Then you have no "file system" - just a single generic file and a .htaccess file.
Don't mix the physical representation and the overall design. It's a common problem.
In a true OO environment, the site will NOT be a type of folder - conceptually they are two entirely different types of objects.
> As for the Item class it handles all the tasks common to everything > managed by the system. They all have metadata, they all abstract > things that exist on the filesystem, etc. The Item class is the > biggest class, but it's not considerably bigger than the classes that > descend from it. Again, not really valid. From your design, almost everything would be derived from Item - which means EVERYTHING it tied together. When you have that type of relationship, it's much harder to make changes.
> And as has already been established, the problem I'm having is down to > PHP not implementing functionality that I need for it, and that said > missing functionality will be in a future version. No, you think the problem is not implementing the functionality you need. I think you have an invalid inheritance hierarchy. You're only seeing the initial problem (which, BTW, will occur in virtually any OO language). You will have others in the future.
 Signature ================== Remove the "x" from my email address Jerry Stuckle JDS Computer Training Corp. jstucklex@attglobal.net ==================
Chad Burrus - 04 Jul 2008 19:01 GMT > > .oO(Gordon) > [quoted text clipped - 36 lines] > the clipboard" and cut and paste the methods into all the classes. > Maintainence nightmare. One workaround that works with instances of a class (which unfortunately does not work with static calls like in your example) is to use the get_class function to grab the class name of the current object, and then build a string you can pass to the constant function.
However, since you want static functions, the only way I know of to work around the problem is to cheat: override the getConst function in SubClass and pass in the class name to the SuperClass function, which will give you something like this:
class SuperClass { const CNST = 'Super class';
public static function getCnst ($class = NULL) { if (!$class) { $class = get_class(); } return constant($class . '::CNST'); }
}
class SubClass extends SuperClass { const CNST = 'Sub class';
public static function getCnst () { return parent::getCnst(get_class()); }
}
echo SubClass::getCnst(); // outputs "Sub class"
You somewhat avoid the "inherit by clipboard" maintenance issue, but you still have to override the getCnst method in all of your subclasses, which kind of defeats the whole point.
HTH
Gordon - 05 Jul 2008 10:58 GMT > > > .oO(Gordon) > [quoted text clipped - 81 lines] > > HTH Thanks, that's not a bad idea. While the functions still have to be in all the classes only the ancestor class has to define the actual logic, all the descendants only have to call it. That's certainly an improvement.
|
|
|