elme Posted April 25, 2013 Share Posted April 25, 2013 I've got some classes, and each of those classes have a collection of static functions which returns an instance of those classes, instead of having those functions in 20 different classes, I tried to move them to a parent class and inherit that class. The problem is, when I use "return new self" from the parent class, it won't return the properties of the child it's been called from. Here's a simple example of what i am trying to do - <?php class Personal_Details{ static function create_user(){ return new self; } } class Female_User extends Personal_Details{ public $gender = "f"; } class Male_User extends Personal_Details{ public $gender = "m"; } $new_user = Male_User::create_user(); echo $new_user->gender; ?> I guess I'm using the wrong logic here, but how can i make this work the way i intended to? Thans. Quote Link to comment Share on other sites More sharing options...
Hall of Famer Posted April 25, 2013 Share Posted April 25, 2013 (edited) Well you can try this: static function create_user(){ return new static; } The self keyword references to the very specific class in which the method is defined, in your case it is the parent class personal_detail, this is why the property $gender is undefined when you call this method. The static keyword, on the other hand, points to the very child class that calls this static method. Read this article for more details on the variation between self and static: http://stackoverflow.com/questions/5197300/new-self-vs-new-static Anyway incase you have to, Id recommend against calling parent's static method to create objects of its child classes, static properties/methods dont work well with inheritance and composition, they aint true OOP at all. Try rewriting the classes with instance properties/methods using factory pattern is the better idea, and its better done in a specialized factory object. Edited April 25, 2013 by Hall of Famer Quote Link to comment Share on other sites More sharing options...
ignace Posted April 25, 2013 Share Posted April 25, 2013 class GenderEnum { const MALE = 'M'; const FEMALE = 'F'; const ALIEN = 'A'; public static isValid($gender) { return in_array($gender, array(self::MALE, self::FEMALE, self::ALIEN)); } } class User { private $gender; public function setGender($gender) { if (!GenderEnum::isValid($gender)) { throw new UnexpectedValueException(); } $this->gender = $gender; } }Unless you have different behavior for your Male and Female classes these should be just one class. And by different behavior I mean: class MaleUser extends User { public function doThingA() { // do stuff } } class FemaleUser extends User { public function doThingA() { // do it completely different } } Quote Link to comment Share on other sites More sharing options...
seandisanti Posted April 25, 2013 Share Posted April 25, 2013 If you get errors trying to implement HoF's code, check your php version as late static bindings were not available before 5.3. Id recommend against calling parent's static method to create objects of its child classes, static properties/methods dont work well with inheritance and composition, they aint true OOP at all. It can be done correctly and easily, if you plan it out first. What do you mean 'aint true OOP'? This is one function from my Model class that is extended by most of my objects that have data representations in my database. public static function findById($id){ $db = Database::getInstance(); $sql = "SELECT * FROM " . static::$tableName . " WHERE id = " . $db->quote($id); return new static::$className($db->query($sql)->fetch(PDO::FETCH_ASSOC)); } I can then call Class::findById() from any class that extends Model, and have an instance of the object based on a row in the relevant table. Quote Link to comment Share on other sites More sharing options...
elme Posted April 28, 2013 Author Share Posted April 28, 2013 Thank you everyone, eventually i upgraded my php to 5.4 and used "trait" Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.