Foros aprenderaprogramar.com
Aprender a programar => C, C++, C#, Java, Visual Basic, HTML, PHP, CSS, Javascript, Ajax, Joomla, MySql y más => Mensaje iniciado por: jupertivo en 17 de Abril 2015, 21:34
-
Buenas noches a tod@s. A continuación os transcribo el código que he realizado sobre el ejercicio propuesto en la entrega CU00667B de "Java desde cero".
Clase TestListaCantantesFamosos, con el 'main':
public class TestListaCantantesFamosos {
public static void main (String [ ] args) {
String nombreDeLaLista="\"Cantantes famosos y sus discos más vendidos\"";
EntradaDeTeclado entrada;
CantantesFamosos cantante;
System.out.println("Empezamos el programa. Para salir, pulse 'return'");
ListaCantantesFamosos lista=new ListaCantantesFamosos(nombreDeLaLista);
cantante=new CantantesFamosos();
cantante.setNombre("Madonna");
cantante.setDiscoConMasVentas("All I Want Is You");lista.addNombre(cantante);
cantante=new CantantesFamosos();
cantante.setNombre("Jorge Negrete");
cantante.setDiscoConMasVentas("Jalisco");lista.addNombre(cantante);
System.out.println("La lista se llama: "+nombreDeLaLista);
System.out.println("La lista inicial contiene los siguientes datos: ");
lista.listarTodosLosNombres();
do{ //Bucle do-while para ingresar datos en la lista
System.out.println("\nPor favor, introduzca los datos de otro cantante. Para salir, pulse 'Return'");
entrada=new EntradaDeTeclado();
//Si pulsamos 'RETURN' en cualquiera de las dos entradas,
//el objeto 'CantantesFamosos' actual no se añadirá a la lista
if(entrada.getContinuar()) {//1ª Entrada: Introducción del cantante
cantante=new CantantesFamosos();
cantante.setNombre(entrada.getEntrada());
entrada=new EntradaDeTeclado();
if(entrada.getContinuar()) {//2ª Entrada: Introducción del disco
cantante.setDiscoConMasVentas(entrada.getEntrada());
lista.addNombre(cantante);
System.out.println("\nLa lista actualizada contiene los siguientes datos: ");
lista.listarTodosLosNombres(); } } }
while(entrada.getContinuar()); ////Si pulso 'Return', se acabará la introducción de datos
System.out.println("\nLa lista actualizada contiene los siguientes datos: ");
lista.listarTodosLosNombres();
System.out.println("\nFin del programa"); } }
Clase ListaCantantesFamosos:
import java.util.Iterator;
import java.util.ArrayList;
public class ListaCantantesFamosos { //Clase que representa una lista de objetos 'CantantesFamosos' manejada con la clase ArrayList de Java
private String nombreDeLaLista; //Establecemos un atributo nombre de la lista
private ArrayList<CantantesFamosos>listaCantantesFamosos; //Declaramos un ArrayList que contiene objetos 'CantantesFamosos'
public ListaCantantesFamosos(String nombre) {//Constructor
nombreDeLaLista=nombre;
listaCantantesFamosos=new ArrayList<CantantesFamosos>();}
public void addNombre(CantantesFamosos cantante) {listaCantantesFamosos.add(cantante);}
public void listarTodosLosNombres() {
int i=1;
Iterator<CantantesFamosos>it=listaCantantesFamosos.iterator(); //Creamos el objeto it de tipo Iterator con objetos tipo 'CantantesFamosos'
CantantesFamosos cantante;
while(it.hasNext()) {//'True' si el objeto tratado no es el último
cantante= it.next();
System.out.println("Cantante "+i+": "+cantante.getNombre()+" "+"Disco con más Ventas: "+cantante.getDiscoConMasVentas());
i++; } } }
Clase CantantesFamosos:
public class CantantesFamosos{
private String nombre;
private String discoConMasVentas;
public CantantesFamosos() {} //Constructor vacío
public void setNombre(String valorNombre) {nombre=valorNombre;}
public void setDiscoConMasVentas(String valorDiscoConMasVentas) {discoConMasVentas=valorDiscoConMasVentas;}
public String getNombre() {return nombre;}
public String getDiscoConMasVentas() {return discoConMasVentas;} }
Clase EntradaDeTeclado:
import java.util.Scanner;
public class EntradaDeTeclado {
private String entradaTeclado;
boolean continuar=true;
public EntradaDeTeclado() { //Constructor
entradaTeclado="";
pedirEntrada(); } //Al crear un objeto, se ejecuta este método
public void pedirEntrada() {
Scanner entradaEscaner=new Scanner(System.in);
entradaTeclado=entradaEscaner.nextLine();
if (entradaTeclado.length()==0) {continuar=false;} }
//Si pulso 'Return', no se introducirán más datos
public boolean getContinuar() {return continuar;}
public String getEntrada() {return entradaTeclado;} }
Gracias por vuestra atención. saludos.
-
Hola Jupertivo
He estado leyendo su código, compile, cumple con lo que se pidió, bien, pero he visto algunos fallos en el código, empecemos por clase:
1. En tu clase CantantesFamosos, el titulo de clase siempre se pone en singular, no plural... si hablaras con otro programador y dices "he creado una clase CantantesFamosos" sonara extraño... la clase debería ser CantanteFamoso (No te preocupes, este error lo suelo cometer yo a veces..) compara esto:
he creado un objeto CantantesFamosos.
he creado un objeto CantanteFamoso.
hay que tener en cuenta eso!
2. En la misma clase CantanteFamoso he visto tu constructor vacio... esto no es optimo. Cada vez que invocaras un objeto CantanteFamoso aparecera completamente vacio de datos, el cantante no tendra nombre ni disco famoso... En cambio, con un costructor asi:
public CantanteFamoso(){
nombre = "";
discosConMasVentas = "";
}
Ya es diferente, el cantante famoso tiene nombre y disco. Planteate que el constructor es la "identidad" de la clase, por decirlo así. . Me ha funcionado a mi pensar así. Claro, hay casos en el que se debe poner vacío, pero en este caso cambian las cosas.
3. En tu clase test, observamos ahora lo siguiente, y tiene que ver con el punto anterior del constructor:
System.out.println("Empezamos el programa. Para salir, pulse 'return'");
ListaCantantesFamosos lista=new ListaCantantesFamosos(nombreDeLaLista);
cantante=new CantantesFamosos();
cantante.setNombre("Madonna");
Como tienes el constructor vació, lo que estas haciendo aquí es manipular los atributos directos de clase... esto no es optimo.
Me encanto tu forma de salir del programa por cierto :)
Saludos!
-
Hola Dan_SB. Lo primero, gracias por tus observaciones y pronta respuesta. Da gusto seguir este curso y la interacción que del mismo se hace en el foro. Sois maravillosos.
Sobre los puntos 1 y 2, totalmente de acuerdo. En un principio, inicialicé los atributos de CantanteFamoso en el constructor, como se dijo en las lecciones del curso. Después los quité. No pasará más ;D.
Respecto al punto 3, "manipular los atributos directos de clase... esto no es optimo", ¿no es óptimo manipularlos si antes no los inicializo desde el constructor de la clase 'CantanteFamoso'; o no debiera darles estos valores manualmente desde el 'main' directamente, y sí hacerlo desde el constructor de la clase 'CantanteFamoso'?.
"Me encanto tu forma de salir del programa por cierto :)
Gracias ;)
Y gracias por tu atención y comentarios:"Corregir pequeños errores, evita grandes fracasos" . Saludos.
-
Hola jupertivo, pueden verse distintas situaciones:
a) Lo más normal sería que tuvieras constructores para CantanteFamoso que permitieran crear objetos de distintas maneras. Por ejemplo un constructor vacío que inicializara atributos a 0, "" y false. Otro constructor que permita recibir un String y directamente creara un CantanteFamoso donde el nombre se estableciera al recibido a través del parámetro y el disco con más ventas quedara como "". Y otro constructor que permitiera recibir dos parámetros de modo que se inicializara tanto el nombre como el disco con más ventas.
Pero lo anterior no es obligatorio. En algunos casos podrías decidir hacer lo que has hecho: dejar el constructor vacío e inicializar los atributos usando los métodos set. Esto es válido, digamos que no es lo que se suele hacer porque es menos práctico. Si dispones de constructores puedes inicializar los objetos más rápidamente. Imagínate que en vez de 1 ó 2 atributos tuvieras 4 ó 5. Lo que podrías resolver con un constructor, tendrías que hacerlo usando 4 ó 5 líneas de set (menos práctico).
En resumen:
- Lo más habitual es inicializar objetos a través del constructor (no tener un constructor vacío). No obstante, no está prohibido tener un constructor vacío y crear el objeto y establecer sus atributos con set (aunque los programadores no suelen hacer esto excepto en casos especiales porque es menos práctico).
Salu2
-
Buenos días Ogramar. Da gusto con vosotros. Gracias como siempre por los comentarios.
Si dispones de constructores puedes inicializar los objetos más rápidamente. Imagínate que en vez de 1 ó 2 atributos tuvieras 4 ó 5. Lo que podrías resolver con un constructor, tendrías que hacerlo usando 4 ó 5 líneas de set (menos práctico).
Lógico, claro y conciso. Muchas gracias. Te inserto el código tal y como lo he modificado a este último comentario.
Clase 'TestListaCantantesFamosos':
public class TestListaCantantesFamosos {
public static void main (String [ ] args) {
String nombreDeLaLista="\"Cantantes famosos y sus discos más vendidos\"";
EntradaDeTeclado entrada;
CantanteFamoso cantante;
System.out.println("Empezamos el programa. Para salir, pulse 'return'");
ListaCantantesFamosos lista=new ListaCantantesFamosos(nombreDeLaLista);
cantante=new CantanteFamoso("Madonna","All I Want Is You");
lista.addNombre(cantante);
cantante=new CantanteFamoso("Jorge Negrete","Jalisco");
lista.addNombre(cantante);
System.out.println("La lista se llama: "+nombreDeLaLista);
System.out.println("La lista inicial contiene los siguientes datos: ");
lista.listarTodosLosNombres();
do{ //Bucle do-while para ingresar datos en la lista
System.out.println("\nPor favor, introduzca los datos de otro cantante. Para salir, pulse 'Return'");
entrada=new EntradaDeTeclado();
//Si pulsamos 'RETURN' en cualquiera de las dos entradas,
//el objeto 'CantantesFamosos' actual no se añadirá a la lista
if(entrada.getContinuar()) {//1ª Entrada: Introducción del cantante
cantante=new CantanteFamoso();
cantante.setNombre(entrada.getEntrada());
entrada=new EntradaDeTeclado();
if(entrada.getContinuar()) {//2ª Entrada: Introducción del disco
cantante.setDiscoConMasVentas(entrada.getEntrada());
lista.addNombre(cantante);
System.out.println("\nLa lista actualizada contiene los siguientes datos: ");
lista.listarTodosLosNombres(); } } }
while(entrada.getContinuar()); ////Si pulso 'Return', se acabará la introducción de datos
System.out.println("\nLa lista actualizada contiene los siguientes datos: ");
lista.listarTodosLosNombres();
System.out.println("\nFin del programa"); } }
clase 'CantanteFamoso':
public class CantanteFamoso{
private String nombre;
private String discoConMasVentas;
public CantanteFamoso() {//Constructor 1
nombre="";
discoConMasVentas="";}
public CantanteFamoso(String valorNombre,String valorDiscoConMasVentas) {//Constructor 2
nombre=valorNombre;
discoConMasVentas=valorDiscoConMasVentas;}
public void setNombre(String valorNombre) {nombre=valorNombre;}
public void setDiscoConMasVentas(String valorDiscoConMasVentas) {discoConMasVentas=valorDiscoConMasVentas;}
public String getNombre() {return nombre;}
public String getDiscoConMasVentas() {return discoConMasVentas;} }
La verdad es que es más práctico y elegante así. ¿Le falta o sobra algo?.
-
Lo veo correcto, como hemos comentado es más elegante y más cómodo disponer de constructores que faciliten el trabajo, aunque tampoco es obligatorio. Puede que en ciertos casos se decida no tener constructores o tenerlos vacíos.
Salu2
-
Gracias Ogramar por la atención. Saludos