![]() |
Object-Oriented Habits
When is inheritance overdoing it? Which of these two programs is better? Why? I'd like to hear your thoughts. My object oriented habits are limited to my experiences, so I'd like to hear others.
I, personally, would do either one. I could not give a definite answer. Inheritance :
class child:Flags :
MALE = 1 |
Re: Object-Oriented Habits
Personally, I think it depends on the program. If the two inheriting classes would be implemented substantially differently, then definitely go with inheritance. If the differences are fairly small, then I'd go with your second solution, though I'd probably wrap the constants into the class as class attributes, like so:
:
(And, as an aside, you should probably start getting in the habit of using new style classes (i.e inheriting everything from object, if it isn't inheriting anything else) instead of old-style as you're using now. |
Re: Object-Oriented Habits
Yes, I like your suggestion. I tend to stay away from non-global-scope constants. But I'll shift gradually.
Oh? What does inheriting 'object' provide? I thought that only added some more callable methods, or something to that effect... |
Re: Object-Oriented Habits
For now its mostly just style, though old-style classes will be gone in 3.0.
New style-classes are mostly useful for the descriptor protocol and some meta-class goodness, neither of which you need very frequently. |
Re: Object-Oriented Habits
Oh, ****. That must be why my meta-class wasn't working before.
|
Re: Object-Oriented Habits
The inheritance based model is just Java/C++'s version of OOP. Python can probably handle more sophisticated techniques like Mixins.
|
Re: Object-Oriented Habits
I absolutely agree that it depends on the program.
In general, I use inheritance for modeling similarities in behavior or expectations of the class user. Strictly speaking, this is not required in Python the way it is in statically typed languages, since duck-typing allows you to invoke any method on any object, and find out at runtime whether or not the object implements that method. Contrast with, say, Java or C++, in which a program wont compile unless an object implements a method called on it. So I use inheritance as a way of modeling interfaces, or defining common base class code that is the same for multiple subclasses. To answer your specific example, I prefer the attribute-based implementation given by ZenMasterJG (I also prefer the naming style - classes should be capitalized to be easily distinguishable from instances). But if you find your Child class starting to contain lots of code like: :
if self.gender == Child.MALE:then you might consider creating MaleChild and FemaleChild subclasses of Child, and then letting polymorphism take care of the "if" logic. Like this (please forgive the sexism, you picked the example domain!): :
class Child(object):becomes: :
class MaleChild(Child):and then your code can write: :
for ch in childrenList:and instead of the underlying class using "if self.gender==Child.MALE" conditionals, the object's type will just run the gender-specific version of favorite_color or play_with_dolls. What separates Python from Java and C++ is that in Python, you could write all this same code and MaleChild and FemaleChild don't really have to inherit from Child. The class attributes and methods all get dynamically resolved at runtime, there is no compile time check to see whether an object actually implements favorite_color or play_with_dolls. Now if you then find that you are duplicating methods like this in both classes: :
def should_be_in_school(self):then you could refactor MaleChild and FemaleChild to inherit from a common Child base class, and put the gender-inspecific code in that class, to be common to both MaleChild and FemaleChild objects. But personally, I would probably use a common base class in such a case, even if just to have a common __init__ method, and to help me keep track of classes that are intended to maintain a common set of supported methods. Here is something NOT to do with inheritance: don't confuse inheritance "is-a" with composition "is-implemented-using-a". Here is a bad example: :
class Class(list):Just because you might implement a roster of children in a classroom with a Python list does not mean that you should inherit from list for such a thing. Instead do this: :
class Class(object):The time to inherit from a base type would be if you wanted a specialized version of that base type, such as a list that was always kept in sorted order. I would posit that domain classes pretty much never inherit from base types (such as int, dict, list, etc.). -- Paul |
| All times are GMT -5. The time now is 2:13 PM. |
Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC