[OCPJP6] 005 – Declarações e controle de acesso

Controles de acesso em métodos e variáveis

Um pouco diferente das classes, os métodos e variáveis podem ser declarados como:

  • public
  • private
  • default (lembrando que default é oculto)
  • protected

Segue abaixo um pouco de cada controlador de acesso.

public

Quando um método ou variável é declarado como public, significa que todas as classes que a enxergam (independente do caminho do pacote) podem acessar. Vejamos 3 diferentes formas de acessar:

  • A partir de um método declarado na mesma classe.
  • A partir de um método usando uma referência da classe.
  • A partir de um método herdado.

private

Quando um método ou variável é declarado como private, significa que apenas a classe que a declarou pode acessar. Más, é importante lembrar que as variáveis podem ser alteradas por outros métodos public (ex: setters).

Brincando um pouco com private 🙂

Dentro de uma classe “A” existe um método private com o nome de fazAlgumaCoisa(), e uma outra classe “B” estende (extends) a classe “A”, e essa classe também tem um método fazAlgumaCoisa().

 – A classe “B” vai compilar?

Esse método sobrescreveu o método da classe “A”? (resposta no final)

default

Quando declaramos os métodos ou as variáveis como default, significa que apenas a classe que a declarou + as classes do mesmo pacote podem acessar.

 protected

Esse controle de acesso… esse sim (muahahahahaha)… esse tem muitas pegadinhas.

A primeira vista é simples =) Só acessam os métodos e variáveis protected as classes que estão no mesmo pacote ou através de herança.

Brincando um pouco mais =)

Agora com alguns exemplos:

package certificacao;
// A super classe (Generelização)
public class Fruta {
    private String nome;
    protected String getNome() { return nome; }
    protected void setNome(String nome) { this.nome = nome; }
}
package certificacao.citrica;
import certificacao.Fruta;
// Classe específica
public class FrutaCitrica extends Fruta {
    private String vitaminaC;
    String getVitaminaC() { return vitaminaC; }

    @Override
    public String toString() {
        // Acessando um método protected
        return super.getNome();
    }
}
package certificacao.citrica.plus;
import certificacao.citrica.FrutaCitrica;
// Classe mais específica
public class FrutaCitricaPlus extends FrutaCitrica {
    private String[] arrayVitaminaC;
    public String[] getArrayVitaminaC() { return arrayVitaminaC; }

    public String getFirstVitaminaC() {
        // NÃO COMPILA, o método getVitaminaC() tem um
        // controlador default e está em um pacote diferente.
        return super.getVitaminaC();
    }
}

Um plus no assunto =)

Será que podemos modificar o nível do controle de acesso de um método em herança, sobrescrevendo-o?

– Sim, mas apenas pode aumentando o nível do controle de acesso.

 E agora a resposta da brincadeirinha com private =)

Sim, o código irá compilar!

É possível criar um método com o mesmo nome do método private da classe “A” que não irá sobrescrever, porque a classe “B” nem sabe que existe o método fazAlgumaCoisa() da classe “A”.

Comentem, estendam o assunto… Compartilhem =)

[OCPJP6] 003 – Declarações e controle de acesso

Modificadores e controles de acesso em classes

As classes em Java, são compostas por variáveis e métodos. O modo como você declara -utilizando um modificador ou controle de acesso – uma classe, um método ou uma variável afeta o comportamento do código. Vejamos abaixo isso em classes:

Os modificadores se dividem em duas categorias:

  1. Modificadores de acesso: public, protected, private.
  2. Modificadores que não se referem a acesso (incluindo strictfp, final e abstract).

Os controles de acesso (nível de acesso) são classificados em quatro e são representados por três modificadores de acesso. O quarto controle de acesso – chamado de acesso default – é o que você obtém quando não usa nenhum dos três modificadores de acesso.

Dentre os quatro controladores de acesso apenas dois podem ser usados nas declarações das classes, são eles public ou default, a não ser que seja uma inner class (classe interna) que pode usar o controlador private.

Modificadores de acesso

default

Uma classe com acesso default não tem nenhum modificador na declaração. Esse é o controle que você obtém quando não declara um modificador. As classes de nível default só podem ser acessada por classes do mesmo pacote.

Exercicio.java

package certificacao;

class Exercicio { }

Prova.java

package certificacao.prova;
import certificacao.Exercicio;

class Prova extends Exercicio { }

A classe Prova.java não irá compilar porque está em pacote diferente. Para essa classe compilar seria necessário mudar o modificador de acesso para public da classe Exercicio.java ou mover uma das classes para o mesmo pacote podendo manter o modificador default.

public

Uma classe com acesso public dá acesso a todas as classes de todos os pacotes. No entanto, não esqueça de que ao utilizar uma classe public de outro pacote, você precisará importar a classe.

Modificadores que não se referem a acesso

final

Classes com o modificador final significam que não podem ser estendidas, ou seja, nenhuma outra classe pode herdar de uma classe final. Na prática, você quase nunca criará uma classe final. As classes final acabam com um benefício fundamental da programação OO – a herança. A não ser que você tenha uma série preocupação de segurança.

Exercicio.java

package certificacao;

public final class Exercicio { }

Prova.java

package certificacao.prova;

import certificacao.Exercicio;

class Prova extends Exercicio { }

Neste caso a classe Prova.java não compilaria.

abstract

Uma classe abstract não jamais pode ser instanciada. O seu único propósito/missão, é ser estendida (herdada). Classes abstract são útilizadas para deixar as coisas genéricas, comuns a suas especializações (classes que herdam dela).

Carro.java

package certificacao.automovel;

public abstract class Carro {

    private String cor;
    private String valor;
    // getters and setters
}

Bmw.java

package certificacao.automovel;

public class Bmw extends Carro {

    private Turbo turbo;
    // getters and setters
}

Neste caso uma Bmw tem tudo que um Carro tem + turbo. Pensando em uma outra especialização de Carro, poderíamos criar um Palio com tudo que um Carro tem, mas sem o turbo da Bmw rs.

Mais pra frente irei escrever um pouco sobre polimorfismo, e como as classes abstratct são importante em questões de flexibilidade e extensibilidade.

Analisando os dois casos: Não é possível ter uma classe final e abstract ao mesmo tempo. Uma anularia a outra rs =)

Comentem, estendam o assunto… Compartilhem =)