473,320 Members | 2,012 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Dynamic class inheritance

Hi, I want to know if it is any workaround for this:

I have a class which models a database table behavior (table abstract class)
I have several clases wich extends the table abstract class, providing information about their fields. The name of this classes are the names of the tables on the database. (users, stock, sales, etc)

I want to have a class wich provide additional functionality to each the users, stock, sales, etc, and define it dynamically.

Ex:
class Users extends Table{}
$myParent = 'Users'
class List extends $myParent {}

This actually doesn't work, that's why I'm looking a workaround.
Thank you.
Aug 8 '09 #1
7 5171
Dormilich
8,658 Expert Mod 8TB
@santiagofs
this doesn’t make sense to me. usually you create several instances of one class to resemble each of the tables, which would also solve your inheritance problem.
Aug 8 '09 #2
I understand it may be not make sense to you. Lets try explain it a bit more.
As you say, I'm creating several instances of the table class to resemble each of the tables.
But each of this classes may be used in different contexts: managing lists and editing records on a CMS, presenting data to the user, make summarys, manage translations, etc.

You can create a base class which do all that things, but you obtain a single huge class which is very difficult to mantain (and understand).
Also, the idea is the table base class can be used in many projects without changes, meanwhile other behaviors do.

It's also a more semantic approach if you want: the table abstract class and its childs belongs to the data layer.
The dynamic classes I'm trying to implement are to present data to the users, the top layer of any application.


(You can use interfases, but you have to write the same method on each child class. Not a solution.)

Hope I can explain my problem a little more.

Thanks
Aug 8 '09 #3
Dormilich
8,658 Expert Mod 8TB
@santiagofs
I’d do a different child class (or something along) for each purpose.

@santiagofs
maybe one of the standard Design Patterns may be of use here (Factory or Facade…)

@santiagofs
Interfaces are for API (completely different purpose), and you don’t need to limit yourself to just one child class—if it suits your needs you can have 4 or more extending classes.
Aug 8 '09 #4
Dormilich, thanks for your replay

@Dormilich
I understand interfaces are a way to implement pseudo multiple inheritance. Probably I'm wrong.

@Dormilich
I know you can have the child classes you want:
Users extends List extends Edit extends Table (where List, Edit and Table are kind of abstract and Users do the overrides needed).
But you came with a Users class having a lot of functionallity you dont need in a particular moment (you don't need List functionallity while using Edit) and most important, suponse you upgrade your model including two more clases:
Users extends Summary extends Translations extends List extends Edit extends Table
Then you have to modifie all the final classes (Users, Stock, Products, Blah) to suit your new needs (and all the projects you are using them)

What I'm trying to solve (I'm carrying it through many time and different programming languages) is how to extend the functionality / behavior of particular objects, not the more abstract ones.
Usually I used object composition but this implies modification of the base classes every time you have a new need.

Let say both you and me are Persons (and instances of the Person class). If I go to a party I wear a Tuxedo, if I go to the beach I wear a SwimSuit.
The exposed models are as I'm going to a party with all my wardrobe in a bag! and worst, that you and me are carring the exact same clothe everywhere.


@Dormilich
Thanks, I'll read what you propose (I'm not aware about the existing theoretical patterns).

Thanks again for replying, it helps a lot to expose a problem to get a better understanding of it.
Aug 8 '09 #5
Atli
5,058 Expert 4TB
Hi.

This looks a bit odd to me.
As I see it, you are trying to add functionality to a class after it has been defined.

For example, if we take your wardrobe example, it looks to me like you are trying to do something like:
Expand|Select|Wrap|Line Numbers
  1. abstract class Person { }
  2.  
  3. class John extends Person {}
  4. class Jane extends Person {]
  5.  
  6. class Tuxedo extends John {}
  7. class Swimsuit extends Jane {}
Where the parents of the Tuxedo and Swimsuit classes would be dynamic, changing according to which person is meant to wear what.

But this obviously has major issues, like the fact that using this method (which isn't possible, by the way), only one person could wear each wardrobe per execution.

You should be doing something more like:
Expand|Select|Wrap|Line Numbers
  1. abstract class Person {}
  2.  
  3. abstract class TuxedoPerson extends Person {}
  4. abstract class SwimsuitPerson extends Person {}
  5.  
  6. class John extends TuxedoPerson {}
  7. class Jane extends SwimsuitPerson {}
And PHP being awesome, you can define which class to extend at runtime:
Expand|Select|Wrap|Line Numbers
  1. if($wardrobe == "Tuxedo") {
  2.   class John extends TuxedoPerson {}
  3. }
  4. else if($wardrobe == "Swimsuit") {
  5.   class John extends SwimsuitPerson {}
  6. }
  7. else {
  8.   class John extends Person{}
  9. }
P.S.
It's like 5 in the morning here, so I may quite possibly be to tired to even understand the problem... I'll check back in the morning (or more like tomorrow afternoon, at this rate :-)
Aug 12 '09 #6
Markus
6,050 Expert 4TB
@Atli
Still, even that would make little sense to me; favor composition over inheritance! And by that I mean, prefer HAS-A over IS-A.

Expand|Select|Wrap|Line Numbers
  1. abstract class AbstractPerson {
  2.  
  3.     /**
  4.      * @var string Person's name
  5.      */
  6.     private $name;
  7.     /**
  8.      * @var Wardrobe Person's current wardrobe
  9.      */
  10.     private $wardrobe;
  11.  
  12.     /**
  13.      * @see       AbstractPerson::$name
  14.      * @param  string $name
  15.      * @return void
  16.      */
  17.     public function setName($name) {
  18.         // All people will set their name the same way,
  19.         // so this doesn't need to be abstract
  20.         $this->name = $name;
  21.     }
  22.  
  23.     /**
  24.      * @see       AbstractPerson::$wardrobe
  25.      * @param  Wardrobe $w
  26.      * @return void
  27.      */
  28.     public function setWardrobe(Wardrobe $w) {
  29.         // Again, this will be the same throughout any child
  30.         // classes, so no need to abstract it.
  31.         $this->wardrobe = $w;
  32.     }
  33.  
  34.     // I got bored of documenting.
  35.     public function getWardrobeType() {
  36.         return $this->wardrobe->getName();
  37.     }
  38.  
  39.     /**
  40.      * Makes the person walk - behaviour defined by child classes,
  41.      * because all people walk differently.
  42.      * 
  43.      * @access public
  44.      * @return void
  45.      */
  46.     public abstract function walk();
  47.     /**
  48.      * Makes the person talk - behaviour defined by child classes,
  49.      * because all people talk differently.
  50.      * 
  51.      * @access public
  52.      * @return void
  53.      */
  54.     public abstract function talk();
  55. }
  56.  
  57. /**
  58.  * Use a base abstract class to program to an interface,
  59.  * not implementation - this is generally a strongly-typed
  60.  * language technique, but PHP 5 has type-hinting, so use it!
  61.  */
  62. abstract class Wardrobe {
  63.  
  64.     public $name;
  65.  
  66.     public function setName($name) {
  67.         $this->name = $name;
  68.     }
  69.     public function getName() {
  70.         return $this->name;
  71.     }
  72. }
  73.  
  74. class TieAndSuit extends Wardrobe {
  75.     // Some cool methods would go here - I can't think of any
  76.     // at the moment.
  77.     public function __construct($name = __CLASS__) {
  78.         $this->name = $name;
  79.     }
  80. }
  81.  
  82. class Swimsuit extends Wardrobe {
  83.     // Some cool methods would go here - I can't think of any
  84.     // at the moment.
  85.     public function __construct($name = __CLASS__) {
  86.         $this->name = $name;
  87.     }
  88. }
  89.  
  90. class BaggyJeans extends Wardrobe {
  91.     // Some cool methods would go here - I can't think of any
  92.     // at the moment.
  93.     public function __construct($name = __CLASS__) {
  94.         $this->name = $name;
  95.     }
  96. }
  97.  
  98. class John extends AbstractPerson {
  99.  
  100.     public function __construct($name = __CLASS__) {
  101.         $this->name = $name;
  102.     }
  103.  
  104.     /**
  105.      * @see AbstractPerson::talk()
  106.      */
  107.     public function talk() {
  108.         // Should probably return this rather than print it
  109.         // directly in the method.. but whatever trevor!
  110.         printf("Hi, my name is %s, and I have a deep void"
  111.               ." - the women love it, especially your mom.\n",
  112.               $this->name
  113.         );
  114.     }
  115.  
  116.     /**
  117.      * @see AbstractPerson::walk()
  118.      */
  119.     public function walk() {
  120.         printf("Hi, my name is %s, and I walk with a gangster-lean.\n",
  121.                $this->name
  122.         );
  123.     }
  124. }
  125.  
  126. $john = new John;
  127. $john->walk();
  128. $john->talk();
  129. $john->setWardrobe(new BaggyJeans);
  130. print $john->getWardrobeType();
  131.  
Notice AbstractPerson::$wardrobe - that is a HAS-A relationship; AbstractPerson has a Wardrobe - because AbstractPerson::$wardrobe expects the abstract Wardrobe, you're not programming to an implementation, but to an interface (not an interface struct, but to the super-type Wardrobe).

My $0.2

P.S. I got bored of documenting it - that always happens to me! :P
Aug 12 '09 #7
Atli, thank you. I didn't know you could use conditionals for class extension. I think it not applies to my current problem, but sure it will be usefull.

Markus, I agree with you that composition must be favored over inheritance: a Person is not an Arm or a Leg, a Person Has an Arm and Has a Leg.

But only when the HAS A really applies: a Diver could HAVE Equipment but IS a Person.

Object composition has a backdraw too: if you add behaviors to a base class over time, again, it becames huge and difficult to mantain. In a scenario where you are not the only developer, having many people touching base classes it's always a problem.

I came to a solution that combines a little of both concepts (inheritance and composition), thought I think it may have less performance:


Expand|Select|Wrap|Line Numbers
  1. class Dynamic_class {
  2.     private $base = '';
  3.  
  4.     function __construct($base)
  5.    {
  6.        $this->base = $base
  7.    }
  8.       public function __call($name, $arguments) {
  9.         return call_user_func_array(array($this->base, $name),$arguments);
  10.     }
  11.  
  12.     public function __set($name, $value) {
  13.        $this->base->$name = $value;
  14.     }
  15.  
  16.     public function __get($name) {
  17.         return $this->base->$name;
  18.     }
  19. }
  20.  
  21. class Diver extends Dynamic_class
  22. {
  23.     // Diver behavior here
  24.  
  25. }
  26.  
  27. class Person {}
  28.  
  29. $John = new Person;
  30. $JohnDiver = new Diver($John);
  31.  
Through $JohnDiver you can access both Person and Diver properties and methods, and if needed, you can override in Diver any method or property of Person.

This way you can create all the different behaviors you want (Diver, Pilot, Doctor, Blah), without directly modifying the base class (which means you can always trust on code it's actually working and properly debuged)

All classes remains small enough to be well handled (the big issue with multiple inheritance)
You can have each developer on a team working on a different behavior at the same time without interfering with others.

Besides, as the solution I came is not as 'elegant' I'd like, I think it helps a lot the abstraction process and modeling.

Thank you Marcus, it was by talking with you I came to this approach. I you see any problem with it or a way to do it better, please tell me.

Thanks again.
Aug 12 '09 #8

Sign in to post your reply or Sign up for a free account.

Similar topics

4
by: PengYu.UT | last post by:
Hi, Some dynamic polymorphism programs can be converted to the equavalent static polymorphism programs. I'm wondering if there are any generall procedures that I can use to do this conversion. ...
0
by: Pascal Costanza | last post by:
Dynamic Languages Day @ Vrije Universiteit Brussel ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Monday, February 13, 2006, VUB Campus Etterbeek The VUB (Programming Technology Lab,...
5
by: Derek | last post by:
I have an advanced question that I hope there is a possible answer for... Say that I have a list of base objects and I wish to allow them to be passed to various routines which may wish to...
2
by: Marvin | last post by:
Hi, It's been claimed that inheritance structures are less important in dynamic languages like Python. Why is that and where can i read more about that? /Marv
3
by: cwertman | last post by:
I have a question regarding dynamic properties. I have an Object say Account --Id --Prefix --Fname --Lname --Suffix
11
by: axel22 | last post by:
Please observe this simple model of multiple inheritance: void main() { class A { public: virtual void print() { cout << "A" << endl; }; class Support1 : virtual public A {
8
by: mfc | last post by:
Suppose I have a Cookie class and a Factory Class. There are many types of Cookies and maybe one or more Factories with a ProcessCookie Method. Suppose all the PutInBox method does is decide what...
16
by: devicerandom | last post by:
Hi, I am currently using the Cmd module for a mixed cli+gui application. I am starting to refactor my code and it would be highly desirable if many commands could be built as simple plugins. ...
16
by: manatlan | last post by:
I've got an instance of a class, ex : b=gtk.Button() I'd like to add methods and attributes to my instance "b". I know it's possible by hacking "b" with setattr() methods. But i'd like to do...
3
by: c.ginestet | last post by:
Hello, I want to create classes that I could aggregate with each others using operators. This would therefore take the form of a dynamic aggregation. For instance, (This code does not...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.