26 - POO - Colaboración de clases

Normalmente un problema resuelto con la metodología de programación orientada a objetos no interviene una sola clase, sino que hay muchas clases que interactúan y se comunican.

Plantearemos problemas separando las actividades en dos clases.

Problema 1

Un banco tiene 3 clientes que pueden hacer depósitos y extracciones. También el banco requiere que al final del día calcule la cantidad de dinero que hay depositado.

Lo primero que hacemos es identificar las clases:
Podemos identificar la clase Cliente y la clase Banco.

Luego debemos definir las propiedades y los métodos de cada clase:

Cliente		
    propiedades
        nombre
        monto
    métodos
        depositar
        extraer
        imprimir

Banco
    propiedades
        3 Cliente (3 objetos de la clase Cliente)
    métodos
        operar
        depositosTotales

Proyecto119 - Principal.kt

class Cliente(var nombre: String, var monto: Float) {

    fun depositar(monto: Float) {
        this.monto += monto
    }

    fun extraer(monto: Float) {
        this.monto -= monto
    }

    fun imprimir() {
        println("$nombre tiene depositado la suma de $monto")
    }
}

class Banco {
    val cliente1: Cliente = Cliente("Juan", 0f)
    var cliente2: Cliente = Cliente("Ana", 0f)
    var cliente3: Cliente = Cliente("Luis", 0f)

    fun operar() {
        cliente1.depositar(100f)
        cliente2.depositar(150f)
        cliente3.depositar(200f)
        cliente3.extraer(150f)
    }

    fun depositosTotales() {
        val total = cliente1.monto + cliente2.monto + cliente3.monto
        println("El total de dinero del banco es: $total")
        cliente1.imprimir()
        cliente2.imprimir()
        cliente3.imprimir()
    }
}

fun main(parametro: Array<String>) {
    val banco1 = Banco()
    banco1.operar()
    banco1.depositosTotales()
}

Primero hacemos la declaración de la clase Cliente, al constructor principal llegan el nombre del cliente y el monto inicial depositado (las propiedades las estamos definiendo en el propio constructor):

class Cliente(var nombre: String, var monto: Float) {

El método que aumenta la propiedad monto es:

    fun depositar(monto: Float) {
        this.monto += monto
    }

Y el método que reduce la propiedad monto del cliente es:

    fun extraer(monto: Float) {
        this.monto -= monto
    }

Para mostrar los datos del cliente tenemos el método:

    fun imprimir() {
        println("$nombre tiene depositado la suma de $monto")
    }

La segunda clase de nuestro problema es el Banco. Esta clase define tres propiedades de la clase Cliente (la clase Cliente colabora con la clase Banco):

class Banco {
    val cliente1: Cliente = Cliente("Juan", 0f)
    var cliente2: Cliente = Cliente("Ana", 0f)
    var cliente3: Cliente = Cliente("Luis", 0f)

El método operar realiza una serie de depósitos y extracciones de los clientes:

    fun operar() {
        cliente1.depositar(100f)
        cliente2.depositar(150f)
        cliente3.depositar(200f)
        cliente3.extraer(150f)
    }

El método que muestra cuanto dinero tiene depositado el banco se resuelve accediendo a la propiedad monto de cada cliente:

    fun depositosTotales() {
        val total = cliente1.monto + cliente2.monto + cliente3.monto
        println("El total de dinero del banco es: $total")
        cliente1.imprimir()
        cliente2.imprimir()
        cliente3.imprimir()
    }

En la funciób main de nuestro programa procedemos a crear un objeto de la clase Banco y llamar a los dos métodos:

fun main(parametro: Array<String>) {
    val banco1 = Banco()
    banco1.operar()
    banco1.depositosTotales()
}

Problema 2

Plantear un programa que permita jugar a los dados. Las reglas de juego son:
se tiran tres dados si los tres salen con el mismo valor mostrar un mensaje que "gano", sino "perdió".

Lo primero que hacemos es identificar las clases:

Podemos identificar la clase Dado y la clase JuegoDeDados.

Luego las propiedades y los métodos de cada clase:

Dado		
    propiedades
        valor
    métodos
        tirar
        imprimir

JuegoDeDados
    atributos
        3 Dado (3 objetos de la clase Dado)
    métodos
        jugar

Proyecto120 - Principal.kt

class Dado (var valor: Int){

    fun tirar() {
        valor = ((Math.random() * 6) + 1).toInt()
        imprimir()
    }

    fun imprimir() {
        println("Valor del dado: $valor")
    }
}

class JuegoDeDados {
    val dado1 = Dado(1)
    val dado2 = Dado(1)
    val dado3 = Dado(1)

    fun jugar() {
        dado1.tirar()
        dado2.tirar()
        dado3.tirar()
        if (dado1.valor == dado2.valor && dado2.valor == dado3.valor)
            println("Ganó")
        else
            print("Perdió")
    }
}

fun main(parametro: Array<String>) {
    val juego1 = JuegoDeDados()
    juego1.jugar()
}

La clase Dado define un método tirar que almacena en la propiedad valor un número aleatorio comprendido entre 1 y 6. Además llama al método imprimir para mostrarlo:

class Dado (var valor: Int){

    fun tirar() {
        valor = ((Math.random() * 6) + 1).toInt()
        imprimir()
    }

La clase JuegoDeDados define tres propiedades de la clase Dado:

class JuegoDeDados {
    val dado1 = Dado(1)
    val dado2 = Dado(1)
    val dado3 = Dado(1)

En el método jugar de la clase JuegoDeDados procedemos a pedir a cada dado que se tire y verificamos si los tres valores son iguales:

    fun jugar() {
        dado1.tirar()
        dado2.tirar()
        dado3.tirar()
        if (dado1.valor == dado2.valor && dado2.valor == dado3.valor)
            println("Ganó")
        else
            print("Perdió")
    }

En la función main de nuestro programa creamos un objeto de la clase JuegoDeDados:

fun main(parametro: Array<String>) {
    val juego1 = JuegoDeDados()
    juego1.jugar()
}

Problema propuesto

  • Plantear una clase Club y otra clase Socio.
    La clase Socio debe tener los siguientes propiedades: nombre y la antigüedad en el club (en años).
    Al constructor de la clase socio hacer que llegue el nombre y su antigüedad.
    La clase Club debe tener como propiedades 3 objetos de la clase Socio.
    Definir un método en la clase Club para imprimir el nombre del socio con mayor antigüedad en el club.
Solución
Proyecto121

class Socio (val nombre: String, val antiguedad: Int) {
    fun imprimir() {
        println("$nombre tiene una antiguedad de $antiguedad")
    }
}

class Club {
    val socio1 = Socio("Juan", 22)
    val socio2 = Socio("Ana", 34)
    val socio3 = Socio("Carlos", 1)

    fun mayorAntiguedad() {
        socio1.imprimir()
        socio2.imprimir()
        socio3.imprimir()
        print("Socio con mayor antiguedad:")
        when {
            socio1.antiguedad > socio2.antiguedad && socio1.antiguedad > socio3.antiguedad -> print(socio1.nombre)
            socio2.antiguedad > socio3.antiguedad -> print(socio2.nombre)
            else -> print(socio3.nombre)
        }
    }
}

fun main(parametro: Array<String>) {
    val club1 = Club()
    club1.mayorAntiguedad()
}