Sobes.tech
Junior

O que é visibilidade no contexto da programação Java?

sobes.tech IA

Resposta da IA

A visibilidade no contexto do Java (também chamada de âmbito de visibilidade) determina a acessibilidade de uma variável, método, construtor ou classe de outras partes do programa. É controlada pelos modificadores de acesso.

No Java, existem quatro níveis de visibilidade:

  1. public: Acessível de qualquer lugar dentro e fora do pacote.
  2. protected: Acessível dentro do mesmo pacote e em subclasses (mesmo em outros pacotes).
  3. Modo padrão (default ou package-private): Acessível apenas dentro do mesmo pacote. Não é especificado explicitamente por um modificador.
  4. private: Acessível apenas dentro da mesma classe.
Modificador Classe Pacote Subclasse (fora do pacote) Qualquer classe (fora do pacote)
public Sim Sim Sim Sim
protected Sim Sim Sim Não
Default Sim Sim Não Não
private Sim Não Não Não

O uso de modificadores de visibilidade desempenha um papel importante na encapsulação e no controlo de acesso aos elementos do programa.

Exemplo de uso de modificadores:

// Classe A no pacote com.example.package1
package com.example.package1;

public class ClassA {
    public int publicVar;
    protected int protectedVar;
    int defaultVar; // Modificador padrão
    private int privateVar;

    public void publicMethod() {
        // Pode aceder a todas as variáveis da classe ClassA
        System.out.println("Método público em ClassA");
    }

    protected void protectedMethod() {
        System.out.println("Método protegido em ClassA");
    }

    void defaultMethod() {
        System.out.println("Método padrão em ClassA");
    }

    private void privateMethod() {
        System.out.println("Método privado em ClassA");
    }

    public void accessMembers() {
        publicVar = 1;
        protectedVar = 2;
        defaultVar = 3;
        privateVar = 4; // OK, acesso dentro da classe
        privateMethod(); // OK, acesso dentro da classe
    }
}
// Classe B no mesmo pacote com.example.package1
package com.example.package1;

public class ClassB {
    public void accessClassAMembers(ClassA objA) {
        objA.publicVar = 10; // OK, público
        objA.protectedVar = 20; // OK, protegido (mesmo pacote)
        objA.defaultVar = 30; // OK, padrão (mesmo pacote)
        // objA.privateVar = 40; // Erro de compilação, privado
        objA.publicMethod(); // OK, público
        objA.protectedMethod(); // OK, protegido (mesmo pacote)
        objA.defaultMethod(); // OK, padrão (mesmo pacote)
        // objA.privateMethod(); // Erro de compilação, privado
    }
}
// Classe C em outro pacote com.example.package2
package com.example.package2;
import com.example.package1.ClassA;

public class ClassC extends ClassA { // ClassC é uma subclasse de ClassA
    public void accessClassAMembersFromSubclass() {
        publicVar = 100; // OK, público
        protectedVar = 200; // OK, protegido (subclasse, mesmo em outro pacote)
        // defaultVar = 300; // Erro de compilação, padrão (outro pacote)
        // privateVar = 400; // Erro de compilação, privado

        publicMethod(); // OK, público
        protectedMethod(); // OK, protegido (subclasse, mesmo em outro pacote)
        // defaultMethod(); // Erro de compilação, padrão (outro pacote)
        // privateMethod(); // Erro de compilação, privado
    }
}
// Classe D em outro pacote com.example.package2 (NÃO subclasse de ClassA)
package com.example.package2;
import com.example.package1.ClassA;

public class ClassD {
    public void accessClassAMembers(ClassA objA) {
        objA.publicVar = 1000; // OK, público
        // objA.protectedVar = 2000; // Erro de compilação, protegido (outro pacote, não subclasse)
        // objA.defaultVar = 3000; // Erro de compilação, padrão (outro pacote)
        // objA.privateVar = 4000; // Erro de compilação, privado

        objA.publicMethod(); // OK, público
        // objA.protectedMethod(); // Erro de compilação, protegido (outro pacote, não subclasse)
        // objA.defaultMethod(); // Erro de compilação, padrão (outro pacote)
        // objA.privateMethod(); // Erro de compilação, privado
    }
}

Compreender a visibilidade ajuda a criar um código mais robusto e modular, limitando o acesso indesejado aos detalhes internos das classes.