[OCPJP6] 016 – Orientação a objetos

Sobrecarga de construtores

Como vimos anteriormente o grande propósito de um construtor é instanciar uma classe, e indo além podemos definir contratos para instanciar uma determinada classe, ou seja, definir atributos obrigatórios e/ou padrões.

Por exemplo, uma classe Quadrado(int lado) define que toda instância de Quadrado obrigatoriamente deve atribuir um valor “lado”.

Legal né… E se eu quisesse oferecer a possibilidade de instanciar um Quadrado com lados fracionários? Quadrado(double lado)

package certificacao;
public class Quadrado {
    double lado;
    public Quadrado(int l) { this.lado = l; }
    public Quadrado(double l) { this.lado = l; }
}

E se houvesse uma herança (generalização -> especialização)? Até onde poderiamos ir? 😛

  • O construtor mais específico irá ser chamado
  • Se houver ambiguidade não irá compilar
package certificacao;
public class Pessoa {
    public Pessoa() { System.out.println("()"); }
    public Pessoa(Object param1) { System.out.println("(Object)"); }
    // Lembre-se: String é uma especialização de Object
    public Pessoa(String param1) { System.out.println("(String)"); }
}

– E se eu fizesse: new Pessoa(null); o que aconteceria?

Se você respondeu: (String) você acertou, porque String é a classe mais específica entre Object e String 😉

 – E seu ao invés de Pessoa(Object param1) eu tivesse Pessoa(Integer param1) o que aconteceria?

new Pessoa(null); não compilaria, porque o compilador não saberia o que fazer, já que Integer e String são ambíguos a null. Para funcionar seria necessário um cast new Pessoa((String)null);. Veremos mais sobre cast em breve.

Comentem, estendam o assunto… Compartilhem =)

[OCPJP6] 015 – Orientação a objetos

Construtores

Os construtores tem um grande propósito em orientação a objetos, criar uma instância de uma classe 🙂

Refresque-se [008], Complemente…

Regras

  • Um construtor pode ter vários argumentos.
  • Uma classe pode ter mais de um construtor.
  • Em herança:
    • Se a classe base (generalização) tiver apenas um construtor com argumentos, as classes especializadas devem implementar um construtor com os mesmos argumentos (podendo ser subtipos).
    • Todo construtor de uma especialização chama primeiro o construtor base super() implicitamente se não declarado.
    • Não pode declarar/implementar nada acima de uma chamada super().
    • Diferente dos métodos, diminuir ou aumentar o nível de acesso é possível.

Exemplos

1. Argumentos

package certificacao;
public class Animal {
    public Animal(Number n1) { System.out.println("animal"); }
}
package certificacao;
public class Cachorro extends Animal { }

A classe Cachorro não irá compilar porque é obrigatório a declaração do construtor com argumentos da classe base Animal.

public Cachorro (Number n1) { // ...

2. Argumentos

package certificacao;
public class Cachorro extends Animal {
    public Cachorro () { }
}

Mesma situação do exemplo 1 e mais 🙂

O que mais? Por um motivo oculto. Todo construtor chama implicitamente primeiro o construtor base super() e neste caso a classe base Animal não tem um construtor sem argumentos.

3. Argumentos

package certificacao;
public class Cachorro extends Animal {
    public Cachorro (Integer i1) { System.out.println("cachorro"); }
}

Também não funciona 😦 Por quê?

Porque o construtor sem argumentos não foi declarado na classe base Animal, e todo construtor irá chamar o método super() implicitamente quando não declarado, e nesse caso não irá encontrar também. Para funcionar…

package certificacao;
public class Cachorro extends Animal {
    public Cachorro (Integer i1) {
        super(i1);
        System.out.println("cachorro");
    }
}

🙂

Comentem, estendam o assunto… Compartilhem =)

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