En los ejercicios que se presentan a continuación, se especifican el tipo de las variables utilizadas ya que algunos lenguajes de programación -a diferencia de Python
- son tipados. No tengáis en cuenta estos detalles cuando consideréis que no son necesarios.
Construye una clase de nombre CuentaCorriente
que permita almacenar los datos asociados a la cuenta bancaria de un cliente, e interactuar con ellos. Este es nuestro ADT.(POO). Este documento [Working Classes] te ayudará no sólo a tomar estas decisiones de manera rápida, sino también a construir una arquitectura de la aplicación que respete los principios [SOLID].
Cómo manejar los errores y la programación por contrato, en el documento [Programación Defensiva].
Aplicad los principios SOLID que ya conocéis:
SRP
(S) o Principio de Única Responsabilidad (Single responsibility principle): una clase sólo debe tener un motivo para cambiar.
Esta clase tendrá las siguientes propiedades, métodos y constructores:
- Propiedades privadas (de momento, en Python nos da igual que sean privadas):
nombre, apellidos, dirección, teléfono
: todas de tipostring
.NIF
: objeto instancia de la claseDNI
que resolvimos en clase**. Se trata de una relación “Has-A” o “Tiene-una”.saldo
: de tipodouble
.
- Constructores (inicializador en Python):
- Constructor que por defecto inicializa las propiedades de la clase (programación defensiva).
- Constructor al que se le pasen como argumentos todas las propiedades que tiene la clase.
- Métodos públicos:
set()
yget()
para todas las propiedades de la clase [Abstracción y encapsulamiento].retirarDinero()
: resta al saldo una cantidad de dinero pasada como argumento.ingresarDinero()
: añade al saldo una cantidad de dinero.consultarCuenta()
: visualizará los datos de la cuenta.saldoNegativo()
: devolverá un valor lógico indicando si la cuenta está o no en números rojos.
** Puedes reutilizar la clase DNI
que construimos en clase para definir la clase NIF mediante [herencia], si es que fuese necesario alguna especialización o cambio en la clase DNI
. Evalúa si es posible reutilizarla tal cual.
Construye una clase de nombre Hora
que permita almacenar la hora, así como los métodos para manipularla (este es nuestro ADT). Tendrá las siguientes propiedades y métodos:
- Propiedades (todas ellas privadas):
hora
: de tipo entero (00 - 24)minutos
: de tipo entero (00 - 59)segundos
: de tipo entero (00 - 59)
- Constructor (inicializador en Python):
- Constructor que, por defecto, inicialice las propiedades de la clase a 0 [programación defensiva].
- Constructor al que se le pasen como argumentos tres enteros y se los asigne a las propiedades de la clase. Si la cantidad recibida no satisface las restricciones de los valores impuestos a
horas, minutos y segundos
, el valor que se fija es 0 [Manejo de errores]: devolver un valor neutro, aunque en este caso no lo sea.
- Métodos de la clase (públicos):
setHora()
: recibe como argumentos tres enteros y se los asigna a las propiedades de la clase. Utiliza el mismo nombre en las variables que reciben los argumentos y en las propiedades de la clase. Este método ha de diseñarse mediante programación por contrato, es decir, debe incluir una precondición: si los valores recibidos no satisfacen las restricciones de los valores impuestos ahoras, minutos y segundos
, el valor que se establece es 0 [Manejo de errores: devolver un valor neutro, aunque en este caso no lo sea]. Ya que va a ser utilizado en el cosntructor, este precondición podría implementarse en su propia rutina para ser llamada desde este método y desde el "constructor".getHora()
: devuelve la hora como unalista
de la forma[horas, minutos, segundos]
o como unstring
de la forma"horas:minutos:segundos"
.imprmirHora()
que muestra en consola la hora en formatostring
de la forma"horas:minutos:segundos"
.- Métodos
set() y get()
para todas las propiedades [Abstracción y encapsulamiento].
Construye una clase de nombre TarjetaPrepago
que permita interactuar con la información almacenada en una tarjeta de telefonía móvil prepago (este es nuestro ADT).
Esta clase tendrá las siguientes propiedades, métodos y constructores:
- Propiedades privadas:
numeroTeléfono
: de tipostring
.NIF
: objeto instancia de la claseDNI
que resolvimos en clase**. Se trata de una relación “Has-A” o “Tiene-una”saldo
: de tipodouble
(en euros).consumo
: objeto instancia de la claseHora
, para almacenar las horas, minutos y segundos consumidos. Se trata de otra relación “Has-A” o “Tiene-una”. Reutiliza la claseHora
que has construído en el ejercicio anterior.
- Constructores:
- Constructor que inicializa las propiedades de la clase (programación defensiva).
- Constructor que recibe como argumentos los valores para las propiedades de clase
numeroTelefono
,NIF
ysaldo
.
- Métodos públicos:
set()
yget()
para todas las propiedades de la clase [Abstracción y encapsulamiento].ingresarSaldo()
: añade alsaldo
una cantidad de dinero.enviarMensaje()
: recibe como argumento un entero que representa un número de mensajes a enviar, y resta al saldo 9 céntimos por mensaje.realizarLlamada()
: recibe un entero que representa el número de segundos hablados. Se restará alsaldo
la cantidad correspondiente calculada en base a 15 céntimos por establecimiento de llamada y 1 céntimo por segundo. También se actualizará la propiedadconsumo
.consultarTarjeta()
: visualizará todos los datos de la tarjeta en consola.
- Métodos privados.
- Necesitarás un método que se encargue de la responsabilidad de convertir la hora (hora:minutos:segundos) a segundos para poder sumar la duración de la llamada al total de la duración de las llamadas en la propiedad
consumo
. - Haz uso de todos aquellos métodos privados que estimes necesarios.
Construye una clase de nombre Fecha
que represente el tipo de dato abstracto ADT fecha como tres enteros de nombres dia
, mes
y año
. Estas serían las propiedades de la clase.
- Propiedades (todas ellas privadas):
dia
: de tipo entero (01 - 31)mes
: de tipo entero (01 - 12)año
: de tipo entero (1900 - 3000)
- Constructor (inicializador en Python):
- Constructor que, por defecto, inicialice las propiedades de la clase a la fecha 01-01-1900 [programación defensiva].
- Constructor al que se le pasen como argumentos tres enteros y se los asigne a las propiedades de la clase. Si la cantidad recibida no satisface las restricciones de los valores impuestos a
dia
,mes
yaño
, el valor que se fija es 01 o 1900 [Manejo de errores]: (devolver un valor neutro, aunque en este caso no lo sea).
- Métodos de la clase (públicos):
- Método de nombre
setFecha()
que recibe como argumentos tres enteros y se los asigna a las propiedades de la clase (utiliza el mismo nombre en las variables que reciben los argumentos y en las propiedades de la clase). Este método ha de diseñarse mediante programación por contrato, es decir, debe incluir una precondición: si los valores recibidos no satisfacen las restricciones de los valores impuestos adia
,mes
yaño
, el valor que se establece es 01 o 1900 [Manejo de errores: devolver un valor neutro, aunque en este caso no lo sea]. Ya que va a ser utilizado en el cosntructor, este precondición podría implementarse en su propia rutina para ser llamada desde este método y desde el "constructor". - Métodos
set() y get()
para todas las propiedades [Abstracción y encapsulamiento]. incrementarFecha()
: recibe un entero que representa un número de días e incrementa la fecha en dicha cantidad de dias.imprimirFecha()
: escribe la fecha en el formatodia-mes-año
en consola. Se mostrará el nombre del mes, no el número.- método privado
mesLetra()
que devuelve el mes en letras asociado al mes numérico guardado en una determinada instancia (objeto) de la clase; este método será invocado desdeimprimirFecha()
. - método
getFecha()
que devuelve unstring
que contenga la fecha en el formato dia-mes-año.
- El capítulo 28 del [libro de Python][6] que seguimos se desarrolla un ejercicio mediante el que se ilustran los conceptos de POO. Conviene que le echéis un ojo.
- En el capítulo 27 se explican los conceptos básicos de la POO.