Anotações OCJP

Minhas anotações para o exame da Oracle (OCJP)

Herança, casting e outros laços de família

Quem está estudando para a certificação já percebeu que existem alguns obstáculos a serem superados no que diz respeito a herança.

Resolvi então mostrar alguns pontos importantes sobre herança que devem ser lembrados.

1. Herança direta (Filho do pai): Vou chamar de herança direta pois se trata de um extender o comportamento da superclasse para a classe imediatamente abaixo. A chamada do metodo sobrescrito do pai deve ser feita (“respeitosamente”) através da palavra chave super.

class Pai{
  public void metodo(){System.out.println("Primeiro vem o pai...");}
}
class Filho extends Pai{
  public void metodo(){
    super.metodo();
    System.out.println("...depois vem o filho");
  }
}
class PaisEFilhos {
  public static void main(String[] args) {
    new Filho().metodo();
  }
}

Ao instanciar o objeto da classe, a saida no console será:
Primeiro vem o pai…
…depois vem o filho

2. Herança indireta(Avós, Bisavós e outros da árvore genealógica): Vou chamar este de herança indireta pois se trata de herdar um comportamento causado em uma classe de forma indireta. Uma classe chamada Avô poderia ter o metodo chamado por Pai e Filho herdaria esse comportamento de forma indireta (Afinal deve-se respeitar os comportamentos de Avô e Pai).

Bom, agora vamos ao assunto que é o motivador deste artigo. Quando ocorre a criação dos objetos em Java, o comportamento da chamada de um método não é definido pela referência que aponta para o objeto e sim definido pelo objeto que foi instanciado o qual a referência aponta. O exemplo abaixo esclarece melhor:

class Bisavo{
  public void metodo(){System.out.println("Será o bisavô?");}
}
class Avo extends Bisavo{
  public void metodo(){
    System.out.println("Ou será o avô?");
  }
}
class PaisEFilhos {
  public static void main(String[] args) {
    Bisavo bisa = new Avo();
    //vamos chamar a implementacao do objeto avo
    bisa.metodo();
}
}

Até agora está tudo tranquilo. Mas vamos bagunçar este comportamento com o Casting. O Casting nada mais é do que a afirmação ao compilador: “Eu sei o que estou fazendo, confie em mim que este objeto armazenado nesta referência realmente aponta para esta classe”. Para exemplificar, vamos usar a velha relação da fazenda:

class Animal{}
class Gato extends Animal{}
class Cachorro extends Animal{}
class CastingFazenda {
  public static void main(String[] args) {
    //ate agora ok, gato é um animal.
    Animal a = new Gato();
    //conversao ok, é um objeto gato
    Gato g = (Gato) a;
    //nao e cachorro, mas o compilador nao sabe!
    Cachorro c = (Cachorro) a;
  }
}

A última linha de código vai compilar, mas vai lançar uma exceção ClassCastException. O mesmo ocorre com vetor destes objetos.

class CastingVetorFazenda {
  public static void main(String[] args) {
    //criando vetor de animal e populando com objetos da classe Cachorro
    Animal[] animais = new Animal[10];
    for(int i = 0; i < animais.length;i++){
      animais[i] = new Cachorro();
    }
    //Compila, mas vai dar class cast exception. Nao ha como garantir que esse vetor é de gato.
    Gato[] c= (Gato[])animais;
  }
}

Atenção

Sim, foi para chamar a sua atenção mesmo! Quando criamos listas que já possuem definidas as regras de quais objetos de classe irão aceitar, o erro se dará na compilação. Observe o exemplo abaixo com ArrayList:

import java.util.*;
//classes de animais aqui(...)
class CastingListFazenda {
  public static void main(String[] args) {
    //criando lista de animal e adicionando objetos da classe Cachorro
    ArrayList animais = new ArrayList();
    for(int i = 0; i < animais.size();i++){
      animais.add(new Cachorro());
    }
    //Nem compila. Nao ha como garantir que esta lista é de gato.
    ArrayList<Gato> g= (ArrayList<Gato>)animais;
  }
}

Listas criadas utilizando o conceito de generics (Veja esta boa definição de generics feita pela Oracle) já bloqueiam antes da compilação. Desta forma, assegura que não haverá um objeto que possa causar um ClassCastException (E garantindo sempre que não existirão listas que receberão objetos que não tem relação alguma com a Classe (imagina um Gato numa lista de Cachorros, que confusão!)
Bom é isso aí, bons estudos e até a próxima!

Anúncios

3 Respostas para “Herança, casting e outros laços de família

  1. Lucas Guilherme Diedrich 17/04/2011 às 21:46

    Excelente post, só acho que ficou um pouco confuso o último exemplo, não vejo o cast para animais do tipo Gato!

    😉

  2. Pingback: Herança, casting e outros laços de família : JornalJava

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: