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))