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

Declarações de construtores

Em java um objeto é criado a partir de uma instância de classe e ao instanciar um objeto, pelo menos um construtor é invocado. Vejamos algumas definições de como criar um construtor.

Definições

  1. Se sua classe não tiver um construtor explicitamente definido, o compilador criará um.
  2. Não tem tipo de retorno.
  3. Pode ser declarado como public, default, protected ou private.
  4. Pode ter argumentos.
  5. Não pode ser static, final ou abstract.
  6. O modificador de acesso não precisa ser obrigatoriamente o mesmo que o da declaração da classe.

Exemplos

Construtor implicito

package certificacao;
public class Ferramenta { // extends Object { // implicitamente =D
    public static void main(String[] args) {
        // Possivel instanciar Ferramenta()
        // construtor padrao da classe Object
        System.out.println(new Ferramenta());
    }
}

Impedir instância de fora

package certificacao;
public class Ferramenta {
    // Impede a instância fora da classe,
    // Utilizado em padrões Singleton
    private Ferramenta() { }
}

Níveis de acesso

package certificacao;
public class Ferramenta {
    // Segue as normas de visibilidade
    // [default, protected, public] Ferramenta() { }
}

Com argumentos

package certificacao;
public class Ferramenta {
    // Obriga a definicao do argumento nome
    // new Ferramenta() não será mais acessível,
    // a não ser que declare também o construtor sem argumentos.
    public Ferramenta(String nome) {
        // Faz alguma coisa...
    }
}

Por enquanto é isso, mais pra frente vamos brincar com tudo isso 😉

Comentem, estendam o assunto… Compartilhem =)

Anúncios

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

Uma introdução aos modificadores synchronized, native e scrictfp

Estes modificadores são utilizados em métodos e para este módulo da prova da Oracle serão exigidos como um conhecimento superficial (apenas como palavras reservadas do Java). Apenas o scrictfp também pode ser utilizado em classes.

synchronized

Utilizado para garantir que o acesso ao método seja apenas por uma thread de cada vez. É importante notar que o modificador synchronized só pode ser utilizado em métodos – não variáveis e nem classes. Irei apresentar um pouco mais sobre o assunto no módulo de Threads =D

native

Declarado da mesma forma que os métodos abstratos:

package certificacao;
public class Ferramenta {
    public native void executaImplementacaoNativa(); // Em C, C++, etc...
}

Indica que o método está sendo implementado conforme a plataforma, frequentemente em C. Necessário utilizar a api JNI.

scrictfp

Faz com que os cálculos no bloco de código declarado executem um trabalho mais rigoroso dos números com pontos flutuantes, de acordo com a especificação IEEE. Mais sobre o assunto na página do wikipedia.

Comentem, estendam o assunto… Compartilhem =)

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

O modificador final em métodos e variáveis

O grande poder deste modificador é ser imutável!

métodos

Pode ser aplicado em um método com o intuito de não poder ser sobreescrito em herança.

package certificacao;

public class Calculadora {

    public final double soma(double... values) {
        double resultado = 0d;
        if (values != null) {
            for (double d : values) {
                resultado += d;
            }
        }
        return resultado;
    }
}
package certificacao;

public class CalculadoraCientifica extends Calculadora {

    // NAO COMPILA - o metodo soma nao pode ser sobrescrito
    public double soma(double... values) {
        double resultado = 0d;
        // outra regra
        return resultado;
    }
}

variáveis

Pode ser aplicado em um atributo de uma classe/método ou como um argumento de um método.

  • Como atributo de uma classe (inicialização)
package certificacao;

import java.math.BigDecimal;

public class Circulo {
    // NAO COMPILA - a variavel precisa ser inicializada
    private final BigDecimal Pi;
}
  • Como atributo de uma classe em um método (atribuição)
package certificacao;

import java.math.BigDecimal;

public class Circulo {

    private final BigDecimal Pi = new BigDecimal(3.14);

    public BigDecimal calculaArea(BigDecimal raio) {
        // NAO COMPILA - a variavel nao pode atribuir um outro valor
        Pi = new BigDecimal(3.14);
        return Pi.multiply(raio.pow(2));
    }

}
  • Como um parâmetro de um método
package certificacao;

import java.math.BigDecimal;

public class Quadrado {

    private BigDecimal lado;

    public void setLado(final BigDecimal l) {
        // NAO COMPILA - a variavel nao pode atribuir um outro valor
        l = l.multiply(BigDecimal.ONE);
        this.lado = l;
    }
}

algo engraçado

No dicionário modificador: algo que modifica!!

 – Então, que raio de modificador final é esse ?! 🙂

Comentem, estendam o assunto… Compartilhem =)

[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] 004 – Declarações e controle de acesso

De classes abstratas a interfaces

No último post escrevi um pouco sobre classes abstratas, hoje irei passar alguns conceitos de interface, e também alguns exemplos.

  1. Uma interface pode ser public ou default.
  2. Todos os métodos são implicitamente public e abstract. Em outras palavras, você não precisa declarar os modificadores public e/ou abstract no método, mesmo assim ele sempre será public e abstract.
  3. Todas os atributos definidos em uma interface devem ser public, static e final. Em outras palavras, as interfaces só podem declarar constantes (variáveis de não instância).
  4. Uma interface não pode implementar uma interface ou uma classe.
  5. Uma interface pode estender uma ou mais interfaces.
  6. Uma classe que implementa uma interface deve implementar todos os métodos.

Exemplos de métodos e atributos implícitos e explícitos:

Fruta.java

package certificacao;

public interface Fruta {
    public abastract String cor(); // metodo – explicito
}

FrutaCitrica.java

package certificacao;

public interface FrutaCitrica extends Fruta {
    String vitamina = "C"; // constante – public static final
    boolean isAcida(); // metodo – public abstract implicito
}

Um adicional: Interface + Classe Abstrata

Dado uma classe que implementa uma interface e não implementa os métodos, irá ocorrer erro de compilação. Veja abaixo:

Suco.java

package certificacao;

public interface Suco {
    public abstract boolean comAcucar(); // metodo – explicito
}

SucoNatural.java

package certificacao;

public class SucoNatural implements Suco {
    // ERRO
}

Mas, e se for uma classe abstrata?

package certificacao;

public abstract class SucoNatural implements Suco {
    // OK
}

Haaaaaaa… agora compila =) Por quê? 

– O método comAcucar() só precisa ser implementado em uma subclasse de instância, por exemplo public class SucoNaturalSimplesMas, também pode ser implementado na classe SucoNatural.

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 =)