Autor Tema: ejercicio java programar agenda que tenga un arreglo de 50 posiciones y menú  (Leído 18438 veces)

Dysloke

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 6
    • Ver Perfil
Buenas noches a todos,

Estoy iniciándome en la programación en java y quiero crear un código pero mis conocimientos son limitados. La idea es ver como lo resuelven e ir aprendiendo la sintaxis.

Lo que me gustaría hacer es una agenda que tenga un arreglo de 50 posiciones
 
Un menú con 5 opciones
* Añadir un contacto (empresas o personas) --> Se debe preguntar que va a guardar y pedir los datos necesarios
* Mostrar contacto}
* Editar contacto
* Ver listado completo
* Salir

Los datos son:
Persona (nombre, email, dni, celular).
Empresa (nombre, teléfono fijo, pagina web, numero empresa)

La clase principal debe ser abstracta y en las clases hijas implementar el método abstracto mostrarContacto().

Les pido disculpas por no disponer de un código ya que no sé como comenzarlo. Si alguien me puede ayudar se lo agradeceré

Saludos
« Última modificación: 30 de Enero 2018, 18:31 por Alex Rodríguez »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Ayuda con ejercicio java
« Respuesta #1 en: 05 de Noviembre 2017, 01:12 »
Hola Dysloke.

El ejercicio no es complejo, pero si te lo damos ya hecho, te va a costar más entenderlo que no si intentas hacerlo tú, por supuesto eso sí, con nuestra ayuda.

Al tratarse de un ejercicio con varias clases, ya no es solo cuestión de dominar la sintaxis de Java o la lógica de la programación, si no que hay que decidir como enfocarlo.
Esto no se debe solucionar escribiendo todo el código en un único archivo (se puede, pero no es lo óptimo). Cada clase, se ha de escribir por separado, en su propio archivo .java.

Esto permite además, afrontar el ejercicio separado en partes (divide y vencerás...) de modo que podemos concentrarnos en "pequeñas cosas" en lugar de "un gran todo".

De momento, olvídate del arreglo, y del menú de opciones, etc...eso ya lo veremos después.

Lo suyo es empezar a concentrarnos en las clases básicas. Y una buena forma de organizar ideas antes de empezar a teclear código "a lo loco", es hacerse un diagrama UML.
UML es una serie de convenciones a seguir para crear diagramas que representen las clases de un programa, y como se relacionan entre ellas.
No te preocupes ahora por aprender dichas convenciones, eso es lo de menos... básicamente las clases se dibujan como un cuadrado donde dentro está su nombre, están contenidos los atributos de la clase indicando su tipo (String, int, double, boolean,...) y lo mismo con sus métodos... no necesariamente todos, pero si los principales.

Dichas clases se unen mediante flechas para indicar quien implementa a quien, o quien hereda de quien,.... ahora te pondré unas imágenes y lo entenderás enseguida. Es muy fácil.

Hacer un UML previo, aunque no cumpla convenciones ninguna y esté hecho "a nuestra manera", incluso con un lápiz y papel.... nos permite hacernos una idea de que código necesitaremos escribir y como estructurarlo.

Pero primero, ¿cuál es el objetivo del programa?
El objetivo del programa es registrar y gestionar contactos, que pueden ser personas o empresas.

De aquí, ya podemos deducir que clases básicas necesitamos crear.

La clase "padre" podría ser Contacto. Esta clase tendría dos clases "hijas": Persona y Empresa.

Expresado esto en términos de Programación Orientada a Objetos (POO), Contacto sería la clase abstracta, y de esta heredarían las clases Persona y Empresa.

Bien, la clase Contacto, ¿que atributos debería tener? En principio, lo normal es que tenga los atributos que sean comunes entre sus clases "hijas".

Persona y Empresa son muy diferentes, pero tienen un atributo en común, el nombre
Pues este debería ser el atributo que tenga la clase "padre" Contacto.
Esta clase, además, tendrá al menos el método abstracto mostrarContacto().
También tendrá su constructor y el correspondiente getter y setter para su atributo nombre.

Esta será el diagrama UML de la clase abstracta Contacto:


Tiene un atributo, nombre, de tipo String.

Metodos, como hemos dicho:
  • su constructor, que recibe como parametro el nombre de tipo String -> Contacto(String nombre)
  • el método abstracto -> void mostrarContacto(), que es de tipo void, ya que no devuelve ningún valor, sino que mostrará en pantalla los atributos del objeto.
  • un método getter para poder obtener el nombre del objeto, así que devuelve un String ->String getNombre()
  • un método setter, para poder modificar el nombre si quisieramos, así que recibe un String con el nuevo nombre y no devuelve ningún valor -> void setNombre(String nombreContacto)

Bien, las clases Persona y Empresa, tendrán sus propios atributos (el atributo nombre lo herederá de su "padre" Contacto) y sus própios métodos, incluyendo el método mostrarContacto() que es abstracto. Es decir, lo heredan de su padre Contacto, pero el código de este método será distinto para Persona y Empresa, ya que tienen distintos atributos.
Cada una tendrá sus getters y sus setters.

Esta podría ser la clase Persona:


Y esta la clase Empresa:


Y este sería el diagrama completo, donde se indica que las clases Persona y Empresa, heredan (son hijas) de la clase abstracta Contacto:



Vale, esto ya nos da un "boceto" de las clases básicas (con sus atributos y métodos) que necesitamos para empezar ya a escribir algo de código.

Empezaremos por escribir la clase Contacto. Dices que estás iniciándote y aún no dominas la sintaxis Java.

Bien, esta primera clase te la escribo yo.

Citar
package agendaContactos;

public abstract class Contacto {
   
   //atributo
   private String nombre;
   
   //Constructor
   public Contacto(String nombreContacto)
   {
      nombre = nombreContacto;
   }
   
   //metodo abstracto, sin código, ya lo implementarán sus clases hijas
   public abstract void mostrarContacto();
   
   //metodo para cambiar (setter) el nombre de este contacto
   public void setNombre(String nombreContacto)
   {
      nombre = nombreContacto;
   }
   
   //metodo para obtener (getter) el nombre de este contacto
   public String getNombre()
   {
      return nombre;
   }

}

Como ves, son unas pocas líneas y contienen lo que habíamos establecido en su diagrama UML.

Ahora te invito a que intentes a escribir tú el código de las clases Persona y Empresa.
No tengas miedo a equivocarte, o a no ser capaz de completarlo.
Tú inténtalo.
Si lo completas, bien.
Si te atascas y no sabes terminarlo, no importa. Publica aquí lo que hayas podido escribir y entre todos lo corregimos y te indicamos como continuarlo.

De hecho, es la única forma de aprender. Que te atasques y tengas que preguntar o investigar.
Cuando lees el código de otros ya terminado, normalmente se entiende más o menos casi todo y CREES que ya has aprendido.
Pero no, para aprender tienes que atascarte y equivocarte escribiendo tú el código, y luego preguntar para poder seguir.

Cuanto tengamos las tres clases básicas terminadas, ya pensaremos en como hacer lo del arreglo, el menú de opciones, etc...
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Dysloke

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 6
    • Ver Perfil
Re:Ayuda con ejercicio java
« Respuesta #2 en: 05 de Noviembre 2017, 14:38 »
Buen dia Kabuto,

Segui tus indicaciones y ya tengo creada las persona y empresa. Adjunto los codigos para ver si estan correctos.

Clase persona
Código: [Seleccionar]
public class Persona extends Contacto{
 
    String email;
    int telefonoCelular, dni;

    public Persona(String email, int telefonoCelular, int dni, String nombreCompleto, int ID) {
        super(nombreCompleto, ID);
        this.email = email;
        this.telefonoCelular = telefonoCelular;
        this.dni = dni;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getTelefonoCelular() {
        return telefonoCelular;
    }

    public void setTelefonoCelular(int telefonoCelular) {
        this.telefonoCelular = telefonoCelular;
    }

    public int getDni() {
        return dni;
    }

    public void setDni(int dni) {
        this.dni = dni;
    }

    public String getNombreCompleto() {
        return nombreCompleto;
    }

    public void setNombreCompleto(String nombreCompleto) {
        this.nombreCompleto = nombreCompleto;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }
   
    void mostrarContacto(){
        System.out.println(this.getNombreCompleto() + this.getDni() + this.getEmail() + this.getID() + this.getTelefonoCelular());
       
    }
   
   
}


Clase empresa

Código: [Seleccionar]

public class Empresa extends Contacto{
   
    String webSite;
    int cuit, telefonoFijo;

    public Empresa(int telefonoFijo, String webSite, int cuit, String nombreCompleto, int ID) {
        super(nombreCompleto, ID);
        this.telefonoFijo = telefonoFijo;
        this.webSite = webSite;
        this.cuit = cuit;
    }

    public int getTelefonoFijo() {
        return telefonoFijo;
    }

    public void setTelefonoFijo(int telefonoFijo) {
        this.telefonoFijo = telefonoFijo;
    }

    public String getWebSite() {
        return webSite;
    }

    public void setWebSite(String webSite) {
        this.webSite = webSite;
    }

    public int getCuit() {
        return cuit;
    }

    public void setCuit(int cuit) {
        this.cuit = cuit;
    }

    public String getNombreCompleto() {
        return nombreCompleto;
    }

    public void setNombreCompleto(String nombreCompleto) {
        this.nombreCompleto = nombreCompleto;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }
   
    void motrarContacto(){
        System.out.println("Nombre: " + this.getNombreCompleto() + "Telefono fijo: " + this.getTelefonoFijo() +
                "Pagina Web: " + this.getWebSite() + "CUIT: " + this.getCuit());
    }
   
    void mostrarContacto(){
       
        System.out.println(this.getNombreCompleto() + this.getWebSite() + this.getCuit() + this.getID() + this.getTelefonoFijo());   
    }
   
}


Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Ayuda con ejercicio java
« Respuesta #3 en: 05 de Noviembre 2017, 19:12 »
Hola compañero,

Están correctas.
Solo cabe mencionar unas cositas.

  • Has añadido un nuevo atributo, el ID, que yo no lo puse. Se supone que este atributo pertenece a la clase "padre" Contacto y de hecho en el constructor se lo transmites mediante la instrucción super() al igual que el nombre.
    Esto es correcto.
    Pero entonces a la clase Contacto hay que añadirle dicho atributo, hay que ponerlo también en su constructor, y los metodos setID() y getID() deberían estar escritos en la clase Contacto.
    Las clases Persona y Empresa los heredarán, así que no es necesario que ellas tengan estos métodos.
  • Sobre los atributos y su visibilidad o alcance (scope), la cuál puede ser: private, protected, public o friendly

    Cuando no se pone nada al atributo, tal y como tu has hecho, los estás declarando como friendly. Esto significa que otras clases contenidas en el mismo package podrían acceder directamente a estos atributos sin tener que usar los getters y lo setters.

    ¿Esto es algo malo? Pues no necesariamente. En este caso nos da un poco igual, pero por lo general, lo recomendable es declarar los atributos siempre como private, incluso en los casos en los que nos da igual sea cual sea su visibilidad.
    En determinadas ocasiones nos facilitará el trabajo ampliar la visibilidad de determinados atributos y entonces si podemos aumentarla con protected, friendly o public en casos extremos.
    Pero por "convencionalismo", en principio los atributos deberían ser privados y controlar su acceso mediante los métodos getter y setter.
  • Por último, una reflexión sobre el tipo de dato int.
    Por ejemplo, para telefonoCelular y dni has optado por usar el tipo de dato int, que es un dato numérico.
    Normalmente, nos interesará usar int solo en datos que representen cantidades, valores y/o de los cuáles esperamos hacer algún tipo de operación aritmética. Por ejemplo la edad, peso, estatura, distancias, temperaturas....

    Cuando no sea este el caso, lo más probable es que nos interese más usar el tipo de dato String.
    En principio, no es de esperar que vayamos a hacer operaciones aritméticas con el teléfono o el dni.
    Además, teléfono y dni son susceptibles de incluir simbolos y letras que no son admitidos por el tipo int.

    Por ejemplo para el teléfono puede ser necesario que indiquemos el prefijo del pais, que siempre empieza con un símbolo + --> +34678990011
    O en el caso de una Empresa, además del teléfono principal de esta, quizás también queramos especificar la "extensión" de nuestro contacto --> 934568912 ext:2216
    O especificar más de un teléfono con un separador: 934567890 / 934567891

    Para el dni, lo mismo. Normalmente en la mayoría de paises estos números incluyen letras de control --> 567452390-X
    A veces estas letras de control son importantes para determinar si el dni es de uan persona física, ya sea un particular o un autónomo (quien entonces sería una Empresa) o si es el identificador fiscal de una empresa.

    Otra ventaja de usar String es que luego nos facilita filtrar búsquedas en nuestra Agenda.
    Por ejemplo, quizás queramos listar todos los contactos cuyo teléfono pertenezca a la region de Madrid en España, es decir, los que empiezan por +3491xxxxxx
    O los de Acapulco en México, es decir, los que empiezan por +52744xxxxx

    Este tipo de búsqueda no podemos hacerla con un valor int (al margen de que no admite siquiera el simbolo +), porque no podemos extraer de él cifras numéricas concretas. Un int nos da un valor total, si queremos descomponerlo en cifras separadas, hay que transformarlo en un String.
    Pero entonces, mejor declararlo directamente como String.

    Como digo, esto es solo una reflexión que podemos hacernos a la hora de escoger el tipo de dato de un atributo.
    Aunque sea un atributo tipicamente representado mediante números, esto no implica que debamos usar tipos numéricos como int o double. De hecho, como hemos visto, en muchos casos nos interesa usar String.

Al margen de estos detalles, tu código está correcto.

Ahora viene el siguiente paso.
Ya hemos creado las clases básicas que representan los datos que queremos registrar y gestionar.
Ahora hay que decidir como registrarlos y gestionarlos.

El enunciado que has propuesto indica que usemos un arreglo de 50 posiciones. (Sería más fácil usando por ejemplo un ArrayList, que no hay que indicarle un tamaño fijo, puede ir creciendo y menguando dinámicamente según se añaden o eliminan registros)

Bien, este arreglo se podría declarar directamente en la clase principal main, es decir, la que realiza la ejecución del programa, y escribir en ella los métodos necesarios para mostrar el menú y los métodos para realizar las acciones necesarias: añadir contacto, mostrar, editar, etc...
Esto sería correcto y podría funcionar perfectamente.

Pero quizás sería más interesante crear otra clase, que podríamos llamar Agenda, cuyo atributo sea precisamente el arreglo de 50 posiciones donde se registrarán los Contactos.
Esta clase tendrá además los métodos necesarios para gestionar la Agenda: añadir contacto, mostrarlo, editarlo y listar la agenda completa.

Este podría ser su UML:


Quedando así el diagrama UML completo:



Así que, intenta si quieres crear esta nueva clase Agenda.
Esta clase no es abstracta, no hereda nada de Contacto, ni Contacto hereda nada de Agenda. (Fíjate en el diagrama UML, que las flechas son distintas)

Son clases diferentes, pero están relacionadas porque Agenda incluye a la clase Contacto como tipo de dato para su atributo, que es el arreglo de 50 posiciones.

Esta clase puede ser un poco más dificil de escribir, porque ahora hay que decidir como programar cada una de las funciones.
Por ejemplo, al añadir un nuevo Contacto, ¿como decidimos en que posición del arreglo lo vamos a guardar?
¿Deberíamos usar un segundo atributo, una variable int por ejemplo, que nos diga cuál es la primera posición que está libre en el arreglo?
La primera vez que ejecutemos el programa, la primera posición libre será [ 0 ] porque aún no hay contactos registrados.
Cuando registremos al primer contacto, la siguiente posición libre será [1], luego será [2], etc... así que cada vez que registremos un contacto podemos incrementar esta variable para saber en todo momento la siguiente posicion libre.

O tal vez otra forma podría ser, al inicializar el objeto Agenda, rellenar los 50 registros con valor null.
Y al querer añadir un nuevo Contacto, recorrer el arreglo y ahí donde encontremos el primer valor null disponible, lo cambiamos por el nuevo contacto.
Es otra forma, pero tal vez la primera sea más rápida ya que en todo momento sabremos directamente la primera posición disponible. En cambio en la segunda forma hay que estar buscando registros null cada vez que añadimos contacto nuevo.

Elige la que más te guste, o idea otra forma de hacerlo que te parezca mejor.

Intenta escribir todo lo que puedas para esta clase Agenda y si te atascas en algún sitio, pues aquí estaremos.

Un saludo. :D
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Dysloke

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 6
    • Ver Perfil
Re:Ayuda con ejercicio java
« Respuesta #4 en: 06 de Noviembre 2017, 02:16 »
Kabuto,

He prestado atencion a lo que me has indicado y realice algunos cambios. Lamentablemente llegue a un punto donde me he trabado.

Paso a dejar el codigo completo para que lo veas:

Contacto

Código: [Seleccionar]
abstract public class Contacto {

    String nombreCompleto;
   

    public Contacto(String nombreCompleto) {
        this.nombreCompleto = nombreCompleto;
       
    }

    public String getNombreCompleto() {
        return nombreCompleto;
    }

    public void setNombreCompleto(String nombreCompleto) {
        this.nombreCompleto = nombreCompleto;
    }

       
   abstract void mostrarContacto();
       
   }

Persona
Código: [Seleccionar]
public class Persona extends Contacto{
 
    String email, telefonoCelular, dni;

    public Persona(String email, String telefonoCelular, String dni, String nombreCompleto) {
        super(nombreCompleto);
        this.email = email;
        this.telefonoCelular = telefonoCelular;
        this.dni = dni;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getTelefonoCelular() {
        return telefonoCelular;
    }

    public void setTelefonoCelular(String telefonoCelular) {
        this.telefonoCelular = telefonoCelular;
    }

    public String getDni() {
        return dni;
    }

    public void setDni(String dni) {
        this.dni = dni;
    }

    public String getNombreCompleto() {
        return nombreCompleto;
    }

    public void setNombreCompleto(String nombreCompleto) {
        this.nombreCompleto = nombreCompleto;
    }

   
    void mostrarContacto(){
        System.out.println(this.getNombreCompleto() + this.getDni() + this.getEmail() + this.getTelefonoCelular());
       
    }
   
   
}

Empresa

Código: [Seleccionar]
public class Empresa extends Contacto{
   
    String webSite, cuit, telefonoFijo;

    public Empresa(String telefonoFijo, String webSite, String cuit, String nombreCompleto) {
        super(nombreCompleto);
        this.telefonoFijo = telefonoFijo;
        this.webSite = webSite;
        this.cuit = cuit;
    }

    public String getTelefonoFijo() {
        return telefonoFijo;
    }

    public void setTelefonoFijo(String telefonoFijo) {
        this.telefonoFijo = telefonoFijo;
    }

    public String getWebSite() {
        return webSite;
    }

    public void setWebSite(String webSite) {
        this.webSite = webSite;
    }

    public String getCuit() {
        return cuit;
    }

    public void setCuit(String cuit) {
        this.cuit = cuit;
    }

    public String getNombreCompleto() {
        return nombreCompleto;
    }

    public void setNombreCompleto(String nombreCompleto) {
        this.nombreCompleto = nombreCompleto;
    }

   
    void motrarContacto(){
        System.out.println("Nombre: " + this.getNombreCompleto() + "Telefono fijo: " + this.getTelefonoFijo() +
                "Pagina Web: " + this.getWebSite() + "CUIT: " + this.getCuit());
    }
   
    void mostrarContacto(){
       
        System.out.println(this.getNombreCompleto() + this.getWebSite() + this.getCuit() + this.getTelefonoFijo());   
    }
   
}

Prueba(Main)

Código: [Seleccionar]

import java.util.Scanner;

public class Prueba {
    public static void main(String[] args) {

        int opc = 0, opc2 = 0, indice = 0, idb,ind = 0;
        String nombreCompleto, email,dni, telefonoCelular, telefonoFijo, webSite, cuit;

        Scanner sc = new Scanner(System.in);
        Object agenda[] = new Object[50];

       
        System.out.println(" 1 - Agregar contacto");
        System.out.println(" 2 - Buscar contacto por ID");
        System.out.println(" 3 - Editar contacto");
        System.out.println(" 4 - Mostrar todos los contactos");
        System.out.println(" 5 - Salir");

        try {
            opc = sc.nextInt();
            opc2 = sc.nextInt();

        } catch (Exception e) {
            System.out.println("Utilizar solo numeros para las opciones");
        }

        while (opc >= 0 && opc <= 5) {
            switch (opc) {

                case 1:
                    System.out.println("Seleccione 1 para añadir un contacto persona o 2 para un contacto empresa");
                    opc2 = sc.nextInt();

                    if (opc2 == 1) {
                        System.out.println(" Se ingresara un contacto persona");

                        System.out.println("Ingrese nombre: ");
                        nombreCompleto = sc.next();
                        System.out.println("Ingrese email: ");
                        email = sc.next();
                        System.out.println("Ingrese telefono celular: ");
                        telefonoCelular = sc.next();
                        System.out.println("Ingrese el DNI: ");
                        dni = sc.next();
                       

                        agenda[indice] = new Persona(email, telefonoCelular, dni, nombreCompleto);
                        indice++;
                    }

                    if (opc2 == 2) {
                        System.out.println(" Se ingresara un contacto empresa");
                   

                    System.out.println("Ingrese nombre: ");
                    nombreCompleto = sc.next();
                    System.out.println("Ingrese telefono fijo: ");
                    telefonoFijo = sc.next();
                    System.out.println("Ingrese la pagina web: ");
                    webSite = sc.next();
                    System.out.println("Ingrese el CUIT: ");
                    cuit = sc.next();
                   

                    agenda[indice] = new Empresa(telefonoFijo, webSite, cuit, nombreCompleto);
                    indice++;

                    break;

                case 2:
                     System.out.println("Busqueda por ID: ");
                     idb=sc.nextInt();
                     
                       
                           
                    break;
                           

                case 3:
                         System.out.println("Editar contacto: ");
                   break;

                case 4:
                         System.out.println("Mostrar todos los contacto: ");                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
                  break; 

                case 5:
                    System.out.println("Salir");
                    break;
            }
        }

    }

}
       


Mis dudas en el main son las siguiente:

* El menu necesito que se repita hasta que el usuario decida salir (es algo basico pero no me sale)
* No se como se hace para cuando ya esten cargados los datos, pueda buscar por ID (el indice del array)
* Tampoco se como se editan los contactos
* La cuestion del try y catch no los use nunca y no se si lo que estoy haciendo esta bien o directamente doy asco jeje.

Desde ya te agradezco tu ayuda compañero Kabuto

Saludos

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Ayuda con ejercicio java
« Respuesta #5 en: 07 de Noviembre 2017, 02:01 »
Vamos comentando algunas cosas.

Primero, en la clase Contacto te falta el atributo de ID. Has de incluirlo si luego en el programa queremos buscar contactos por ID.
Otra opcion sería prescindir del ID y buscar por nombre, pero casi queda mejor hacerlo usando un atributo ID.

Segundo, el arreglo lo has declarado de tipo Object. Esto, funciona bien, pero no es lo ideal.
El tipo Object, es algo así como la clase "universal" de Java, todas las clases, incluso las creadas por ti mismo... heredan de la clase Object automaticamente, sin necesidad de indicarlo en ninguna parte.

Esto significa que en ese arreglo, puedes meter objeto de las clases Persona y Empresa sin problemas. Pero también significa que podrías meter un objeto String, un objeto Scanner, un objeto JButton, un objeto JPanel, un objeto Random, un objeto Date.... en definitiva, en ese arreglo se puede meter CUALQUIER cosa.

Lo ideal es limitarlo a las clases con las que queremos trabajar. Estas clases son Persona y Empresa, que todas ellas heredan de la clase abstracta Contacto.
Así que para ello, el arreglo interesa declararlo como de tipo Contacto, esto nos permite meter Personas y Empresas en ese arreglo, y nada más.


Sobre el menu, si queremos que salga varias veces hasta que el usuario decida terminar el programa, no queda otra que incluirlo dentro del bucle.
Puesto que la opción para finalizar el programa es que el usuario introduzca un 5, pues la condición del bucle es que se repita mientras la opcion sea distinta de 5

Sobre el código que estamos escribiendo, siempre es mejor dividirlo en porciones, usando varios métodos, de manera que el main quede reducido al menor número de lineas posibles.
Esto además es útil para que el código sea más legible y nos es más fácil aclarar ideas, pues muchas veces nos atascamos porque tenemos en pantalla tal cantidad de lineas e instrucciones, que la cabeza se nos embota...

Se puede hacer un método que se encargue únicamente de mostrar el menú. No hará nada más, solo eso, mostrar el menú.
Por ejemplo:
Código: [Seleccionar]
static void mostrarMenu()
    {
    System.out.println("\n");
    System.out.println(" 1 - Agregar contacto");
        System.out.println(" 2 - Buscar contacto por ID");
        System.out.println(" 3 - Editar contacto");
        System.out.println(" 4 - Mostrar todos los contactos");
        System.out.println(" 5 - Salir\n");
    }
Los "\n" es para que haga saltos de linea, asi cada vez que se escriba el menu en pantalla saldrá algo separado del texto de la anterior operacion que hubieramos hecho.
Como ves, es un método muy simple, tan solo escribe lineas de texto en pantalla.
Pero al ponerlo por separado, permite reducir lineas en el main, ya que nos bastará una sola linea para llamarlo en lugar de tener que poner las 6 lineas necesarias para escribir el menu.

Luego, podemos hacer otro método que se encargue de pedir la opcion, y de hecho podemos hacer que sea de tipo boolean, de manera que solo devuelva true si se ha introducido una opción válida (numero de 1 a 5).
Si se introduce cualquier otro numero, o una letra, devolverá false y podemos hacer que se repita la petición de la opción mientras este método devuelva false
Este podría ser el método para pedir la opcion:

Código: [Seleccionar]
static boolean pedirOpcion()
    {
    try
    {
    System.out.print("\nIntroduzca opcion: ");
    opcion = sc.nextInt(); sc.nextLine();//Tras leer valores numericos, interesa hacer un nextLine() para limpiar el stream.
    if (opcion >= 1 && opcion <= 5)
    return true;//Ha introducido una opcion valida
    else
    {
    System.out.println("Error. Solo se admite valor entre 1 y 5.");
    return false;//Opcion invalida
    }
    }
    catch(Exception e)
    {
    sc.nextLine();//De nuevo, es necesario limpiar el stream
    System.out.println("Error. Introduzca solo numeros, entre 1 y 5.");
    return false;//Ha introducido letras o simbolos, no números, lo cual provoca una excepcion
    }
    }

Aquí a lo mejor te parece un poco raro eso de hacer "un nextLine() para limpiar el stream".
La clase Scanner es un poco imperfecta, y tras leer valores numéricos, conviene hacer un nextLine() (sin asignar a ninguna variable) si luego queremos leer datos de tipo String (por ejemplo, nombres).
En este otro hilo lo explico un poco más a fondo.

Si quieres ver uno de los problemas que puede ocasionar, cuando el programa ya esté terminado, quita por ejemplo el nextLine() que hay dentro del catch, ejecuta el programa y mete una letra para forzar que ocurra la excepción por no haber metido un numero.
Verás la diferencia entre poner y no poner ese nextLine() que, aparentemente, no parece hacer nada útil....


Y ya puestos, podemos (casi que debemos) hacer un método para cada una de las opciones del menú: mostrar contacto, editar, listar....

Al dividir todo el programa en pequeños métodos (es lo que se llama programación modular), verás que el metodo principal main queda mucho más legible.
Y en caso de cometer algún error u olvidar algo, es mucho más fácil encontrar donde está el error/olvido ya que podemos irnos directamente al método en cuestión, en lugar de tener que recorrer arriba y abajo un metodo main enorme con cientos de lineas.

Si lo dividimos todo en pequeños métodos, que es lo ideal, surge un pequeño problema.
La mayoría de estos métodos necesitan que el arreglo de Contacto y el objeto Scanner para leer datos por teclado estén visibles para ellos.
Si declaramos el arreglo y el Scanner dentro del método main, como has hecho en tu código, estos métodos no podrán verlos, y no podrán acceder a ellos.
Para hacer que si sean visibles y cualquier método tenga acceso a ellos, tenemos que declararlos fuera del main, los declararemos como atributos de la clase Prueba.
Y han de ser declarados con la palabra reservada static, puesto que el main y el resto de método también serán estaticos.

Otras variables, como el int donde guardamos la opcion escogida por el usuario o la que nos dice hasta que posicion del arreglo tenemos Contactos registrados, también necesitarmos que sean visibles para varios métodos.

Si ahora mismo no tienes claro la diferencia entre estatico y no-estatico, no importa, podemos hablar de eso después. De momento centrémonos en hacer funcionar este programa.


Bien, mira, te dejo aquí una nueva clase Prueba, ya organizada, pero sin terminar.

Código: [Seleccionar]
package agendaContactos;

import java.util.Scanner;

public class Prueba {

    static Scanner sc = new Scanner(System.in);
    static Contacto agenda[] = new Contacto[50];
    static int opcion = 0;
    static int indiceArreglo = 0;
   
    public static void main(String[] args) {

        do{
        mostrarMenu();
       
        while(pedirOpcion() == false);
       
        switch(opcion)
        {
        case 1:
        nuevoContacto();
        break;
        case 2:
        buscarContacto();
        break;
        case 3:
        editarContacto();
        break;
        case 4:
        listarContactos();
        break;
        case 5:
        System.out.println("FIN DEL PROGRAMA");
        }
        }while(opcion != 5);

    }//Fin del metodo main()
   
    static void mostrarMenu()
    {
    System.out.println("\n");
    System.out.println(" 1 - Agregar contacto");
        System.out.println(" 2 - Buscar contacto por ID");
        System.out.println(" 3 - Editar contacto");
        System.out.println(" 4 - Mostrar todos los contactos");
        System.out.println(" 5 - Salir\n");
    }
   
    static boolean pedirOpcion()
    {
    try
    {
    System.out.print("\nIntroduzca opcion: ");
    opcion = sc.nextInt(); sc.nextLine();//Tras leer valores numericos, interesa hacer un nextLine() para limpiar el stream.
    if (opcion >= 1 && opcion <= 5)
    return true;//Ha introducido una opcion valida
    else
    {
    System.out.println("Error. Solo se admite valor entre 1 y 5.");
    return false;//Opcion invalida
    }
    }
    catch(Exception e)
    {
    sc.nextLine();
    System.out.println("Error. Introduzca solo numeros, entre 1 y 5.");
    return false;//Ha introducido letras o simbolos, no números, lo cual provoca una excepcion
    }
    }
   
    static void nuevoContacto()
    {
    if (indiceArreglo == 50)
    System.out.println("\nLa Agenda esta llena. No caben nuevos contactos");
    else
    {
    System.out.print("\nIndique si es una (E)mpresa o una (P)ersona (E/P): ");
char opcion = sc.nextLine().toUpperCase().charAt(0);

switch (opcion)
{
case 'E':
agenda[indiceArreglo] = pedirDatosEmpresa();
indiceArreglo++;
break;
case 'P':
agenda[indiceArreglo] = pedirDatosPersona();
indiceArreglo++;
break;
default:
System.out.println("No se reconoce la opcion indicada: " + opcion);
}
    }
    }
   
    static Persona pedirDatosPersona()
    {
    System.out.print("\nIntroduzca ID: ");
int id = sc.nextInt(); sc.nextLine();
System.out.print("Introduzca Nombre: ");
String nombre = sc.nextLine();
System.out.print("Introduzca E-Mail: ");
String email = sc.nextLine();
System.out.print("Introduzca DNI: ");
String dni = sc.nextLine();
System.out.print("Introduzca numero celular: ");
String celular = sc.nextLine();

return new Persona(id, nombre, email, dni, celular);
    }
   
    static Empresa pedirDatosEmpresa()
    {
    System.out.print("\nIntroduzca ID: ");
int id = sc.nextInt(); sc.nextLine();
System.out.print("Introduzca Nombre: ");
String nombre = sc.nextLine();
System.out.print("Introduzca numero tlf fijo: ");
String fijo = sc.nextLine();
System.out.print("Introduzca URL pagina web: ");
String web = sc.nextLine();
System.out.print("Introduzca numero empresa: ");
String nEmpresa = sc.nextLine();

return new Empresa(id, nombre, fijo, web, nEmpresa);
    }
   
    static void buscarContacto()
    {
    /*
    * Comprobar si existe al menos un contacto registrado.
    * Pista: Si indiceArreglo == 0, es que aún no hay Contactos registrados.
    * Si hay contactos en el arreglo:
    * Pedir ID del contacto que se quiere editar.
    * Recorrer arreglo hasta encontrar el Contacto con dicho ID
    * o hasta donde indique indiceArreglo, ya que quizás nos han dado un ID que no existe.
    *
    * Si se encuentra el Contacto, comprobar si es una instancia de Persona o Empresa,
    * hacer casting a la clase que corresponda y mostrar su datos actuales.
    * Pista: la instruccion instanceof nos dice cual es la clase con la que se instancio un objeto
    */
    }
   
    static void editarContacto()
    {
    /*
    * Comprobar si existe al menos un contacto registrado.
    * Pista: Si indiceArreglo == 0, es que aún no hay Contactos registrados.
    * Si hay contactos en el arreglo:
    * Pedir ID del contacto que se quiere editar.
    * Recorrer arreglo hasta encontrar el Contacto con dicho ID
    * o hasta donde indique indiceArreglo, ya que quizás nos han dado un ID que no existe.
    *
    * Si se encuentra el Contacto, comprobar si es una instancia de Persona o Empresa,
    * hacer casting a la clase que corresponda y mostrar su datos actuales.
    * Pista: la instruccion instanceof nos dice cual es la clase con la que se instancio un objeto
    *
    * Decidir si:
    * (Proceso fácil y rápido)
    * - Pedimos todos los datos completos otra vez y directamente sustituimos el contacto en la posicion del arreglo
    * donde encontramos el contacto que se quiere editar.
    * Se puede reaprovechar los métodos pedirDatosPersona() y pedirDatosEmpresa()
    *
    * (Proceso un poco más complejo)
    * - Preguntamos al usuario que atributo quiere modificar y solo nos ocupamos de ese atributo.
    * ESto es más complejo porque habría que mostrar nuevos submenus, distintos si es una Persona o una Empresa
    * y hacer más switch para ver que atributo se ha decidido modificar.
    */
    }
   
    static void listarContactos()
    {
    /*
    * Recorrer arreglo, hasta donde indique la variable indiceArreglo
    * y mostrar los datos de cada Contacto.
    */
    }
   
       
}
       

  • Los objetos y variables que necesitamos sean visibles para todos los métodos, están declarados ya como atributos estáticos.
  • El método principal main, está reducido a tan solo unas pocas líneas ya que todo el código importante estará separado en distintos métodos.
    Consta básicamente de un bucle do..while() (es prácticamente lo mismo que un while()) que se repetirá hasta que el usuario meta un 5 como ocpion.
    Cada vez que se repite:
    - llama al metodo que muestra el menu.

    - llama al metodo que pide opcion al usuario. Este metodo esta puesto como condicion de otro bucle while(), de este modo el metodo se repite cada vez que devuelve false.
    Recuerda que si devuelve false, es porque el usuario ha introducido una opcion equivocada.
    Esta linea te puede parecer un poco rara porque el metodo pedirOpcion() no está DENTRO del bucle while(), si no que está puesto como CONDICION.
    Esta es una forma de simplificar el codigo, en realidad el bucle while() esta vacío, carece de cuerpo.. simplemente comprobará la CONDICION (nuestro método pedirDatos()) una y otra vez hasta que devuelva TRUE, lo que significa que el usuario introdujo una opción válida.

    -Tras pedir opcion, ejecuta un switch y según la opcion introducida, llamará a los distintos métodos que se encargan de crear nuevo contacto, editar, mostrar o listar.
  • Después del main, vienen los métodos.
    El primero, el de dar de alta un contacto, te lo he dejado ya hecho. Fíjate que además se sirve de otros dos métodos que se dedican únicamente a pedir datos para crear y retornar un objeto Persona, o un objeto Empresa.
    Luego lo comentamos un poco más a fondo.
  • El resto de métodos estan sin hacer, aunque he puesto comentarios sobre más o menos los pasos que habría que seguir.
    Intenta hacer tu lo que puedas.
    El metodo de editarContacto es cierto que es un poco más dificil que el resto, en los comentarios ya he puesto que habría que decidir entre dos formas de hacerlo, una más simple y fácil y otra un poco más complicada.
    Podríamos hacer de momento la forma fácil, y una vez que esté terminado todo y funcionando, atrevernos con la forma difícil.
    En realidad esta segunda forma de hacerlo no es dificil, es solo que requiere mucho más código porque habría que presentar un nuevo submenú para que el usuario decida qué atributo quiere modificar, submenús que serán distintos segun si estamos con una Empresa o una Persona..

Para no hacer posts tan grandes, debajo posteo otro mensaje explicando un poco el método nuevoContacto()
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Ayuda con ejercicio java
« Respuesta #6 en: 07 de Noviembre 2017, 02:19 »
(..continua del post anterior..)

Este es el método nuevoContacto()
Código: [Seleccionar]
static void nuevoContacto()
    {
    if (indiceArreglo == 50)
    System.out.println("\nLa Agenda esta llena. No caben nuevos contactos");
    else
    {
    System.out.print("\nIndique si es una (E)mpresa o una (P)ersona (E/P): ");
char opcion = sc.nextLine().toUpperCase().charAt(0);

switch (opcion)
{
case 'E':
agenda[indiceArreglo] = pedirDatosEmpresa();
indiceArreglo++;
break;
case 'P':
agenda[indiceArreglo] = pedirDatosPersona();
indiceArreglo++;
break;
default:
System.out.println("No se reconoce la opcion indicada: " + opcion);
}
    }
    }

Lo primero que hace es comprobar si la agenda esta llena o no.
La forma que tenemos de saber si podemos añadir nuevos Contactos, y en que posicion del arreglo debemos añadirlo, es valiendonos de una varaible int que yo he llamado indiceArreglo

Al iniciar el programa, su valor es 0.
Esto significa que tenemos 0 contactos.
Y además significa que el primer contacto que añadamos, se colocará en la posición 0. Tras añadir el contacto, su valor se incrementa y ahora valdría 1.

Esto significaría que tendríamos 1 Contacto creado, que está en la posicion 0 (indiceArreglo - 1).
Y significaría que el próximo Contacto se añadiría en la posición 1.

Y así sucesivamente.

Por eso empezamos preguntando si indiceArreglo == 50. Porque si ya vale 50, significa que ya tenemos Contactos desde la posicion 0 a la 49 del arreglo, y entonces ya no queda sitio para nuevos Contactos

Si no vale 50, es que podemos añadir nuevos Contactos.
Pero primero tenemos que saber si se quiere añadir una Empresa o una Persona, así que se lo preguntamos al usuario mediante un simple char.
Aquí, para no complicar más el código, hacemos la pregunta confiando en que el usuario no se equivocará y sabrá elegir una opcion buena.
Se podría hacer un metodo similar al de pedirOpcion() comentado anteriormente, que compruebe que el usuario mete una opción valida y se repita la petición si no es así.
Pero no vale la pena complicar más el código en este momento.

Tras pedir el char, analizamos que ha elegido. Si es una Persona, metemos en la posicion que nos indica indiceArreglo, el objeto resultante del método pedirDatosPersona() e incrementamos el indice del arreglo.
Si es una Empresa, hacemos lo mismo pero con el método pedirDatosEmpresa().

pedirDatosPersona() y pedirDatosEmpresa() son métodos que piden al usuario los datos necesarios para crear un objeto de una de estas dos clases y los retorna ya listos para que podamos introducirlos directamente en el arreglo.


Código: [Seleccionar]
static Persona pedirDatosPersona()
    {
    System.out.print("\nIntroduzca ID: ");
int id = sc.nextInt(); sc.nextLine();
System.out.print("Introduzca Nombre: ");
String nombre = sc.nextLine();
System.out.print("Introduzca E-Mail: ");
String email = sc.nextLine();
System.out.print("Introduzca DNI: ");
String dni = sc.nextLine();
System.out.print("Introduzca numero celular: ");
String celular = sc.nextLine();

return new Persona(id, nombre, email, dni, celular);
    }

Código: [Seleccionar]
static Empresa pedirDatosEmpresa()
    {
    System.out.print("\nIntroduzca ID: ");
int id = sc.nextInt(); sc.nextLine();
System.out.print("Introduzca Nombre: ");
String nombre = sc.nextLine();
System.out.print("Introduzca numero tlf fijo: ");
String fijo = sc.nextLine();
System.out.print("Introduzca URL pagina web: ");
String web = sc.nextLine();
System.out.print("Introduzca numero empresa: ");
String nEmpresa = sc.nextLine();

return new Empresa(id, nombre, fijo, web, nEmpresa);
    }


Como ves, hacer uno o varios métodos especificos para determinadas tareas, puede parecer engorroso, pero en realidad hace que el código sea mucho más fácil de entender, mucho más fácil de mantener y mucho más fácil de reaprovechar.
Estos metodos para pedir datos de persona o empresa, pueden reutilizarse en otros métodos, e incluso en otras clases..

Creo que no haya nada más que comentar, si tienes alguna pregunta, dispara...
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Dysloke

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 6
    • Ver Perfil
Re:Ayuda con ejercicio java
« Respuesta #7 en: 07 de Noviembre 2017, 02:33 »
Compañero Kabuto,

Nunca crei que alguien me pudiera dar una explicacion tan genial del problema. Mañana me pondre a leer absolutamente todo y probar todos los cambios.

Si me llego a trabar (espero que no) te estare consultando.

Desde ya muy agradecido por tu ayuda  ;D ;D

Dysloke

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 6
    • Ver Perfil
Re:Ayuda con ejercicio java
« Respuesta #8 en: 08 de Noviembre 2017, 01:19 »
Dejo esto por aqui para que vean la continuacion de la explicacion del compañero Kabuto.


Mira un arreglo (también llamado array, vector,...) es una agrupación de variables del mismo tipo y bajo un mismo nombre.

Si yo declaro:
int[] numeros = new int[10];

Estoy diciendo que tengo 10 variables de tipo int, y que están agrupadas bajo el nombre "numeros".
Estas variables están numeradas para que podamos apuntar a ellas una por una.
La primera está en la posición 0 y la última en este ejemplo está en la posicion 9 (del 0 al 9 hay 10 números, 10 posiciones)

La sintaxis para apuntar a una de estas posiciones, es usar el nombre del arreglo y entre corchetes  el número de posición que nos interesa.
Ejemplos:
Quiero sacar por pantalla el primer número:
Código: [Seleccionar]
System.out.println("Primer numero: " + numeros[0]);
Quiero guardar en la posición 5, el mismo número que tengo en la posicion 8:
Código: [Seleccionar]
numeros[5] = numeros[8];
En lugar de números para indicar la posición, puedo usar variables de tipo int, que es de hecho lo más habitual.

Supongamos que quiero mostrar TODOS los números del arreglo.
Puedo hacer 10 system.out....
Código: [Seleccionar]
System.out.println("Numero: " + numeros[0]);
System.out.println("Numero: " + numeros[1]);
System.out.println("Numero: " + numeros[2]);
System.out.println("Numero: " + numeros[3]);
....
....
System.out.println("Numero: " + numeros[9]);

Pero esto es muy engorroso, imagina hacerlo con la agenda de 50 Contactos.
O imagina si el arreglo fuera de 10.000 posiciones... o más....

Podemos simplificarlo usando un bucle for, el cuál me irá incrementando una variable llamada i que empieza en valor 0, y le pediré que la incremente +1 mientras i sea menor que 10

Código: [Seleccionar]
for (int i = 0; i < 10; i++)
    System.out.println("Numero: " + numeros[i]);

De este modo uso la variable i para apuntar a las posiciones del arreglo, en lugar de tener que poner números directamente.
En este caso, sabemos que el arreglo tiene 10 posiciones y por eso le decimos que el bucle se detenga cuando llegue a 10, ya que no existen más posiciones después de numeros[9]. Si intentamos mostrar posiciones superiores a esta, el programa dará error.

Pero, ¿que pasa si no sabemos cuanto mide el arreglo? Lo más habitual es que escribamos métodos y programas que van a recibir arreglos para operar con ellos, pero no siempre van a medir lo mismo.
El bucle for que he puesto antes solo sirve para un arreglo que tenga 10 posiciones, si recibieramos un arreglo que tiene menos posiciones, el programa daría error al pedir mostrar posiciones que no existen.

Y si recibieramos un arreglo más grande, no lo estaríamos mostrando al completo, solo veríamos las 10 primeras posiciones.

Para escribir un código que funcione con cualquier arreglo, sea cual sea su tamaño, podemos preguntarle al arreglo cual es su longitud y establecerlo como límite en el bucle for.
Código: [Seleccionar]
for (int i = 0; i < numeros.length; i++)
    System.out.println("Numero: " + numeros[i]);

numeros.length nos devuelve el valor del atributo "longitud" del arreglo, así ese bucle siempre recorrerá el arreglo al completo, sea cual sea su longitud

Podemos parar el recorrido del for si se cumple una determinada condición.
Por ejemplo, supongamos que queremos recorrer el arreglo al completo, pero que se detenga si encuentra un número negativo y además nos diga en que posición lo ha encontrado:
Código: [Seleccionar]
for (int i = 0; i < numeros.length; i++)
    if (numeros[i] < 0)
    {
        System.out.println("Numero negativo encontrado en posicion: " + i);
        break;
    }

Al detectar un numero negativo (menor que 0), saca un mensaje en pantalla y detiene la búsqueda usando la sentencia break. Esta sentencia "rompe" la ejecución del bucle for haciendo que se detenga antes de que se cumpla la condición impuesta al for, que era incrementar i hasta llegar a 10.

Con estas nociones, podemos ya escribir el código necesario para buscar un Contacto y mostrarlo sus datos en pantalla.
Código: [Seleccionar]
static void buscarContacto()
    {
        if (indiceArreglo == 0)
    System.out.println("No hay Contactos registrados en la Agenda.");
    else
    {
    System.out.print("\nIntroduzca ID del Contacto a buscar: ");
    int IDaBuscar = sc.nextInt(); sc.nextLine();
   
    for (int i = 0; i < indiceArreglo; i++)
    {
    if (agenda[i].getID() == IDaBuscar)
                        {
    agenda[i].mostrarContacto();
                                break;
                         }
    }
    }
    }

Lo primero es preguntar si indiceArreglo tiene valor 0, porque si esto es así, significa que aun no hemos registrado Contactos y no tiene sentido hacer niguna busqueda.
Recuerda que indiceArreglo, va aumentando cada vez que añadamos Contactos.

En caso de haber Contactos registrados, pedimos al usuario que nos indique el ID que quiere buscar.
Y usamos un bucle for para recorrer el arreglo de Contactos, y por cada elemento que recorremos, preguntamos si su ID coincide con el ID que nos han pedido buscar.
En caso de encontrar coincidencia, mostramos en pantalla los datos del Contacto, llamando a su propio metodo mostrarContacto().

Y tras mostrar los datos, detenemos el bucle con la sentencia break, pues ya no tiene sentido seguir buscando mas contactos, cuando ya hemos encontrado el que buscábamos.

Fíjate que en este caso, el bucle for su condición no es que la i se incremente hasta alcanzar los 50 registros del arreglo de Contactos.
LA condición es incrementarse hasta alcanzar el valor de la variable indiceArreglo.

ESto es porque, aunque hemos declarado un arreglo de 50 posiciones, dichas posiciones están "vacías" cuando el programa se inicia por primera vez.
Si permitimos preguntar por posiciones vacías, el programa se romperá.

Las posiciones las iremos llenando según vamos registrando nuevos Contactos.
Por esto es importantísima la variable indiceArreglo. Nos dice en todo momento en que posicion podemos registrar un nuevo contacto, hasta que posición podemos hacer búsquedas sin riesgo de preguntar por posiciones vacías, nos dice de inmediato si la agenda esta vacía (posicionArreglo == 0) o si la Agenda está completa (indiceArreglo == 50)

Bien, el método para buscar y mostrar Contacto ya está heho y funciona bien.
Pero aún tiene un pequeño defecto.
Al realizar la busqueda del Contacto, si lo encuentra, lo mostrará en pantalla.
Pero si no lo encuentra, no hará NADA, absolutamente NADA.
Volverá a salir el menú principal y esto no es elegante, puede resultar confuso para el usuario del programa que no está seguro de qué ha pasado con su petición de búsqueda.

En caso de no encontrar el Contacto deseado, lo ideal sería que el programa informase al usuario de que no existe ningún Contacto con ese ID.
Para ello, habría que añadir al método algún tipo de control, para que cuando el bucle de búsqueda termine, poder saber si ha encontrado o no al Contacto.
Y si no lo ha encontrado, informar al usuario.

Una forma fácil de hacerlo es usar una variable booleana que empiece con valor false.
Si encontramos el Contacto buscado, le damos valor true. Si no, conservará su valor false.

Así, al terminar el bucle podemos preguntar por el valor de esta variable, y si vemos que ha conservado su valor false, sabremos que no se encontró el Contacto, y podemos informar de ello.

Código: [Seleccionar]
static void buscarContacto()
    {
        if (indiceArreglo == 0)
    System.out.println("No hay Contactos registrados en la Agenda.");
    else
    {
    boolean encontrado = false;//Para controlar si encontramos o no al Contacto
   
    System.out.print("\nIntroduzca ID del Contacto a buscar: ");
    int IDaBuscar = sc.nextInt(); sc.nextLine();
   
    for (int i = 0; i < indiceArreglo; i++)
    {
    if (agenda[i].getID() == IDaBuscar)
    {
    agenda[i].mostrarContacto();
    encontrado = true;
    break;
    }
    }
   
    //Bucle for ha finalizado, comprobemos si ha sido porque encontró al Contacto
    if (encontrado == false)
    System.out.println("NO se ha encontrado ningun contado con el ID: " + IDaBuscar);
    }
    }

Prueba este método y verás que funciona.

Con esto también deberías poder hacer el método listarContactos(), pues es recorrer toda la Agenda (hasta donde nos diga la variable indiceArreglo) y mostrar los datos de los contactos en pantalla.

En el foro, mencioné que podría ser necesario comprobar con instanceof si el Contacto es una instancia de Persona o Empresa y hacer un casting para mostrar su datos.
Puesto que el metodo .mostrarContacto() es abstracto y comun a ambas clases, no es necesario hacer ningún casting.

Si quisieramos acceder a un método especifio de Persona (por ejemplo getEmail()) o uno de Empresa (por ejemplo getNumeroEmpresa()), entonces si que habría que hacer casting.
Esto de hacer casting, preguntar con instanceof, etc... es por el Polimorfismo de las clases.
En el foro hay un capitulo del Curso de Java donde se explica. También podemos hablar de ello más adelante.

Dysloke

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 6
    • Ver Perfil
Re:Ayuda con ejercicio java
« Respuesta #9 en: 08 de Noviembre 2017, 03:00 »
Consulta: recorro el array para mostrar el contenido grabado y no me muestra nada. Mejor dicho me muestra un null y simbolos

Seleccione la opcion deseada: 4
tp4.Persona@4554617c
null

a que se puede deber este error?

Saludos

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Ayuda con ejercicio java
« Respuesta #10 en: 10 de Noviembre 2017, 00:22 »
Consulta: recorro el array para mostrar el contenido grabado y no me muestra nada. Mejor dicho me muestra un null y simbolos

Seleccione la opcion deseada: 4
tp4.Persona@4554617c
null

a que se puede deber este error?

Saludos

¿Cómo lo estás mostrando?

Meter el objeto en system.out no servirá..
Por ejemplo:
Código: [Seleccionar]
System.out.println(agenda[i]);Eso, solo funcionaría si hubieras sobreeescrito el metodo toString(), que todas las clases heredan de la superclase Object,  dentro de tus clases. Aunque esto es otro asunto que mejor dejar para otro momento para no liar más el asunto.

En tu ejercicio, para mostrar la información de los contactos has de llamar al método mostrarContacto(), que fue declarado como abstracto en la clase Contacto, y posteriormente sobreescribiste en los clases hijas, tal que así:

Código: [Seleccionar]
void mostrarContacto(){
        System.out.println(this.getNombreCompleto() + this.getDni() + this.getEmail() + this.getTelefonoCelular());
       
    }

Por lo tanto, dentro del bucle deberías poner algo así para llamar a este método:

Código: [Seleccionar]
agenda[i].mostrarContacto();
Recuerda que el bucle en principio no debería recorrer TODO el arreglo, pues el arreglo tiene 50 posiciones pero tu seguramente NO has creado 50 nuevos contactos. Esto puede explicar que te muestre algunos null en pantalla.
En el código que te pasé, usábamos la variable indiceAgenda para contar cuantos contactos vamos creando y así saber, entre otras cosas, hasta donde debe llegar el bucle a la hora de recorrer el arreglo y mostrar los contactos.
El límite del bucle ha de ser el valor de indiceAgenda, y no la longitud total del arreglo.

Por cierto, tu método mostrarContacto() no es muy "bonito".
Al mostrar contactos en pantalla saldrá algo parecido a:
Citar
Juan Ramon62535625wjuan.ramon@yahoo.com645789675
Es decir, saldrán todos los atributos juntos en una sola línea.

No hay que obsesionarse con la presentación, pero tampoco hay que despreciarla je je.
De momento concentrate en que funcione. Y luego puedes hacer el método mostrarContacto() un poco más elegante.
Por ejemplo:

Código: [Seleccionar]
@Override
public void mostrarContacto()
{
System.out.println("\nDATOS DEL CONTACTO");
System.out.println("------------------\n");
System.out.println("Nombre: " + super.getNombre());
System.out.println("E-Mail: " + email);
System.out.println("D.N.I: " + dni);
System.out.println("Num Celular: " + celular);
}

Por cierto, fíjate que sobre el método he especificado la cláusula @Override

Esta cláusula es para indicar al compilador que queremos sobreescribir un método heredado, en este caso, estamos sobreescribiendo a mostrarContactos() que viene heredado de la clase Contacto.

No es obligatoria poner esta cláusula, normalmente los compiladores ya detectan ellos solos si estamos sobreescribiendo o no.
Pero si es muy recomendable ponerlo. Por una parte es útil al programador para identificar fácilmente qué métodos están sobreescribiendo y cuáles no.

Pero sobre todo ayuda a prevenir posibles errores.
Por ejemplo:
el método mostrarContactos() es de tipo void, no devuelve ningún valor

Si yo en una clase hija escribo de nuevo el método mostrarContactos(), también como tipo void, el compilador sabrá que estoy sobreescribiendo, aunque no yo no use la cláusula @Override.
En cambio, supongamos que me equivoco. Yo quiero sobreescribir ese método, pero por error indico , que en lugar de void,  digo que es tipo String (estoy cambiando la "firma" del método) y hasta pongo que devuelva un dato de tipo String y todo...

En este caso, el compilador pensará que estoy "sobrecargando" (que no es lo mismo que sobreescribir) el método mostrarContactos() y no se quejará por haber cambiado la "firma", lo dará por bueno.
Sin embargo, yo he cometido un error, y no me he dado cuenta porque para el compilador es correcto.

En cambio, si yo hubiera especificado previamente la cláusula @Override, entonces el compilador ahora sí sabría que mi intención no es "sobrecargar", si no que quiero "sobreescribir". Y entonces sí se quejará si cometo algún cambio en la "firma" del método.

Por eso la cláusula @Override es importante. Porque así informo al compilador de cuál es mi intención (sobreescribir), aunque luego por despiste sin darme cuenta haga otra cosa diferente (sobrecargar), momento en el cuál el compilador me mostrará un warning
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".