[Tutor] class design - base classes with optional properties?
alan.gauld at btinternet.com
Fri Jan 23 00:24:22 CET 2009
"Marcus Goldfish" <magoldfish at gmail.com> wrote
> I'm trying to design a base class for a hierarchy. The properties I
> want to
> specify for the base class depend on the values of other properties
> of the
> base class.
Don't worry so much about the properties, the important thing to focus
in your base classes is the behaviour. What exactly will these classes
What methods will they have? How will they be overridden in your
Ideally the properties are invisible to the users of the class so the
interactions of the properties should all be controlled by the
> class FoodProcessor:
> "Model for a kitchen appliance food processor"
> speed_settings # example [1, 2, 3, 4]
> blade_settings # example ["slice", "grate", "grind"]
> slice_thickness # example ["thin", "thick"], but only if
> blade_setting is "slice"
> it only make sense to have the slice_thickness property set when
> blade_settings = "slice"; otherwise, it would be preferable to only
> the speed_settings and blade_settings properties. For example:
So create a method to initialise slicing which sets both properties
(with appropriate default values if you like)
Similarly define methods for grating and grinding. Think about
what you want to *do* with a class not what you want to store.
The function should dictate the attributes.
> class ProcessorA(FoodProcessor):
> "A slicing-only processor"
> speed_settings = [1, 2, 3, 4]
> blade_settings = "slice"
> slice_thickness = ["thin", "thick"]
> class ProcessorB(FoodProcessor):
> "A non-slicing processor"
> speed_settings = [1,2,3,4]
> blade_settings = ["grate", "grind"]
> slice_thickness = None
Unless this is a multi function food processor I'd probably
go for a heirarchy of
In fact I might do that anyway and then create
MultiFunction as a subclass of of all 3 food
class MultiFunction(Slicer, Grater, Grinder):
Remember that ideally nothing outside the class should be manipulating
the attributes directly, everything should be done by sending messages
(ie calling methods) to the objects. The fact that you want a
suggests that you have some form of polymorphic operations to be
performed? What are those operations at the abstract FoodProcessor
It is actually very common that the root object in a heirarchy has
few if any attributes but will have all the methods needed for the
to work. As you subclass you add attributes to support the subclass
specific implementation of the methods.
If you truly want a multi purpose mixer and don't want to subclass
all 3 types then you could have a changeBlade method that specifies
the blade type and any additional attributes. The Blades could even
be a class heirarchy in their own right:
# create a new processor with initially a slicer blade
p = FoodProcessor(Slicer(thickness))
p.process(Cheese(5, 'oz')) # uses a Cheese object with weight in
and so on...
But the only real solution will depend on what you intend to do with
your classes. Think about how you want to write the client code.
Think about doing that using method calls rather than manipulating
the inner data. That way you can leverage polymorphism to your
Author of the Learn to Program web site
More information about the Tutor