Home > Software engineering >  Partial inheritance
Partial inheritance

Time:10-24

I am new to Python but there is something driving me crazy about class inheritance, and all the solutions I find on the web do no work for me, and I am having trouble understanding why.

I have a class, Bond, which has as instances a term that we’ll invest in them, a certain amount that will be invested, a minimum price, a minimum term and yearly interest rate. The subclass LongTerm has minimum term of 2 years, a minimum amount of $250 and a yearly interest of 2.5%.

The following code works correctly:

class Bond(object):
    def __init__(self,minTerm, term,amount,minPrice,yrlyRate):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate

class LongTerm(Bond):
    def __init__(self, term,amount,minPrice, minAmount = 1000, minTerm = 5, yrlyRate = 0.05):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minAmount = minAmount
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate

But when I use the partial inheritance function

super().__init__(term,amount,minPrice)

it shows an error:

TypeError: __init__() missing 2 required positional arguments: 'minPrice' and 'yrlyRate'

Code using super():

class Bond(object):
    def __init__(self,minTerm, term,amount,minPrice,yrlyRate):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate

class LongTerm(Bond):
    def __init__(self, term,amount,minPrice, minAmount = 1000, minTerm = 5, yrlyRate = 0.05):
        super().__init__(term,amount,minPrice)
        self.term = term
        self.amount = amount
        self.minPrice = minPrice

Why should not I be able to partially inherit only some instances of the superclass?

CodePudding user response:

If your subclass requires less information than your superclass than perhaps you need to not use inheritance. In the event that it's not possible to modify the original then perhaps composition would be more helpful.

Method 1. with general class inheritance

class Bond:
    def __init__(self, minTerm, term, amount, minPrice, yrlyRate):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate


class LongTerm(Bond):
    def __init__(self, term, amount, minPrice, minAmount = 1000, minTerm = 5, yrlyRate = 0.05):
        super().__init__(minTerm, term, amount, minPrice, yrlyRate)
        self.minAmount = minAmount

Method 2). With overriding example and defaulting arguments

class Bond:
    def __init__(self, minTerm, term, amount, minPrice, yrlyRate):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate
    
    def short_term_only(self):
        #do some stuff

        
class LongTerm(Bond):
    def __init__(self, term, amount, minPrice, minAmount = 1000, minTerm = 5, yrlyRate = 0.05):
        # In the event that maybe we don't care about some of the information or methods
        # in the parent we can set them to none or even over-ride the methods
        super().__init__(minTerm, None, None, minPrice, yrlyRate)
        self.minAmount = minAmount
        
    def short_term_only(self):
        raise NotImplementedError

Method 3) With class composition. The concern with this method it that methods available to class Bond won't be inherently available to class LongTerm

class LongTerm:
    def __init__(self, term, amount, minPrice, minAmount = 1000, minTerm = 5, yrlyRate = 0.05):
        self.bond = Bond(minTerm, term, amount, minPrice, yrlyRate)
        self.minAmount = minAmount

CodePudding user response:

I think what you need is something like this...

class Bond:
    def __init__(self, term, amount, minPrice, minTerm, yrlyRate):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate

    def __repr__(self):
        return f"Term: {self.term}, Amount: {self.amount}, MinPrice: {self.minPrice}, MinTerm: {self.minTerm}, YearlyRate: {self.yrlyRate}"

class LongTerm(Bond):
    def __init__(self, term, amount, minPrice, minTerm=5, yrlyRate=0.05, minAmount=1000):
        super().__init__(term=term, amount=amount, minPrice=minPrice, minTerm=minTerm, yrlyRate=yrlyRate)
        self.minAmount = minAmount

print(LongTerm(term=1, amount=23, minPrice=45.2))
  • Related