OOP & Abstract Classes

Nick Craig-Wood nick at craig-wood.com
Mon May 11 14:30:04 EDT 2009


Adam Gaskins <agaskins_ng at kelleramerica.com> wrote:
>  I am a fairly seasoned PHP developer (don't shoot, I'm changing teams!:) who 
>  is admittedly behind the curve with OOP. Like most who learned PHP, I 
>  started doing web app backend stuff, but I have moved to full blown windows 
>  apps in the last 6 months using Winbinder. As you may know Winbinder is 
>  essentially abandoned, and programming windows apps with Winbinder or even 
>  GTK-PHP is less than ideal. I also deal heavily in serial/rs-232 
>  communications which is a pain in PHP. Long story short, I'm tired of doing 
>  things in such a hackish manner and want to write applications that are 
>  cross platform (I'd like to get our production dept on linux eventually) and 
>  truely object oriented.
> 
>  So I was beginning to learn OOP for PHP, and it seemed to me that abstract 
>  classes were just right for my application. In my application I must 
>  communicate with several peices of test equipment that communicate via 
>  RS-232. Most use SCPI instructions, some do not and require low level 
>  communication.
> 
>  The way I understand abstract classes is that I could have a class that has 
>  all my abstract methods such as 'init', 'getMeasurement', 'setPressure', 
>  etc... then I could use this common interface to to control my different 
>  pieces of hardware (after I write a library for each of them).
> 
>  Is this a valid application for abstract classes? Or am I making life more 
>  complicated than it need be?

This sounds like a fine use for Abstract classes.

Python doesn't have language support for them directly, but they are
usually written like this

    class DeviceBase(object):
        def __init__(self):
            raise NotImplementedError()
        def getMeasusrement(self):
            raise NotImplementedError()
        def setPressure(self, pressure):
            raise NotImplementedError()

Then subclass it for the real functionality

    class RealDevice(DeviceBase):
        def __init__(self):
            self.pressure = 0
        def getMeasusrement(self):
            return 0
        def setPressure(self, pressure):
            self.pressure = pressure

However, I normally found that there is some functionality that is
common to all subclasses so there may be some real methods in your
DeviceBase class, eg

class DeviceBase(object):
    def __init__(self, device):
        self.device = device
    def getMeasurement(self):
        raise NotImplementedError()
    def setPressure(self, pressure):
        raise NotImplementedError()
    def __repr__(self):
        return "%s(%r)" % (self.__class__.__name__, self.device)

class RealDevice(DeviceBase):
    def __init__(self, device):
        DeviceBase.__init__(self, device)
        self.pressure = 0
    def getMeasurement(self):
        return self.pressure
    def setPressure(self, pressure):
        self.pressure = pressure

Which looks like this when you test it

>>> base = DeviceBase("/dev/ttyS0")
>>> base
DeviceBase('/dev/ttyS0')
>>> base.getMeasurement()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in getMeasurement
NotImplementedError
>>> base.setPressure(14)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in setPressure
NotImplementedError
>>>
>>> real = RealDevice("/dev/ttyS1")
>>> real
RealDevice('/dev/ttyS1')
>>> real.getMeasurement()
0
>>> real.setPressure(14)
>>> real.getMeasurement()
14
>>> 

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list