Autor Tema: Java ejercicio resuelto mediante POO y entidades modeladas mediante clases class  (Leído 4451 veces)

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Se propone el siguiente ejercicio de programación en Java:

Citar
Caso Universidad: Haciendo uso de la programación orientada a objetos complete el ejercicio propuesto sobre el registro de notas de los estudiantes de la universidad que brinde las funcionalidades de:

  • registrar la nota de 5 estudiantes en 5 asignaturas diferentes
  • Obtenga una nota definitiva de cada asignatura para cada estudiante se tienen 3 notas parciales en cada asignatura (todas con igualdad de valor)
  • Un promedio general de cada estudiante en todas sus asignaturas.
  • Un promedio de la nota definitiva de todos los estudiantes por cada asignatura

Este ejercicio ya fue resuelto en un mensaje anterior hace tiempo, pero por si quizás no quedó claro, lo resolvemos de nuevo.

Se pide resolver mediante POO, así que lo primero es identificar la entidades que intervienen y podrían requerir ser modeladas mediante clases.
Normalmente, modelaremos como clases aquellas entidades que se componen de "otras cosas" y/o tienen algunas funcionalidades concretas que conviene que las resuelvan ellas mismas.

Nos dicen que hay Estudiantes, que tienen Asignaturas. Y que cada Asignatura tendría 3 notas parciales, a partir de las cuales se podría calcular la nota definitiva para dicha Asignatura.

Estudiante y Asignatura es evidente que serán clases, ya que están compuestas de "otras cosas".
Un Estudiante se compone de Asignaturas y de al menos un nombre, aunque no se indique en el enunciado.
Además sería útil que un Estudiante, por si solo, tenga funcionalidades como darnos el promedio de las notas de sus Asignaturas

Una Asignatura se compone de tres notas parciales y también habría que darle un nombre.
Y también interesa que por si sola sepa hacer cosas como calcular su nota definitiva mediante las tres notas parciales que la componen

Una nota parcial no se compone de nada, es simplemente un valor int, o double si lo preferimos. Ni requiere poseer ninguna funcionalidad especial, así que no será una clase.

Una nota definitiva sí se compone de tres notas parciales. ¿Debería ser una clase?
Podría serlo... Quizás si el ejercicio fuera más avanzado y las notas definitivas tuvieran un tratamiento más especial, entonces interesaría modelarlo como una clase.

Pero en este caso no sería necesario, aquí la nota definitiva en realidad es un mero cálculo aritmético que lo único que ha de hacer es mostrarse en pantalla cuando se requiera. Y para resolver eso basta con usar un método, no hace falta modelar una clase.

Así que tendríamos la clase Asignatura.
Se compone de un nombre y tres notas parciales, que las podemos agrupar en un array
Mediante constructor le damos un nombre.
Luego con métodos, podemos registrar una nota en una posición concreta del array.
Y también calcular y retornar la nota definitiva. (por eso no requiere modelarse como una clase)
Código: [Seleccionar]
public class Asignatura {
//Cada asignatura tiene tres notas parciales
private int[] parciales = new int[3];
private String nombre;

public Asignatura(String nombre) {
this.nombre = nombre;
}

public String getNombre() {
return nombre;
}

/*
* Registra una nota parcial en la posición del array que
* se indique.
*/
public void registrarNotaParcial(int nota, int posicion) {
parciales[posicion] = nota;
}

/*
* Todas las notas tienen el mismo peso para calcular la nota
* definitiva. Así que basta con calcular el valor medio de las tres.
*/
public int getNotaDefinitiva() {
int sumaNotas = parciales[0] + parciales[1] + parciales[2];
return sumaNotas / 3;
}
}

Luego tendríamos la clase Estudiante.
Se compone de nombre, que recibe por constructor, y 5 objetos Asignatura, que también agruparemos en un array.

Con métodos podemos registrar una Asignatura en una posición concreta del array.
También podemos obtener la nota definitiva de una Asignatura concreta, indicando la posición del array que se quiere consultar.

Y también podemos obtener el "promedio general" de este Estudiante, es decir, sumar las notas definitivas de todas sus Asignaturas y calcular el promedio de dicha suma.
Código: [Seleccionar]
public class Estudiante {

//Cada Estudiante tiene 5 asignaturas
private Asignatura[] asignaturas = new Asignatura[5];
private String nombre;

public Estudiante(String nombre) {
this.nombre = nombre;
}

public String getNombre() {
return nombre;
}

/*
* Registra una Asignatura en la posicion del array que
* se le indique
*/
public void registrarAsignatura(Asignatura asign, int posicion) {
asignaturas[posicion] = asign;
}

/*
* Retorna la nota definitiva de la asignatura que se encuentra
* en la posicion del array indicada.
*/
public int getNotaDeAsignatura(int posicion) {
return asignaturas[posicion].getNotaDefinitiva();
}

/*
* Hace un promedio general de todas las asignaturas
* de este estudiante
*/
public int getPromedioGeneral() {
//Sumamos las notas definitivas de sus asignaturas
int sumaNotas = 0;
for (Asignatura asig: asignaturas)
sumaNotas += asig.getNotaDefinitiva();
//Retornamos el promedio
return sumaNotas / 5;
}

}

Y con esto ya podemos componer la clase principal donde se pondrán en marcha todas las funcionalidades de la aplicación.
Lo vemos en el siguiente mensaje.
« Última modificación: 18 de Abril 2022, 18:14 por Ogramar »
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: Registrar 5 Estudiantes, con 5 Asignaturas
« Respuesta #1 en: 13 de Febrero 2022, 13:55 »
Vamos a diseccionar la clase principal, que podemos llamar Universidad
Como variables de ámbito global, tendremos un array para los 5 Estudiantes que se han de registrar y un objeto Scanner para pedir datos por teclado.
En mi caso, además he optado por predefinir en un array los nombres de las 5 asignaturas.
De esta forma, ya no es un dato que haya que pedir por teclado cada vez que registramos una asignatura.
Y además, nos aseguramos de que cada Estudiante va a tener las mismas 5 Asignaturas, y en el mismo orden, porque este dato ya no depende de lo que introduzca el usuario.

Código: [Seleccionar]
public class Universidad {

//Nombre de las Asignaturas están predefinidas.
private static final String[] ASIGNATURAS = new String[] {"Matematicas",
"Historia", "Ciencias", "Literatura", "Informatica"};
//Array de Estudiantes
private static Estudiante[] estudiantes;

private static Scanner teclado = new Scanner(System.in);

El método main(), lo que hará será mostrar un menú de opciones y evaluar con un switch la selección del usuario.
Según lo que elija, se invocarán distintos métodos.

Código: [Seleccionar]
public static void main(String[] args) {

int opcion = 0;

do {
System.out.println("\n\t\tMENU UNIVERSIDAD");
System.out.println("\t\t---- -----------\n");
System.out.println("[1] -- Registrar nuevos Estudiantes");
System.out.println("[2] -- Listar notas definitivas de Asignaturas por cada Estudiante");
System.out.println("[3] -- Listar promedio general de cada Estudiante");
System.out.println("[4] -- Listar promedio de nota definitiva de todos los Estudiantes por Asignatura");
System.out.println("[9] -- TERMINAR PROGRAMA");
System.out.print("Opcion: ");
opcion = Integer.parseInt(teclado.nextLine());
switch(opcion) {
case 1:
registrarNuevosEstudiantes();
break;
case 2:
listarNotasDefinitivas();
break;
case 3:
listarPromedioEstudiantes();
break;
case 4:
listarPromediosNotasDefinitivas();
break;
case 9:
System.out.println("\n\t\tFIN DE PROGRAMA");
break;
default:
System.out.println("Opción equivocada");
}
} while(opcion != 9);

}

Veamos el primer método: registrarNuevosEstudiantes()
Lo que hará será inicializar el array de Estudiantes y con un bucle pedir datos para crear 5 Estudiantes.
Por cada Estudiante, usará otro bucle para crear 5 Asignaturas..
Y por cada Asignatura, usará un tercer bucle para pedir las 3 notas parciales.

Así que aunque es un método sencillo, requiere de tres bucles anidados y por eso tiene tantas líneas de código.
Código: [Seleccionar]
private static void registrarNuevosEstudiantes() {

//Inicializamos array de Estudiantes
estudiantes = new Estudiante[5];

//Por cada Estudiante, registraremos 5 Asignaturas, con 3 notas parciales
for (int est = 0; est < estudiantes.length; est++) {
System.out.println("\n\nRegistrando Estudiante #" + (est+1));
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
//Registramos Estudiante en el array
estudiantes[est] = new Estudiante(nombre);

//Para este Estudiante, registramos ahora 5 Asignaturas
for (int asig = 0; asig < ASIGNATURAS.length; asig++) {
//Construimos la Asignatura, tomando el nombre del array predefinido
Asignatura asignatura = new Asignatura(ASIGNATURAS[asig]);

//Ahora, hay que pedir 3 notas parciales para esta Asignatura
System.out.println("\nNotas parciales de " + ASIGNATURAS[asig]);
for (int i = 0; i < 3; i++) {
System.out.print("Parcial #" + (i+1) + ": ");
int parcial = Integer.parseInt(teclado.nextLine());
//Registramos parcial en la Asignatura, indicando la posición donde debe registrarse
asignatura.registrarNotaParcial(parcial, i);
}

/*
* Ya tenemos Asignatura con las 3 notas parciales.
* La registramos en el Estudiante, indicando la posicion donde registrarse
*/
estudiantes[est].registrarAsignatura(asignatura, asig);
}
//Aqui termina el bucle para registrar 5 Asignaturas.
//Ahora se volverá a repetir el ciclo para otro Estudiante, hasta completar los 5
}
}

Ahora el método listarNotasDefinitivas().
Lo que hace es mostrar, por cada Asignatura, la nota definitiva que ha obtenido cada Estudiante.
Así que con un bucle se recorren las asignaturas y con otro anidado se recorren los estudiantes para pedirles la nota definitiva, indicándoles que posición de su array han de consultar.
He aquí la ventaja de predefinir las asignaturas para que se llamen igual y se registren en el mismo orden.
Todos los estudiantes tienen Matematicas en la posición
  • , Historia en la [1], ....

No hace falta buscar asignaturas por nombre, se indica la posición del array de asignaturas predefinidas en la clase main, porque coincide con las posicione del array que cada Estudiante posee

Código: [Seleccionar]
private static void listarNotasDefinitivas() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tNOTAS DEFINITIVAS POR ESTUDIANTES");
//Recorremos cada Asignatura
for (int asig= 0; asig < ASIGNATURAS.length; asig++) {
System.out.println("\n- Asignatura: " + ASIGNATURAS[asig]);
//Recorremos cada Estudiante para obtener su nota en la Asignatura actual
for (Estudiante estu: estudiantes) {
System.out.println("Nombre: " + estu.getNombre());
System.out.println("Nota Definitiva: " + estu.getNotaDeAsignatura(asig));
}
}
}
}


Luego viene el método: listarPromedioEstudiantes()
Muy sencillo, solo hay que recorrer Estudiantes y pedirles su promedio general.
Este promedio se calcula a partir de sus 5 notas definitivas de cada Asignatura, y la clase Estudiante ya sabe calcularlo ella sola.
Código: [Seleccionar]
private static void listarPromedioEstudiantes() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tPROMEDIO GENERAL POR ESTUDIANTES");
//Recorremos Estudiantes y les pedimos su promedio
for (Estudiante estu: estudiantes) {
System.out.println("\nNombre: " + estu.getNombre());
System.out.println("Promedio General: " + estu.getPromedioGeneral());
}
}
}

Por último, el método listarPromediosNotasDefinitivas().
Aquí hay que recorrer cada Asignatura. Y por cada una de ellas, recorrer los 5 Estudiantes y sumar sus notas definitivas para dicha asignatura.
A partir de esta suma, calculamos el promedio entre los estudiantes de esta asignatura.
Código: [Seleccionar]
private static void listarPromediosNotasDefinitivas() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tPROMEDIOS NOTAS DEFINITIVAS");
//Recorremos Asignaturas
for (int asig= 0; asig < ASIGNATURAS.length; asig++) {
System.out.println("\nAsignatura: " + ASIGNATURAS[asig]);
/*
* Por cada Asignatura, sumamos las notas definitivas de los
* 5 Estudiantes. Con esta suma, luego calcularemos el promedio
*/
int sumaNotas = 0;
for (Estudiante estu: estudiantes)
sumaNotas += estu.getNotaDeAsignatura(asig);
//Tenemos la suma, calculamos promedio
System.out.println("Promedio de notas: " + (sumaNotas/estudiantes.length));
}
}
}

Y eso es todo. Puede ser un poco lioso en cuanto a saber si se está pidiendo el promedio de una asignatura de un estudiante, o el promedio de una asignatura para los 5 estudiantes, o el promedio de todas las asignaturas para un solo estudiante...  :o

No recuerdo como lo resolvimos la otra vez, probablemente fuera distinto. Espero que esta vez hayamos dado una solución más clara y comprensible.

Un saludo.

Por cierto, dejo aquí el código completo de la clase principal:

Código: [Seleccionar]
import java.util.Scanner;

public class Universidad {

//Nombre de las Asignaturas están predefinidas.
private static final String[] ASIGNATURAS = new String[] {"Matematicas",
"Historia", "Ciencias", "Literatura", "Informatica"};
//Array de Estudiantes
private static Estudiante[] estudiantes;

private static Scanner teclado = new Scanner(System.in);

public static void main(String[] args) {

int opcion = 0;

do {
System.out.println("\n\t\tMENU UNIVERSIDAD");
System.out.println("\t\t---- -----------\n");
System.out.println("[1] -- Registrar nuevos Estudiantes");
System.out.println("[2] -- Listar notas definitivas de Asignaturas por cada Estudiante");
System.out.println("[3] -- Listar promedio general de cada Estudiante");
System.out.println("[4] -- Listar promedio de nota definitiva de todos los Estudiantes por Asignatura");
System.out.println("[9] -- TERMINAR PROGRAMA");
System.out.print("Opcion: ");
opcion = Integer.parseInt(teclado.nextLine());
switch(opcion) {
case 1:
registrarNuevosEstudiantes();
break;
case 2:
listarNotasDefinitivas();
break;
case 3:
listarPromedioEstudiantes();
break;
case 4:
listarPromediosNotasDefinitivas();
break;
case 9:
System.out.println("\n\t\tFIN DE PROGRAMA");
break;
default:
System.out.println("Opción equivocada");
}
} while(opcion != 9);

}

private static void registrarNuevosEstudiantes() {

//Inicializamos array de Estudiantes
estudiantes = new Estudiante[5];

//Por cada Estudiante, registraremos 5 Asignaturas, con 3 notas parciales
for (int est = 0; est < estudiantes.length; est++) {
System.out.println("\n\nRegistrando Estudiante #" + (est+1));
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
//Registramos Estudiante en el array
estudiantes[est] = new Estudiante(nombre);

//Para este Estudiante, registramos ahora 5 Asignaturas
for (int asig = 0; asig < ASIGNATURAS.length; asig++) {
//Construimos la Asignatura, tomando el nombre del array predefinido
Asignatura asignatura = new Asignatura(ASIGNATURAS[asig]);

//Ahora, hay que pedir 3 notas parciales para esta Asignatura
System.out.println("\nNotas parciales de " + ASIGNATURAS[asig]);
for (int i = 0; i < 3; i++) {
System.out.print("Parcial #" + (i+1) + ": ");
int parcial = Integer.parseInt(teclado.nextLine());
//Registramos parcial en la Asignatura, indicando la posicion donde debe registrarse
asignatura.registrarNotaParcial(parcial, i);
}

/*
* Ya tenemos Asignatura con las 3 notas parciales.
* La registramos en el Estudiante, indicando la posición donde registrarse
*/
estudiantes[est].registrarAsignatura(asignatura, asig);
}
//Aqui termina el bucle para registrar 5 Asignaturas.
//Ahora se volverá a repetir el ciclo para otro Estudiante, hasta completar los 5
}
}

private static void listarNotasDefinitivas() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tNOTAS DEFINITIVAS POR ESTUDIANTES");
//Recorremos cada Asignatura
for (int asig= 0; asig < ASIGNATURAS.length; asig++) {
System.out.println("\n- Asignatura: " + ASIGNATURAS[asig]);
//Recorremos cada Estudiante para obtener su nota en la Asignatura actual
for (Estudiante estu: estudiantes) {
System.out.println("Nombre: " + estu.getNombre());
System.out.println("Nota Definitiva: " + estu.getNotaDeAsignatura(asig));
}
}
}
}

private static void listarPromedioEstudiantes() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tPROMEDIO GENERAL POR ESTUDIANTES");
//Recorremos Estudiantes y les pedimos su promedio
for (Estudiante estu: estudiantes) {
System.out.println("\nNombre: " + estu.getNombre());
System.out.println("Promedio General: " + estu.getPromedioGeneral());
}
}
}

private static void listarPromediosNotasDefinitivas() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tPROMEDIOS NOTAS DEFINITIVAS");
//Recorremos Asignaturas
for (int asig= 0; asig < ASIGNATURAS.length; asig++) {
System.out.println("\nAsignatura: " + ASIGNATURAS[asig]);
/*
* Por cada Asignatura, sumamos las notas definitivas de los
* 5 Estudiantes. Con esta suma, luego calcularemos el promedio
*/
int sumaNotas = 0;
for (Estudiante estu: estudiantes)
sumaNotas += estu.getNotaDeAsignatura(asig);
//Tenemos la suma, calculamos promedio
System.out.println("Promedio de notas: " + (sumaNotas/estudiantes.length));
}
}
}
}
« Última modificación: 13 de Febrero 2022, 13:57 por Kabuto »
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".