blueFast
blueFast

Reputation: 44501

Derived class with differing interface

The following code:

class Cache:

    def __init__(self):
        self._cache = []

    def store(self, data):
        self._cache.append(data)

    def stats(self):
        print('We are caching {} elements'.format(len(self._cache)))


class LegoCache(Cache):

    def store(self, weight, color):
        Cache.store(self, (weight, color))

has a problem in that the store method does not implement the interface of the base class.

How can this code be improved? I have the following ideas:

Are there other alternatives?

EDIT

The base class must also support this other use case:

class ZombieCache(Cache):

    def store(self, dead_since, humans_eaten, can_be_saved=False):
        Cache.store(self, dict(
            dead_since=dead_since, 
            humans_eaten=humans_eaten, 
            can_be_saved=can_be_saved))

Upvotes: 1

Views: 48

Answers (2)

Ghazanfar
Ghazanfar

Reputation: 1469

I would implement it like this,

class Cache:

  def __init__(self):
      self._cache = []

  def store(self, data):
      self._cache.append(data)

  def stats(self): 
      print('We are caching {} elements'.format(len(self._cache)))


class LegoData(object):

  def __init__(self, weight, color):
      self.weight = weight
      self.color = color

class LegoCache(Cache):
   pass

Client will access it like this,

lego_cache = LegoCache()
lego_cache.store(LegoData(weight=10, color='Green'))

Upvotes: 0

clemens
clemens

Reputation: 17722

You may use a variable argument list in the base class:

class Cache:

    def __init__(self):
        self._cache = []

    def store(self, *args):
        self._cache.append(args)

    def stats(self):
        print('We are caching {} elements'.format(len(self._cache)))

class LegoCache(Cache):
    pass
    # "overloading" store isn't needed

So it isn't needed to overload this method or add methods with different names for specials cases:

cache = Cache()
legoCache = LegoCache()

cache.store(x)
legoCache.store(x, y)

Another solution may be delegation:

class LegoCache(object):
    def __init__(self):
        self.cache = Cache()

    def store(self, weight, color):
        self.cache.store((weight, color))
        # or just self.cache.store(weight, color) if you use the *args implementation

Upvotes: 2

Related Questions