When we define a subclass, we are often extending some superclass
to add features. One common design pattern is to do this by defining a
subclass to use parameters in addition to those expected by the
superclass. We must reuse the superclass constructor properly in our
subclass.
Referring back to our Card
and
FaceCard
example in the section called “Inheritance”, we wrote an initializer in
FaceCard
that referred to
Card
. The __init__
function
evaluates super(FaceCard,self).__init__
, passing
the same arguments to the Card
's
__init__
function.
As an aside, in older programs, you'll often see an alternative to
the super
function. Some classes will have an
explicit call to Card.__init__( self, r, s )
. Normally, we
evaluate object.method()
, and the
object
is implicitly the
self
parameter. We can, it turns out, also
evaluate Class.method( object )
. This provides the
object
as the self
parameter.
We can make use of the techniques covered in the section called “Advanced Parameter Handling For Functions” to simplify our subclass initializer.
class FaceCard( Card ):
"""Model a 10-point face card: J, Q, K."""
def __init__( self, *args ):
super(FaceCard,self).__init__( *args )
self.label= ("J","Q","K")[self.rank-11]
self.pval= 10
def __str__( self ):
return "%2s%s" % ( self.label, self.suit )
In this case we use the def __init__( self, *args )
to capture all of the positional parameters in a single list,
args
. We then give that entire list of positional
parameters to Card.__init__
. By using the
*
operator, we tell Python to explode the list into
individual positional parameters.
Let's look at a slightly more sophisticated example.
Example 22.4. boat.py
class Boat( object ):
def __init__( self, name, loa ):
"""Create a new Boat( name, loa )"""
self.name= name
self.loa= loa
class Catboat( Boat )
def __init__( self, sailarea, *args ):
"""Create a new Catboat( sailarea, name, loa )"""
super(Catboat,self).__init__( *args )
self.mainarea= sailarea
class Sloop( CatBoat ):
def __init__( self, jibarea, *args );
"""Create a new Sloop( jibarea, mainarea, name, loa )"""
super(Sloop,self).__init__( *args )
self.jibarea= jibarea
|
The Boat class defines essential attributes for all
kinds of boats: the name and the length overall (LOA).
|
|
In the case of a Catboat , we add
a single sail area to be base definition of
Boat . We use the superclass
initialization to prepare the basic name and length overall
attributes. Then our subclass adds the sailarea for the single
sail on a catboat.
|
|
In the case of a Sloop , we add
another sail to the definition of a
Catboat . We add the new parameter first
in the list, and the remaining parameters are simply given to
the superclass for its initialization.
|