# follow up on
# https://medium.com/@cscalfani/goodbye-object-oriented-programming-a59cda4c0e53#.5os988r69
# this, however, is a bit "artificial" example (as it can be simply solved by not defining derived add_all method)
# more realistic scenario would be something like
# http://stackoverflow.com/questions/20822850/change-python-mro-at-runtime


class Array(object):
    def __init__(self):
        self._a = []
    
    def add(self, element):
        self._a.append(element)
        
    def add_all(self, elements_list):
        for i in elements_list:
            #self._a.append(i) #this will work fine
            self.add(i) #this will fail the derived class
            
class ArrayCount(Array):
    def __init__(self):
        super(ArrayCount, self).__init__()
        self._count = 0
    
    def add(self, element):
        super(ArrayCount, self).add(element)
        self._count += 1
    
    def add_all(self, elements_list):
        super(ArrayCount, self).add_all(elements_list)
        self._count += len(elements_list)


if __name__ == '__main__':
    arr = ArrayCount()
    n = 4
    arr.add_all(range(n))
    assert arr._count == n, 'Expected {}, got {}'.format(n, arr._count)