Autor Tema: ¿Qué es encapsular en programación orientada a objetos? Ocultar miembros clase  (Leído 1467 veces)

feruedez

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 1
    • Ver Perfil
Primero que nada, hola. No sé si me puedan ayudar a crear un código para un negocio que se dedica a darle mantenimiento a equipos tecnológicos. Lo que se quiere lograr con el código es:

- Que el usuario se pueda registrar llenando con sus datos (nombre completo, número de celular)
- Elegir de una tabla o solo elegir el tipo de servicio que desea los cuales son (calibración, reparación y otro)
- Y que al final imprima sus datos, el servicio que eligió y que se le pueda dar un número de cliente

pero el codigo debe incluir: clases (atributos y métodos), encapsulamiento, herencia y manejo de excepciones

y aqui es donde me pierdo yo apenas se hacer encapsulamientos y algo de poo y llevo atorada aqui bastante tiempo de igual manera gracias por su tiempo 
« Última modificación: 19 de Junio 2022, 13:28 por Ogramar »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Re: Ayuda con un Codigo
« Respuesta #1 en: 31 de Marzo 2022, 13:08 »
Hola

Encapsular simplemente consiste en ocultar los miembros de una clase (atributos, métodos...) de forma que no se pueda acceder a ellos desde "fuera" de la propia clase.
Esto lo hacemos con los modificadores de acceso: public, private, protected...

Es decir, cuando en una clase declaramos sus atributos como private, pues ya estamos encapsulando.  :)

Por lo general, los atributos vamos a querer que sean privados y los métodos querremos que sean públicos.
De hecho, usaremos métodos públicos (getters/setters) para dar acceso desde el exterior a los atributos privados.

Pero, ¿entonces para que hacemos atributos privados si luego los "desprotegemos" dando acceso mediante métodos públicos?

La cuestión es que si hacemos los atributos públicos, no tendremos forma de controlar que valor reciben.
En cambio, dando acceso mediante métodos, aquí si que podemos poner controles, si queremos.

Por ejemplo, supón que creamos una clase Persona donde hacemos public un atributo que representa la edad.
Puede que alguien que esté usando nuestra clase haga un programa sin un control de "calidad de datos" mínimo y ocurran cosas como que el atributo edad reciba el valor 1500, o el valor -45, es decir, valores que son absurdos para la edad de una persona.

Si ese programador es descuidado, no es culpa nuestra. Pero podemos poner de nuestra parte para que nuestra maravillosa clase Persona, sea más segura y fiable.

Así que lo que haremos será "encapsular" el atributo edad para que no se pueda acceder directamente a él.
Escribiremos un método para dar acceso al atributo, uno llamado setEdad(int edad);, pero dentro del método pondremos nosotros un control de "calidad de datos".
Con un if podemos comprobar si la edad recibida entre paréntesis, es un valor apropiado.
Si es un valor negativo o es demasiado alto, lo rechazaremos y mostraremos mensaje de aviso en pantalla.
Y si es un valor aceptable, pues entonces sí se lo asignaremos al atributo edad que tenemos "encapsulado" y protegido.

De esta manera, nuestra clase ya impone ciertas reglas y límites para los valores de los atributos. Y esto hace que el programador que use nuestra clase, tenga que ser más cuidadoso con su código ya que no podrá registrar "personas" si no se ocupa de controlar mejor la calidad de los datos que vaya a recoger.


Bien, tras aclarar que es el encapsulamiento y cuál es su propósito, vamos a ver el ejercicio.

Piden clases, encapsulamiento, herencia y control de excepciones. Es un ejercicio sencillo donde la herencia no parece necesaria, pero bueno, podemos "forzarla" un poco para incluirla.


Mi propuesta sería crear una clase Usuario y una clase Mantenimiento.
Esta última, sería la clase madre de otras tres subclases: Reparacion, Calibracion y Otros
Así ya tenemos herencia.

Esta podría ser la clase Usuario:
Código: [Seleccionar]
public class Usuario {

private int numCliente;
private String nombre;
private String celular;

public Usuario(int numCliente, String nombre, String celular) {
this.numCliente = numCliente;
this.nombre = nombre;
this.celular = celular;
}

public int getNumCliente() {
return numCliente;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public String getCelular() {
return celular;
}

public void setCelular(String celular) {
this.celular = celular;
}

@Override
public String toString() {
return String.format("Nº Cliente: %d\nNombre: %s\tCelular: %s", numCliente, nombre, celular);
}

}

Esta la clase Mantenimiento, que como está destinada a ser clase "madre", la podemos declarar como abstracta. Esto es porque luego en el programa, no vamos a querer crear objetos de esta clase madre, si no que vamos a querer crear solo objetos de sus clases hijas.
Código: [Seleccionar]
public abstract class Mantenimiento {

protected Usuario usuario;
protected String equipo;

public Mantenimiento(Usuario usuario, String equipo) {
this.usuario = usuario;
this.equipo = equipo;
}
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
public String getEquipo() {
return equipo;
}
public void setEquipo(String equipo) {
this.equipo = equipo;
}
@Override
public String toString() {
return String.format("Datos Usuario: %s\n\t---------------\nEquipo: %s\n\t---------------\n",
usuario, equipo);
}
}

Fíjate que aquí los atributos están como protected y no como private.
Podrían ser private, pero cuando creamos clases abstractas, muchas veces vamos a querer que sus clases hijas puedan acceder directamente a los atributos que están heredando de su clase madre.
Con protected, damos acceso solo a las clases hijas. Siguen estando encapsulados, pero le abrimos las puertas a los "legítimos herederos".

Vamos a ver estas clases hijas.
Esta sería Calibracion, que es casi idéntica a su clase madre, solo varía su método toString().
Código: [Seleccionar]
public class Calibracion extends Mantenimiento {

public Calibracion(Usuario usuario, String equipo) {
super(usuario, equipo);
}

@Override
public String toString() {
return String.format("%sTipo Manteminiento: Calibracion", super.toString());
}

}

La clase Reparacion si añade un nuevo atributo para indicar que pieza es la que requiere ser reparada:
Código: [Seleccionar]
public class Reparacion extends Mantenimiento {

private String piezaFalla;

public Reparacion(Usuario usuario, String equipo, String piezaFalla) {
super(usuario, equipo);
this.piezaFalla = piezaFalla;
}

public String getPiezaFalla() {
return piezaFalla;
}

public void setPiezaFalla(String piezaFalla) {
this.piezaFalla = piezaFalla;
}

@Override
public String toString() {
return String.format("%sTipo Manteminiento: Reparacion\nPieza que falla: %s",
super.toString(), piezaFalla);
}

}

Y la clase Otros, que usa un atributo extra para pedir una descripción del servicio que se necesita:
Código: [Seleccionar]
public class Otros extends Mantenimiento {

private String descripcion;

public Otros(Usuario usuario, String equipo, String descripcion) {
super(usuario, equipo);
this.descripcion = descripcion;
}

public String getDescripcion() {
return descripcion;
}

public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}

@Override
public String toString() {
return String.format("%sTipo Mantenimiento: Otros\nDescripcion: %s", super.toString(), descripcion);
}

}


Con esto, ya podemos hacer una clase main donde usar un ArrayList de tipo Mantenimiento, donde registraremos objetos Calibracion, Reparacion y Otros
Como todas son hijas de Mantenimiento es posible juntar objetos de esas tres clases en esa colección.

Es un ejemplo muy sencillo, un menú muy básico para registrar mantenimientos y mostrar un listado:
Código: [Seleccionar]
import java.util.ArrayList;
import java.util.Scanner;

public class ManteminientoEquipos {

private static ArrayList<Mantenimiento> mantenimientos = new ArrayList<Mantenimiento>();
private static Scanner teclado = new Scanner(System.in);

public static void main(String[] args) {

int opcion = 0;

do {
System.out.println("\n\t\tMANTENIMIENTO EQUIPOS");
System.out.println("\t\t------------- -------\n");
System.out.println("[1] --- Registrar nuevo Mantemimiento");
System.out.println("[2] --- Listar Mantenimientos registrados");
System.out.println("[3] --- TERMINAR PROGRAMA");
System.out.print("Elija opcion: ");
try {
opcion = Integer.parseInt(teclado.nextLine());
switch(opcion) {
case 1:
nuevoManteminiento();
break;
case 2:
listarMantenimientos();
break;
case 3:
System.out.println("\n\t\tFIN DE PROGRAMA");
break;
default:
System.out.println("Opcion inexistente");
}
}
catch(NumberFormatException nfe) {
System.out.println("ERROR: Introduzca solo números");
opcion = 0;
}
}while(opcion != 3);

}

private static void nuevoManteminiento() {
//Pedimos datos cliente
System.out.println("\nDATOS DEL CLIENTE:");
System.out.print("Nombre Completo: ");
String nombre = teclado.nextLine();
System.out.print("Celular: ");
String celular = teclado.nextLine();
//Numero cliente se genera según longitud del arraylist
int numCliente = 1000 + mantenimientos.size();
//Preguntamos equipo a mantener
System.out.print("\nEQUIPO A MANTENER: ");
String equipo = teclado.nextLine();
//Preguntamos tipo mantenimiento
int tipo = 0;
while (tipo < 1 || tipo > 3) {
try {
System.out.println("\nTIPO DE MANTEMIENTO:");
System.out.println("[1] -- Calibracion\n[2] -- Reparacion\n[3] -- Otros");
System.out.print("Elija: ");
tipo = Integer.parseInt(teclado.nextLine());
switch (tipo) {
case 1:
mantenimientos.add(new Calibracion(new Usuario(numCliente, nombre, celular), equipo));
break;
case 2:
System.out.print("Pieza que falla: ");
String pieza = teclado.nextLine();
mantenimientos.add(new Reparacion(new Usuario(numCliente, nombre, celular), equipo, pieza));
break;
case 3:
System.out.print("Descripcion del mantenimiento: ");
String descripcion = teclado.nextLine();
mantenimientos.add(new Otros(new Usuario(numCliente, nombre, celular), equipo, descripcion));
break;
default:
System.out.println("Tipo inexistente");
}
}
catch(NumberFormatException nfe) {
System.out.println("ERROR: Introduzca solo números");
tipo = 0;
}
}//Fin del while
//Mostramos datos del mantenimiento registrado
System.out.println("\nMANTENIMIENTO REGISTRADO:\n");
System.out.println(mantenimientos.get(mantenimientos.size() - 1));
}

private static void listarMantenimientos() {
System.out.println("\nLISTADO DE MANTENIMIENTOS");
System.out.println("------- -- --------------\n");
for (Mantenimiento mant: mantenimientos)
System.out.println("\n" + mant + "\n");
}

}

Fíjate que al listar los objetos del ArrayList, aunque están todos guardados como Mantenimiento, luego al imprimirse en pantalla cada objeto se comporta como un Calibracion, o un Reparacion o un Otros, según corresponda.

Esto se llama polimorfismo, otro término más que hay que conocer en POO

Citar
      MANTENIMIENTO EQUIPOS
      ------------- -------

[1] --- Registrar nuevo Mantemimiento
[2] --- Listar Mantenimientos registrados
[3] --- TERMINAR PROGRAMA
Elija opcion: 2

LISTADO DE MANTENIMIENTOS
------- -- --------------


Datos Usuario: Nº Cliente: 1000
Nombre: Lucas Ramirez   Celular: 657908742
   ---------------
Equipo: Impresora de tinta HP900C
   ---------------
Tipo Manteminiento: Calibracion


Datos Usuario: Nº Cliente: 1001
Nombre: Sara Pelaez   Celular: 634561290
   ---------------
Equipo: Laptop Lenovo CN2000
   ---------------
Tipo Manteminiento: Reparacion
Pieza que falla: Pantalla


Datos Usuario: Nº Cliente: 1002
Nombre: Jorge Morales   Celular: 65533990
   ---------------
Equipo: Smartphone Samsung G300
   ---------------
Tipo Mantenimiento: Otros
Descripcion: Sustituir batería por una de 6500mAh


Pregunta si algo no ha quedado claro.
Un saludo.
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".