473,775 Members | 2,572 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Inheritance Question

I've got an inheritance question and was hoping brighter minds could
guide me. I am in the strange situation where some of the methods in a
subclass are actually more general than methods in a superclass. What
is the preferred way to handle such situations. My original thought was
to do something like this:

class AA(object):
def general_method( ): pass

class A(AA):
# redefine general_method( ) to call a
# restricted version of AA.general_meth od()

class B(A,AA):
# redefine general_method( ) to call AA.general_meth od()

This seems ugly to me, and I am wondering if there is a better method.
So any suggestions would be appreciated.
Thanks!


-----------

For a more "concrete" example:

Suppose all the animals in the world have only 1 or 2 legs.

class Legs(object)
def run(): pass
def walk(number_of_ legs):
# lots of commands
# that do not depend on the
# number of legs but definitely
# have to do with walking

if number_of_legs == '1':
# blah blah

if number_of_legs == '2':
# blah blah

# more commands

class HasAtLeastOneLe g(Legs):
def walk():
# Legs.walk(numbe r_of_legs=1)

class HasTwoLegs(HasA tLeastOneLeg,Le gs):
def walk()
# Legs.walk(numbe r_of_legs=2)

# isinstance(HasT woLegs, HasAtLeastOneLe g) --True
Nov 10 '06 #1
6 1505
At Friday 10/11/2006 21:13, Jackson wrote:
>I've got an inheritance question and was hoping brighter minds could
guide me. I am in the strange situation where some of the methods in a
subclass are actually more general than methods in a superclass. What
is the preferred way to handle such situations. My original thought was
to do something like this:

class AA(object):
def general_method( ): pass

class A(AA):
# redefine general_method( ) to call a
# restricted version of AA.general_meth od()

class B(A,AA):
# redefine general_method( ) to call AA.general_meth od()

This seems ugly to me, and I am wondering if there is a better method.
So any suggestions would be appreciated.
(Note that even using your design, B doesn't have to inherit from
both A and AA, just inheriting from A is enough to be able to call
AA.general_meth od)

It's hard to tell in this abstract terms, but maybe you should
consider whether really B "is an" A, and A "is an" AA.
Other kind of relationships are possible, like delegation ("behaves
like") or the strategy pattern ("now behaves like...", at runtime).
>For a more "concrete" example:
Ahhhh! I didn't notice this when I read your post.
>Suppose all the animals in the world have only 1 or 2 legs.
I would not consider walk a method of Legs, but of Animal. An Animal
"has" Legs; it may have OneLeg or TwoLegs. An Animal walks "using" its legs.

class Animal:
def __init__(self, number_of_legs) :
# an animal has legs
self.legs = CreateLegs(self , number_of_legs)

def walk(self):
# an animal uses its legs to walk
self.legs.walk( )

class Legs:
def walk():
raise NotImplementedE rror # an abstract Legs doesn't have how to walk

class OneLeg(Legs): # a monopod? like in Plinius?
"http://en.wikipedia.or g/wiki/Monopod_(creatu re)"
def walk():
# implement walking with one leg
print "Look ma, just one leg!"

class TwoLegs(Legs):
def walk():
# implement walking with two legs
print "Left, rigth, left, right..."

def CreateLegs(anim al, number_of_legs) :
# legs might depend on animal too
if number_of_legs= =1: return OneLeg()
elif number_of_legs= =2: return TwoLegs()
raise ValueError, "Invalid number of legs: %d" % number_of_legs

If walking in general, have some common structure, you can put the
"sketch" on Legs and let the derived classes "fill the gaps". This is
known as "Template Method Pattern" - look for it.
--
Gabriel Genellina
Softlab SRL

_______________ _______________ _______________ _____
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ˇgratis!
ˇAbrí tu cuenta ya! - http://correo.yahoo.com.ar
Nov 11 '06 #2
Gabriel Genellina wrote:
If walking in general, have some common structure, you can put the
"sketch" on Legs and let the derived classes "fill the gaps". This is
known as "Template Method Pattern" - look for it.
Or if you'd rather see a concrete example, here's how your toy example
would look refactored using the template pattern:

class Creature(object )
def run(): pass
def walk():
# lots of commands
# that do not depend on the
# number of legs but definitely
# have to do with walking

self._specializ ed_walk(*args, **kwds)

# more commands

def _specialized_wa lk(self, *args):
raise NotImplementedE rror
class UnipedalCreatur e(Creature):
def _specialized_wa lk(self, *args, **kwds):
# blahblah
class BipedalCreature (Creature):
def _specialized_wa lk(self, *args, **kwds):
# blahblah
HTH,
George

Nov 11 '06 #3

Jackson wrote:
I've got an inheritance question and was hoping brighter minds could
guide me. I am in the strange situation where some of the methods in a
subclass are actually more general than methods in a superclass. What
is the preferred way to handle such situations. My original thought was
to do something like this:

class AA(object):
def general_method( ): pass

class A(AA):
# redefine general_method( ) to call a
# restricted version of AA.general_meth od()

class B(A,AA):
# redefine general_method( ) to call AA.general_meth od()

This seems ugly to me, and I am wondering if there is a better method.
So any suggestions would be appreciated.
I don't have an answer, but I have a similar question, so I hope you
don't mind if I add it to this thread. Hopefully there will be some
commonality in the responses.

Continuing your analogy of animals, assume a class A with a 'walk'
method and an 'eat' method.

Most animals walk the same way, but a few don't, so I create a subclass
AW and override the walk method.

Most animals eat the same way, but a few don't, so I create a subclass
AE and override the eat method.

How do I create an instance of an animal that both walks and eats
differently?

This is how I do it at present.

class A(object): # walks normally, eats normally
def walk(self):
normal walk
def eat(self):
normal eat

class AW(A): # walks differently, eats normally
def walk(self):
different walk

class E(object): # abstract class
def eat(self):
different eat

class AE(E,A): # walks normally, eats differently
pass

class AWE(E,AW): # walks differently, eats differently
pass

So I use multiple inheritance instead of subclassing to override the
eat method. It works, but it feels ugly. Is there a cleaner solution?

Thanks

Frank Millman

Nov 11 '06 #4
At Saturday 11/11/2006 03:31, Frank Millman wrote:
>Continuing your analogy of animals, assume a class A with a 'walk'
method and an 'eat' method.

Most animals walk the same way, but a few don't, so I create a subclass
AW and override the walk method.

Most animals eat the same way, but a few don't, so I create a subclass
AE and override the eat method.

How do I create an instance of an animal that both walks and eats
differently?

This is how I do it at present.

class A(object): # walks normally, eats normally
def walk(self):
normal walk
def eat(self):
normal eat

class AW(A): # walks differently, eats normally
def walk(self):
different walk

class E(object): # abstract class
def eat(self):
different eat

class AE(E,A): # walks normally, eats differently
pass

class AWE(E,AW): # walks differently, eats differently
pass

So I use multiple inheritance instead of subclassing to override the
eat method. It works, but it feels ugly. Is there a cleaner solution?
Answer 1) Move *both* ways of walk, and *both* ways of eating, to
another base class. Best when this is pure behavior - no new
attributes are involved.

class A(object): # does not know how to walk, neither how to eat
def walk(self):
raise NotImplemented
def eat(self):
raise NotImplemented

class WalkNormallyCap ability(object) : # knows how to walk normally
def walk(self):
normal walk

class WalkDifferentCa pability(object ): # knows how to walk different
def walk(self):
different walk

class EatNormallyCapa bility(object): # knows how to eat normally
def eat(self):
normal eat

class EatDifferentCap ability(object) : # knows how to eat different
def eat(self):
different eat

class
AWnEn(A,WalkNor mallyCapability ,EatNormallyCap ability): # walks
normally, eats normally
pass

class
AWdEn(A,WalkDif ferentCapabilit y,EatNormallyCa pability): # walks
different, eats normally
pass
....etc.

The xxxCapability classes are usually referred as "mixin class" -
they add a new capability to an existing class, without adding new
attributes (they could, but initialization gets more complicated, you
must rewrite __init__ and so...). They may inherit from a common base
class, too, but that's not required in Python.
Answer 2) Use an instance of another class to define how to walk and
how to eat. Advantage: it can later be modified at runtime (strategy pattern).

class A(object):
def __init__(self, walker, eater):
self.walker=wal ker
self.eater=eate r
def walk(self):
self.walker.wal k()
def eat(self):
self.eater.eat( )

class NormalWalker(ob ject): # knows how to walk normally
def walk(self):
normal walk

class DifferentWalker (object): # knows how to walk different
def walk(self):
different walk

class NormalEater(obj ect): # knows how to eat normally
def eat(self):
normal eat

class DifferentEater( object): # knows how to eat different
def eat(self):
different eat

a=A(NormalWalke r(), DifferentEater( ))
or define a factory function when you decide which walker an which
eater to use based on its arguments. As above, they may inherit from
a common base class (Walker, Eater, by example).

--
Gabriel Genellina
Softlab SRL

_______________ _______________ _______________ _____
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ˇgratis!
ˇAbrí tu cuenta ya! - http://correo.yahoo.com.ar
Nov 11 '06 #5

Gabriel Genellina wrote:
At Saturday 11/11/2006 03:31, Frank Millman wrote:
Continuing your analogy of animals, assume a class A with a 'walk'
method and an 'eat' method.

Most animals walk the same way, but a few don't, so I create a subclass
AW and override the walk method.

Most animals eat the same way, but a few don't, so I create a subclass
AE and override the eat method.

How do I create an instance of an animal that both walks and eats
differently?
[snip]
Answer 1) Move *both* ways of walk, and *both* ways of eating, to
another base class. Best when this is pure behavior - no new
attributes are involved.
[snip details]
>
Answer 2) Use an instance of another class to define how to walk and
how to eat. Advantage: it can later be modified at runtime (strategy pattern).
[snip details]

Many thanks for this, Gabriel.

I have seen explanations like this before, but my eyes usually glaze
over before I have finished, and I end up more confused than when I
started.

With a combination of my subconscious slowly getting an understanding
of this, and your clear explanation, I think I have finally got it.

Obviously my real world situation is quite a bit more complex than this
simple example, but with the help you have given me I can now
experiment with different ideas and decide on the best strategy.

Thanks again

Frank

Nov 11 '06 #6
Jackson wrote:
For a more "concrete" example:

Suppose all the animals in the world have only 1 or 2 legs.

class Legs(object)
def run(): pass
def walk(number_of_ legs):
# lots of commands
# that do not depend on the
# number of legs but definitely
# have to do with walking

if number_of_legs == '1':
# blah blah

if number_of_legs == '2':
# blah blah

# more commands

class HasAtLeastOneLe g(Legs):
def walk():
# Legs.walk(numbe r_of_legs=1)

class HasTwoLegs(HasA tLeastOneLeg,Le gs):
def walk()
# Legs.walk(numbe r_of_legs=2)
Well, I would have done this differently. If the only difference in
behavior between one- and two-legged creatures is their gait, I
probably wouldn't have bothered breaking Legs into subclasses. I'd
just pass the number of legs into __init__:

class Legs(object):
def __init__(self,n umber_of_legs):
self.number_of_ legs = number_of_legs
def walk(self):
# non-legs-dependent stuff
if self.number_of_ legs == 1:
# one-legged gait
elif self.number_of_ legs == 2:
# two-legged gait
else:
raise ValueError("inv alid number of legs")
# more non-legs-dependent stuff

Then, when defining some sort of monster class, I'd do something like
this:

class Human(object):
def __init__(self):
self.legs = Legs(2)
# etc.

class Dufflepud(objec t):
def __init__(self):
self.legs = Legs(1)
# etc.

If there's more to it than just gait (say for example, one-legged
creatures attack differently, jump higher, and can't turn invisible
because they don't have enough limbs to cast Level 4 Invisibility),
then I would factor out differences in behavior into subclasses.

class Legs(object):
def walk(self):
# non-leg-related stuff
self.set_gait()
# more non-leg-related stuff

class OneLeg(Legs):
def set_gait(self):
# set the one-legged gait

class TwoLegs(Legs):
def set_gait(self):
# set the two-legged gait

class Human(object):
def __init__(self):
self.legs = TwoLegs()

class Dufflepud(objec t):
def __init__(self):
self.legs = OneLeg()
ISTM you have been missing out on the true power of inheritance.
Behavior exclusive to creatures with two legs should be implmented in
the TwoLegs class, but in your example you define a HasTwoLegs class
yet still implement this behavior in the base class Legs. That's just
poor use of inheritance. My examples implement behavior exclusive to
two-legged creatures inside the TwoLegs class, where it belongs.

In fact, BEHAVIOR is the key to arranging class hierarchies. (The
classical advice, the inheritance represents the "is a" relationship,
can be very misleading and I don't recommend using it. The focus
should be on behavior.) Anyways, in your universe, there are three
kinds of behaviors:

A. behaviors exclusive to one-footed creatures
B. behaviors exclusive to two-footed creatures
C. behaviors common to both

Once you consider behaviors in this way, how to arrange the class
hierarchy becomes obvious. Each kind of behavior shoud be implemented
in its own class: common behaviors go into base classes, exclusive
behaviors into subclasses. The hierarchy should look like this:

class Legs -- this should implement all common behavior
class OneLeg(Legs) -- should implment all behavior exclusive to
one-legged creatures
class TwoLegs(Legs) -- should implment all behavior exclusive to
two-legged creatures

Note that there's no need for an AtLeastOneLeg class. There are only
one- and two-legged creatures in this univserse, so behaviors exclusive
to creatures with at least one leg apply are in fact common to all
creatures. But suppose we add zero-footed creatures to the universe.
Now we identify five kinds of behaviors:

A. behaviors common to all creatures
B. behaviors exclusive to zero-footed creatures
C. behaviors common to one- and two-footed creatures
D. behaviors exclusive to one-footed creatures
E. behaviors exclusive to two-footed creatures

Now we need an AtLeastOneLeg class in our hierarchy:

class Legs
class ZeroLegs(Legs)
class AtLeastOneLeg(L egs)
class OneLeg(AtLeastO neLeg)
class TwoLegs(AtLeast OneLeg)

But, notice that we still have a OneLeg class, because there's still
behavior exclusive to one-legged creatures. It belongs in OneLeg, not
in AtLeastOneLeg.

Hope this long-winded advice helps.
Carl Banks

Nov 11 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3752
by: KK | last post by:
Windows Forms Inheritance, Incomplete? I was playing around with Windows Forms and found out this Forms Inheritance feature. The moment I saw that, I felt this can be used effectively if the application contains couople of forms which have a consistant look and also shares SOME similar functionality between the forms.
2
2203
by: KK | last post by:
** Posting it here cause after couple of days no body responded.** I was playing around with Windows Forms and found out this Forms Inheritance feature. The moment I saw that, I felt this can be used effectively if the application contains couople of forms which have a consistant look and also shares SOME similar functionality between the forms.
4
12822
by: Dave Theese | last post by:
Hello all, The example below demonstrates proper conformance to the C++ standard. However, I'm having a hard time getting my brain around which language rules make this proper... The error below *should* happen, but my question to the community is *why* does it happen? Any answer will be appreciated, but a section and paragraph number from the C++ Standard would be especially appreciated.
8
7830
by: __PPS__ | last post by:
Hello everybody, today I had another quiz question "if class X is privately derived from base class Y what is the scope of the public, protected, private members of Y will be in class X" By scope they meant public/protected/private access modifiers :) Obviously all members of the base privately inherited class will be private, and that was my answer. However, the teacher checked my answers when I handed in, and the problem was that I had...
22
23384
by: Matthew Louden | last post by:
I want to know why C# doesnt support multiple inheritance? But why we can inherit multiple interfaces instead? I know this is the rule, but I dont understand why. Can anyone give me some concrete examples?
45
6368
by: Ben Blank | last post by:
I'm writing a family of classes which all inherit most of their methods and code (including constructors) from a single base class. When attempting to instance one of the derived classes using parameters, I get CS1501 (no method with X arguments). Here's a simplified example which mimics the circumstances: namespace InheritError { // Random base class. public class A { protected int i;
6
2101
by: VR | last post by:
Hi, I read about Master Pages in ASP.Net 2.0 and after implementing some WinForms Visual Inheritance I tryed it with WebForms (let's say .aspx pages, my MasterPage does not have a form tag itself so, cannot be called a WebForm itself, the child pages will implement forms). I created a Master.aspx page and removed all HTML from it, added some code to the .aspx.vb file to add controls to my page. Then I created a Child.aspx and changed the...
5
2473
by: Noah Roberts | last post by:
Is there anything that says that if you virtually inherit from one class you have to virtually inherit from anything you inherit from?
3
1841
by: RSH | last post by:
I have a simple question regarding inheritance in a web form. I have a DropDownList in an aspx form. It is called DropDownList1 I have a class that will be overriding the render event so I have a snippet of this class: Public Class CustomDDL Inherits DropDownList
8
328
by: RSH | last post by:
Hi, I am working on some general OOP constructs and I was wondering if I could get some guidance. I have an instance where I have a Base Abstract Class, and 4 Derived classes. I now need to make a list class that will store the objects. My question is how do I go about creating the list class...I am assuming it should be a standalone class that uses an arraylist to store the objects. If I go that route how do I instantiate the...
0
9454
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10270
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10109
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10051
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9916
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7464
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5486
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4017
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3611
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.