Autor Tema: Diferencias entre public, private y protected Java. Ejercicio CU00693B# tutorial  (Leído 7104 veces)

Dan_SB

  • Avanzado
  • ****
  • Mensajes: 273
  • *<DanielsCK>*
    • Ver Perfil
Buenas noches. Vengo a resolver el ejercicio CU00693B del curso básico de POO de aprenderaprogramar. El enunciado dice así:

Citar
Considera que estás desarrollando un programa Java donde trabajas con la superclase Profesor y la subclase ProfesorEmerito. Crea el código para estas clases que cumpla los requisitos que indicamos.
Como atributos de la superclase tendremos nombre (String), edad (int) y añosConsolidados (int) declarados como protected.
En la subclase se trabajará con el campo adicional añosEmerito declarado como private.
Un método de la subclase será double obtenerSalarioBase () que obtendrá el salario base como (925 + añosConsolidados * 33.25 + 47.80 * añosEmerito).

Utilicé el mismo código del ejercicio anterior (CU00692B), con los cambios dichos:

Clase Profesor:
Código: [Seleccionar]
package Profe;

public class Profesor {
    protected String nombre;
    protected int edad, añosConsolidados;
    public Profesor(String nombre, int edad, int añosConsolidados){
        this.nombre = nombre;
        this.edad = edad;
        this.añosConsolidados = añosConsolidados;
    }   
    public void setNombre(String dato){nombre = dato;}
    public void setEdad(int dato){edad = dato;}
    public void setAñosConsolidados(int dato){añosConsolidados = dato;}
    public String getNombre(){return nombre;}
    public int getEdad(){return edad;}
    public int getAñosConsolidados(){return añosConsolidados;}
    public double obtenerSalarioBase(){
        double salarioBase = 725 + (añosConsolidados * 33.25);
        return salarioBase;
    }
}

Clase ProfesorEmerito:
Código: [Seleccionar]
package Profe;

public class ProfesorEmerito extends Profesor{
    private int añosEmerito;
    public ProfesorEmerito(String nombre, int edad, int añosConsolidados){
        super(nombre,edad,añosConsolidados);
        añosEmerito = 0;
    }   
    public void setAñosEmerito(int dato){añosEmerito = dato;}
    public int getAñosEmerito(){return añosEmerito;}
     public double obtenerSalarioBase(){
        return 925 + (añosConsolidados * 33.25) + (47.80* getAñosEmerito());
    }
}

Citar
Intenta acceder directamente al campo añosConsolidados desde la subclase (como si fuera un campo más de la subclase) para implementar este método. ¿Es posible sin utilizar una invocación a super ni un método get?

Si es posible acceder a el, pude acceder sin problemas desde la subclase.

Citar
¿Qué ocurre si el atributo en la superclase lo declaras private?

Netbeans se me enoja  ::)



Si declaramos este atributo como privado, solamente la super clase "Profesor" podrá acceder a ella.

Espero sus correcciones y comentarios,
Saludos!
« Última modificación: 14 de Agosto 2019, 18:48 por Ogramar »
"Luchar por tus sueños y cumplirlos... eso es vivir.."

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Hola Dan, todo correcto. Si el atributo fuera private, tendríamos que acceder a él usando un método get que fuera público. Mediante private generamos una restricción de acceso, incluso para las subclases. Las subclases solo conocerán aquello que sea protected ó public.

En return 925 + (añosConsolidados * 33.25) + (47.80* getAñosEmerito()); podemos usar tanto eso como

return 925 + (añosConsolidados * 33.25) + (47.80 * añosEmerito); ya que en esta clase no tenemos problemas para acceder al atributo añosEmerito.

Salu2

diego_godie

  • Sin experiencia
  • *
  • Mensajes: 9
  • Deseo Vivir de esto
    • Ver Perfil
Buenos días! ¿Cómo están? algo me causa curiosidad en esta respuesta
Hola Dan, todo correcto. Si el atributo fuera private, tendríamos que acceder a él usando un método get que fuera público. Mediante private generamos una restricción de acceso, incluso para las subclases. Las subclases solo conocerán aquello que sea protected ó public.

En return 925 + (añosConsolidados * 33.25) + (47.80* getAñosEmerito()); podemos usar tanto eso como

return 925 + (añosConsolidados * 33.25) + (47.80 * añosEmerito); ya que en esta clase no tenemos problemas para acceder al atributo añosEmerito.

Salu2

Al acceder al campo (desde la propia clase) "añosEmerito" podemos acceder con getAñosEmerito o añosEmerito.  Mi duda es si hay alguna diferencia entre las dos formas? ya que las dos hacen lo mismo. Habrá algún motivo para usar una u otra? Disculpen mi ignorancia

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil

Al acceder al campo (desde la propia clase) "añosEmerito" podemos acceder con getAñosEmerito o añosEmerito.  Mi duda es si hay alguna diferencia entre las dos formas? ya que las dos hacen lo mismo. Habrá algún motivo para usar una u otra? Disculpen mi ignorancia

Si la operación va a consistir únicamente en cambiar el valor actual por otro, da igual hacerlo de una manera o de otra.

Sin embargo, muchas veces vamos a querer que la operación sea algo más completa, ya se para aplicar alguna regla de seguridad, alguna comprobación, alguna operación intermedia, etc..

Por ejemplo, pensemos en un atributo edad de una clase Persona.

Si le pasamos un valor directamente al atributo .edad , sin pasar por su habitual setter .setEdad(), podremos introducir cualquier valor, incluso alguno que no tenga sentido, como puede ser un -100 negativo.
Porque no tiene sentido que una persona tenga -100 años....

En cambio, si lo hacemos mediante su método .setEdad(), ahí ya podemos aplicar reglas y filtros para asegurar la "calidad" del dato recibido.

Podemos rechazar edades con valor negativo:

Código: [Seleccionar]
public void setEdad(int edad) {

    if (edad < 0)
        System.out.println("ERROR: La edad no puede ser un valor negativo");
    else
        this.edad = edad;
}

O podemos automatizar ciertas operaciones, como actualizar otro atributos en función del valor de la edad:

Código: [Seleccionar]
public void setEdad(int edad) {

    if (edad < 0)
        System.out.println("ERROR: La edad no puede ser un valor negativo");
    else {
        this.edad = edad;
        if (edad > 75)
            this.listoParaJubilarse = true;
        else if (edad >= 18)
            this.aptoParaVotar = true;
    }
}

Y bueno, cualquier otra cosa que podamos necesitar.
Esta es la ventaja de usar métodos set para cambiar el valor de los atributos, que nos permite aplicar código extra para proteger la calidad del dato, automatizar otros procesos, etc...

Algunas veces no ocurrirá nada de esto, y usar el método será prácticamente igual que acceder directamente al atributo, porque serán casos donde no se requiere hacer nada especial al cambiar el valor.
Pero muchas otras veces, la mayoría, vamos a querer establecer reglas y límites para los datos que recibimos y para ello necesitaremos usar los métodos.
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

diego_godie

  • Sin experiencia
  • *
  • Mensajes: 9
  • Deseo Vivir de esto
    • Ver Perfil
Buenos días! Muchas gracias por la respuesta, tienen razón, mas precisamente el "encapsulamiento de datos". Puntualmente en esta clase no habría diferencia en usar una forma u otra, pero   me doy cuenta que aunque no sea así (al menos en la clase mencionada en el ejemplo), es mejor tener la buena costumbre de acceder a los campos mediante métodos de acceso y hacer validaciones necesarias por ejemplo.
Ya me faltan 5 lecciones para terminar el curso  ;)  Saludos!!

 

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".