win32com: subclass a com object?

Samuel A. Falvo II kc5tja at garnet.armored.net
Mon Dec 13 15:14:20 EST 1999


In article <832skg$4bn$1 at nnrp1.deja.com>, tiddlerdeja at my-deja.com wrote:
>Is COM just interface inheritance? What about implementation
>inheritance?

COM isn't even about interface inheritance.  It's about asking the object,
"Just what is it you can do?"  Until you read up on how the methods of
IUnknown work, you'll be perpetually lost in this regard.  I strongly
recommend that you read the first two chapters of the Microsoft Component
Object Model specification (http://www.microsoft.com/com).

However, to answer your question more directly, COM supports a technique
called "aggregation," which is semantically equivalent to implementation
inheritance.  Aggregation is actually somewhat more powerful, as it gives
you all the capabilities of multiple inheritance without the ambiguities
that come from it.  The memory consumed by "an object" need not reside in
one memory space, either -- it could be scattered between address spaces or
between computers on a network.

Aggregation does require a bit more boiler-plate code on the part of the COM
object implementor, but not too much -- and the results are well worth it.
The client of the COM object (that is, the programmer USING the COM object)
doesn't see anything more complicated about the object.

Delegation (which is what you ended up doing in your second Python example)
is another technique to implementation re-use.  However, it's much more
suited for customizing or wrapping an interface in code.  It's roots are in
more traditional object oriented programming examples.  For example:

class foo:
   def __init__(self, a, b, c):
      self.anA = a
      self.aB = b
      self.aC = c
      
   def dump(self):
      print "A is %s" % self.anA
      print "B is %s" % self.aB
      print "C is %s" % self.aC
      
class myFoo( foo ):
   def __init__(self,a,b,c,d,e):
   
      # Note that we /delegate/ to the superclass' __init__ method
      # to initialize the super-object.
      
      foo.__init__(self,a,b,c)
      self.aD = d
      self.anE = e

   def dump(self):
      # Note that we delegate to the superclass' dump() method.
      
      print "The results from dump() is as follows:"

      foo.dump(self)

      print "D is %s" % self.aD
      print "E is %s" % self.anE
      print "There.  All done!"

Both examples above fall under the category of "delegation."  Any library
which promises an object oriented interface to a system service which itself
isn't inherently object oriented is guaranteed to use delegation to do its
work.

Note that you can use aggregation and delegation concurrently in a single
COM object implementation, producing some of the most flexible code re-use
capabilities I'd ever seen.  For example, let's say I want to log all file
access to a particular file.  I can create a "customized file object" which
aggregates a Log object, and delegates a normal File object.  I want to
delegate the file interfaces because I want to "trap" or "hook" the function
calls, so that I can keep a record of what functions are called and when, as
well as actually perform the file operations.  Of course, this could easily
be done with multiple inheritance in traditional object oriented systems,
but the results are semantically the same, with the additional benefit that
there is no confusion as to which method to invoke if multiple interfaces
implement the same method.

-- 
KC5TJA/6, DM13, QRP-L #1447
Samuel A. Falvo II
Oceanside, CA



More information about the Python-list mailing list