The theory teaches that "composition" is not deriving one class from another, but rather injecting it with an object that is an instance of the class it needs. The class stores that object internally and from there you can safely use it. I try to do it in this example, and I just can't get it right.
# creamos la clase Cuenta
class Cuenta:
# inicializamos los atributos de la clase
def __init__(self,titular,cantidad):
self.titular=titular
self.cantidad=cantidad
# imprimimos los datos
def imprimir(self):
print("Titular: ",self.titular)
print("Cantidad: ", self.cantidad)
#****************************************************************
# creamos la clase CajaAhorro
# esta clase hereda atributos de la clase Cuenta
class CajaAhorro():
# iniciamos los atributos de la clase
def __init__(self,titular,cantidad, cuenta):
self.cuenta = cuenta
# imprimimos los datos de la cuenta
def imprimir_datos_cuenta(self):
print("Cuenta de caja de ahorros")
super().imprimir()
# *****************************************************************
# creamos la clase PlazoFijo
# esta clase también hereda atributos de la clase Cuenta
class PlazoFijo():
# inicializamos los atributos de la clase
def __init__(self,titular,cantidad,plazo,interes, caja_ahorro):
self.caja_ahorro = caja_ahorro
self.plazo=plazo
self.interes=interes
# calculamos la ganancia
def ganancia(self):
ganancia=self.cantidad*self.interes/100
print("El importe de interés es: ",ganancia)
# imprimimos los resultados
def imprimir(self):
print("Cuenta a plazo fijo")
super().imprimir()
print("Plazo disponible en días: ",self.plazo)
print("Interés: ",self.interes)
self.ganancia()
# bloque principal
cuenta = CajaAhorro("Manuel",5000)
caja_ahorro = CajaAhorro(cuenta)
plazo_fijo = PlazoFijo(caja_ahorro)
plazo_fijo.imprimir_datos_cuenta()
I returned:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-17-2c3c3943cb45> in <module>
52
53 # bloque principal
---> 54 cuenta = CajaAhorro("Manuel",5000)
55 caja_ahorro = CajaAhorro(cuenta)
56 plazo_fijo = PlazoFijo(caja_ahorro)
TypeError: __init__() missing 1 required positional argument: 'cuenta'
I will appreciate help to clarify and fix this concept.
Let's examine the data model first.
A Savings Bank contains deposits of various types in the name of various holders. The correct model contains three classes: Savings Bank, Deposit and Holder, since a person can have several deposits and the Savings Bank contains deposits from many people.
Holder Class
The title class is the easiest. In real life, data such as your ID, address, etc. would have to be included.
Important: it is not printed inside classes. What it does is return a string that can be used to print, or send by email, etc. That's why we define the function
__str__
for all classes.When you write
print(algo)
, what Python does is look up the method__str__
of the objectalgo
, call it to get a string which will then be printed.Account Class
The Account class must include all methods to be used in derived classes; for that reason I included the method
ganancia
, since every account has a profit, even if it is zero.Fixed Term Class
This class derives from account, and what it does is model a fixed-term deposit with a certain interest.
SavingsBox Class
This class is a container for accounts (deposits actually). All we need is a name for the box.
Since the class is a container for accounts, we add the method
add
to add a new account.show
Let's see how everything works when Manuel decides to take two time deposits:
produces
Edition: Composition/Inheritance
The class
CuentaAhorro
is essentially a list ( composition ) of class objectsCuenta
. The classCuentaAhorro
does not inherit or duplicate any methods of the classlist
used to store the accounts.The class
Cuenta
illustrates both composition (incorporates an objectTitular
) and inheritance; has a subclass ofCuentaFija
.Each technique has its application.