domingo, 9 de febrero de 2014

Creación de un Banco y Cuentas Bancarias

Buenas, aquí me encuentro otro día más codeando porque me encanta ^^. Esta practica representará un Banco y una Cuenta Bancaria; además de las operaciones que podemos realizar. Aquí teneis el esquema:
Esquema de las clases banco y cuenta en UML

La novedad es que un banco será un array de Cuentas. Un array (por si alguien aún no lo sabe) es un medio de guardar un conjunto de objetos de la misma clase, digamos que es como una "lista ordenada", aunque más adelante veremos que no es así.

Creo que no hay que explicar mucho del esquema. Las variables ppl y unca representan respectivamente la primera posición libre en el array de cuentas (están en posiciones contiguas) y el primer número de cuenta libre, de forma que una vez asignado el número a una nueva cuenta este contador se debe incrementar.
El valor inicial de unca será el de la constante NUMCTALIBRE (1001).

Cosas a tener en cuenta:

Algunas cuestiones:
  1. • Los constructores de la clase Banco se encargarán de crear el array de cuentas con un tamaño inicial, así como de dar valores iniciales a las variables auxiliares. El segundo argumento del constructor de Banco con dos argumentos indica el tamaño inicial del array de cuentas. En el constructor con un argumento el array se inicializará con un tamaño por defecto (10). 
  2. • La creación de cuentas no debe fallar porque el array esté lleno; en caso de no quedar espacio en el array se creará un array (de doble capacidad) para habilitar más espacio. 
  3. • Un banco no permite que una cuenta quede con saldo negativo. Si se intenta realizar un débito por una cantidad mayor que el saldo, solo se permitirá extraer el saldo. En ese caso, el saldo quedará a 0 y se devolverá el dinero que realmente se ha extraído de la cuenta.
  4. • Para facilitar la implementación de algunos métodos se debe implementar un método llamado posicionCuenta. Éste es un método auxiliar que devuelve la posición dentro del array de cuentas en la que se encuentra la cuenta con el número de cuenta dado como argumento. Si la cuenta no existe, el método debe lanzar una excepción RuntimeException de la siguiente manera:                               "throw new RuntimeException(“No existe la cuenta dada”);"
Aquí teneis la clase para testear que todo esté correcto:

public class TestbancoA {
 public static void main(String[] args) {
  Banco b = new Banco("TubbiesBank", 5);
  int nPo = b.abrirCuenta("Po", 500);
  int nDixy = b.abrirCuenta("Dixy", 500);
  int nTinkyWinky = b.abrirCuenta("Tinky Winky", 500);
  int nLala = b.abrirCuenta("Lala", 500);
  System.out.println(b);
  b.ingreso(nPo, 100);
  b.debito(nDixy, 100);
  b.transferencia(nTinkyWinky, nLala, 100);
  System.out.println(b);
  b.cerrarCuenta(nPo);
  b.ingreso(nDixy,200);
  System.out.println(b);
  }
 }

Bueno. Ahora subo las soluciones. 
Cuidado con leer los Spoilers ;)
.
.
.

Clase Cuenta:

public class Cuenta {
 private String titular;
 private double saldo;
 private int cuenta;
 
 public Cuenta(String tit, int num, double din) {
  titular = tit;
  saldo = din;
  cuenta = num;
 }
 public Cuenta(String tit, int num) {
  titular = tit;
  saldo = 0;
  cuenta = num;
 }

 public void ingreso(double cant) {
  saldo += cant;
 }
 public void debito(double cant) {
  saldo -= cant;
 }
 
 public String titular() {return titular;}
 public double saldo() {return saldo;}
 public int cuenta() {return cuenta;}
 
 public String toString() {
  return titular + " con numero de cuenta " + cuenta + " tiene " + saldo + "€";
 }
}

Clase Banco:

public class Banco {
 private final static int NUMCTALIBRE = 1001;
 private String nombre;
 private int ppl;
 private int unca;
 private Cuenta[] cta;
 
 public Banco(String st) {
  
  cta = new Cuenta[10];
  nombre = st;
  ppl = 0;
  unca = NUMCTALIBRE;
 }
 public Banco(String st, int pos) {
  cta = new Cuenta[pos];
  nombre = st;
  ppl = 0;
  unca = NUMCTALIBRE;
 }
 
 public int abrirCuenta(String nombre){

  if(ppl >= cta.length) {
   Cuenta[] cuentaAux = new Cuenta[cta.length * 2];
   System.arraycopy(cta, 0, cuentaAux, 0, ppl);
   cta = cuentaAux;
  }
  cta[ppl] = new Cuenta(nombre, unca);
  ppl++;
  unca++;
  
  return unca-1;
 }

 public int abrirCuenta(String nombre, double din){

  if(ppl >= cta.length) {
   Cuenta[] cuentaAux = new Cuenta[cta.length * 2];
   System.arraycopy(cta, 0, cuentaAux, 0, ppl);
   cta = cuentaAux;
  }
  cta[ppl] = new Cuenta(nombre, unca, din);
  ppl++;
  unca++;
  
  return unca-1;
 } 

 private int posicionDeCuenta(int num){
  int pos = 0;
  boolean esta = false;
  for(int i = 0; i < ppl; i++){
   if (cta[i].cuenta()==num) pos = i; esta = true;
  }
  if(!esta) throw new RuntimeException("No existe la cuenta dada");
  return pos;
 }
public void cerrarCuenta(int num) {

  int pos = posicionDeCuenta(num);
  for (int i = pos; i<cta.length-2; i++) {
   cta[i]=cta[i+1];
  }
  ppl--;
}

 public void ingreso(int numeroDeCuenta, double din) {
  int pos = posicionDeCuenta(numeroDeCuenta);
  cta[pos].ingreso(din);
 }

 public double debito(int numeroDeCuenta, double din){
  double dineroCargado;
  int pos = posicionDeCuenta(numeroDeCuenta);

  if(cta[pos].saldo()>=din) {cta[pos].debito(din);dineroCargado = din;}
  else {
   cta[pos].debito(cta[pos].saldo());
   dineroCargado = cta[pos].saldo();
  }
  return dineroCargado;
 }

 

 public double saldo(int numeroDeCuenta) {
  int pos = posicionDeCuenta(numeroDeCuenta);
  return cta[pos].saldo();
 }

 public double transferencia(int num1, int num2, double din) { //transfiere din dinero de la cuenta num1 a la cuenta num 2
  double dineroDeTransferencia = this.debito(num1, din);
  this.ingreso(num2, dineroDeTransferencia);
  
  return dineroDeTransferencia;
 }

 public String toString(){
  String res ="Banco " + nombre + ": [  ";
  for(int i = 0; i<ppl; i++) {

    res= res + "\n"+ cta[i].toString();
  }
  return res;
 }

2 comentarios:

  1. En primer lugar felicitaros y agradeceros por esta web.
    Es un gran aporte para quienes aprendemos a programar.

    Una duda..en la clase Banco , en el toString, hay algo mal en el for..lo veo mal estructurado.. debería ser int i=0; i<ppl; y después el resto...además ...ese cierre de etiqueta que se hace con ppl al estilo html? ..creo que hay algún error ahí.

    Otra duda... en el diagrama UML para la clase Banco...mejor dicho...en el enunciado del problema, se especifica que "En el constructor con un argumento el array se inicializará con un tamaño por defecto (10). " dónde se ve reflejado eso en el código?


    Gracias de nuevo por esta gran web y felicitaciones!

    Santi

    ResponderEliminar
  2. Muchas gracias :)
    Lo de las etiquetas HTML es normal ya en mis post... Usamos un script algo extraño para que podais tener el código puesto como lo teneis y da muchos fallos al tener que estar cambiando entre el editor HTML y el normal...

    Lo segundo es cierto. Teníamos un 50 puesto.

    Ya está todo cambiado. Es una alegría ver que éste blog va sirviendo y la gente está aprendiendo con él (a fin de cuentas, si os dais cuenta de errores es porque lo vais entendiendo).

    Bueno un saludo y nos seguimos viendo por aquí ;)

    ResponderEliminar