[Tutor] OOP Advice

Daniel Yoo dyoo@hkn.eecs.berkeley.edu
Wed, 7 Mar 2001 02:54:53 -0800 (PST)


Hello!  Ok, let's do a quick scan through your program.  (Some of my code
assumes Python 1.52, so there are probably better ways of writing the code
if you're using a more recent version of Python.)


On Tue, 6 Mar 2001, JRicker wrote:

> class Unit:
>     """
>     Base class of units.  Should not be used only inherited from
>     """
> 
>     XPos = -1 #x location of unit, -1 not on game board
>     YPos = -1 #y loaction of unit, -1 not on game board

In Python, you don't need to predeclare member variables.  I'm guessing
that every Unit should their own separate XPos and YPos.  What you have
right now defines a class variable XPos, YPos for all Units.

Most likely, you don't need those two lines.



>     def ChangeFacing(self, d):
>         if d == -1:
>             if self.Facing == 1:
>                 self.Facing = 6
>             else: self.Facing = self.Facing - 1

There's a slightly nicer way of defining direction, but it involves using
angles and trigonometry.  *shudder*  Seriously though, it will help if you
use angles to define your facing direction.  If we do so, then our move
function becomes a lot more direct and clean:

###
def Move(self):
    self.XPos = self.XPos + cos(self.Facing)
    self.YPos = self.YPos + sin(self.Facing)
###

This assumes that self.Facing now represents the angle (in radians) where
the ship's directed at.  Turning left or right, then, represents adding
and subtracting the quantity pi/2.0 (90 degrees) from the Facing.  Math:
it's actually useful!  *grin*


> My question is this,  Is there a way to set up the init function in unit
> to handle most of the initialization of the object and the rest done by
> the object?  How do I structure things so that Unit is doing most of the
> work?

Yes, Unit can itself have a constructor that does most of the work.  This
way, when we make extensions to Unit, we can still initialize the Unitness
of an object.

All units, at the moment, appear to have inital XPos and YPos, so we can
put that there:

# within Unit definition:
###
    def __init__(self, XPos, YPos):
        self.XPos, Self.Ypos = XPos, YPos
        ## and do other common initialization of Units here
###

If we have something like this, we can take advantage of it in our
inherited classes:

# within Ship definition
    def __init__(self, x, y, f):
        Unit.__init__(self, x, y)   ## Let's call the parent's initializer
        ## and now we can do specific stuff for ships here.


So we can call our parent's initializer directly, passing it the
appropriate arguments.

Hope this helps!