sexta-feira, 5 de agosto de 2011

Java - Herança

Herança: tem a haver com tipos e subtipos.  Subtipos herdam os membros da classe mãe.  Nota: construtores não são considerados membros, e portanto não são herdados.
Em Java, cada classe pode ter apenas uma classe mãe, embora acabe herdando membros não só da mãe, mas também indiretamente da avó, bisavó, etc. (se houver).
Isto cria uma hierarquia de classes em forma de árvore.  A raiz desta árvore é a classe pré-definida Object.

Exemplo:

class MountainBike extends Bicycle {

    // new fields and methods defining 
    // a mountain bike would go here

}

Nomenclatura: subclasse, classe derivada, clesse estendida. classe filha; superclasse, classe base, classe mãe.

Se sua classe é declarada sem mãe, Java a faz automaticamente filha de Object.

Apesar de herdar todos os membros das classes ancestrais, nem todos podem ser acessados.  Apenas membros os seguintes membros pode ser acessados numa subclasse:
  • public
  • protected da mãe
  • package-private, se a subclasse estiver no mesmo pacote da classe base
O que se pode fazer numa subclasse:
Com campos:
  • usar livremente os campos public e protected herdados, independentemente do pacote onde esteja; se estiver no mesmo pacote da mãe, pode tambem usar os campos package-private.
  • declarar um campo com o mesmo nome de um herdado, escondendo o herdado.
  • declarar novos campos que não estejam nas classes ancestrais.
Com métodos:
  • chamar livremente métodos public e protected herdados, independentemente do pacote onde esteja; se estiver no mesmo pacote da mãe, pode tambem usar os campos package-private.
  • escrever um novo método de instância com a mesma assinatura de um método herdado, redefinindo-o.
  • escrever um novo método de classe (static) com a mesma assinatura de um método herdado, escondendo-o.
  • declarar novos métodos que não estejam nas classes ancestrais.
  • escrever um construtor que chame um construtor da superclasse, seja explicitamente com a palavra reservada super, seja implicitamente.
Objetos de um certo tipo são também considerados objetos de qualquer supertipo deste tipo.  Java permite que seja usado um objeto de tipo X em qualquer parte do código onde se espera um objeto de tipo X ou de um tipo ancestral de X.

Por outro lado, o compilador não permite que seja usado um objeto de tipo X em lugares onde se espera algo de um tipo descendente de X, a não ser que se use casting.

MountainBike myBike = (MountainBike)obj;

Ao usar casting, o programador assume a responsabilidade de garantir que haverá um objeto do tipo adequado lá na hora da execução.  Por sua vez, o compilador insere código para verificar se isto realmente foi feito.  Existe o operador instanceof que nos diz se um dado objeto é ou não de uma dada classe:

if (obj instanceof MountainBike) {
    MountainBike myBike = (MountainBike)obj;
}

Reuso de código: muito do que precisamos já foi implementado por alguém.
É mais fácil aproveitar o que já existe, e apenas acrescentar o restante a uma classe existente. Exemplos na hierarquia de classes de Java.

Há duas formas de reuso: por herança e por agregação.  Use herança apenas quando realmente se tratar de um caso de especialização.  Caso contrário, considere agregação.  Exemplos: Pilha, Fila, ListaLigada.

Acoplamento dinâmico: o termo "acoplamento" refere-se ao modo como nomes de métodos são associados ao código que será executado para uma dada chamada.  Em Java, a novidade em relação a C é que esta decisão é postergada até o momento da execução do código, enquanto que em C o acoplamento é feito no momento da compilação.  Isto permite maior liberdade no desenvolvimento independente de partes de um grande sistema.

No tutorial, acoplamento dinâmico é chamado de virtual method invocation, na seção sobre polimorfismo.

Nenhum comentário:

Postar um comentário