Classes Internas (postagem 2/2)
Autor: Gustavo | Publicado: 2015-03-18T09:10:00-03:00


Sobrescrevendo métodos



 Antes
irei apenas fazer uma recordação da
utilização da
sobrescrição de métodos o que é uma característica muito
utilizada em OO
e
essencial para o que iremos falar no resto desta postagem,
caso fique bem a vontade sobre o assunto, poderá ir direto para o
próximo
item.

 Sempre
que uma classe utiliza o relacionamento É-UM é instanciada e
referenciada a partir da classe filho, é herdado os membros de sua
classe pai, porém quando sua classe pai é a classe de referência e
a classe filho na instanciação, apenas os métodos que a classe pai
possue que serão executados e em caso de haver sobrescrição ou
seja, possuir métodos com o mesmo nome que as da classe pai aí sim
estes serão executados..



Exemplo:

 
 
 

  
class
   ClassePai{

 public
   void
   metodoX(){

  System.out.println("X
   pai");

 }

 public
   void
   metodoY(){

  System.out.println("Y
   pai");

 }

 public
   void
   metodoZ(){

  System.out.println("Z
   pai");

 }

}

  
class
   ClasseFilho extends
   ClassePai
   {


             @Override

 public
   void
   metodoY(){

  System.out.println("Y
   filho");

 }

 public
   void
   metodoW(){

  System.out.println("w
   filho");

 }

}

 






public
class
ClasseTesteSobrescricao{

 public
static void
main(String ...args){

  ClassePai
p = new
 ClasseFilho();

  p.metodoX();//
Ok roda referencia pai imprime “X
pai”

  p.metodoY();//
Ok roda imprime “ Y filho”
(sobrescreve)

  p.metodoW();//
ERRO DE COMPILACAO

  ClasseFilho
o = new
 ClasseFilho();

  o.metodoX();//
Ok roda referencia pai imprime “X
pai”

  o.metodoY();//
Ok roda imprime “ Y filho”
(sobrescreve)

  o.metodoW();//
ok

 }

}



Saida:

X
pai

Y
filho

X
pai

Y
filho

w
filho

 

 É
aconselhável sempre que for sobrescrever um método, colocar a
anotação @Override isso vai informar ao compilador que você já
está esperando sobrescrever um método que deveria ser herdado.
Assim
caso a
assintura do método que esteja
sobrescrevendo não
exista,
um erro de compilação será gerado.

 Entendido
isto, me sinto muito mais seguro que este conceito está bem
compreendido, 


darei
continuidade ao assunto principal.



Classes
Internas anônimas



 São
chamadas de classes internas anônimas por além de serem internas
conforme as classes que temos apresentado neste post e no anterior,
seus nomes não são definido ao declararmos uma classe.

 Existem
duas formas diferentes de definirmos uma classe interna anônima e
falarei de ambas aqui.

 Agora
vejamos esta classe ClasseNormal que definimos logo aqui
abaixo:



public
class
ClasseNormal
{

 public
void
teste(){

 System.out.println("Exemplo
de uma classe");

 }

//...muito
mais métodos implelementados abaixo

}

 Agora
vamos supor que queremos em apenas um momento criar uma classe igual
a definida acima mas que necessita sobrescrever este primeiro método
e todos os outros pudessem ser aproveitados.

Este
é o momento de usarmos as classes anônimas conforme abaixo:



public
class
ClasseInternaAnonima {

 public
static
void
main(String... args)
{

  ClasseNormal
iia
= new
ClasseNormal()
{

   public
void
teste() {

    System.out.println("Exemplo
de classe interna anonima");

   }

  };

  iia.teste();//irá
imprimir o método sobrescrito “Exemplo
de classe interna anonima” ''''   //que
utilize dos outros métodos já desenvolvidos da class

 }

}

 Temos
acima um exemplo simples de classe anônima. Ela não possui nome mas
sabemos dizer quais são suas características, a
idéia aqui é sobrescrever qualquer
método que a classe ClasseNormal possui. Vale lembrar que se por
algum motivo definir
algum método que a ClasseNormal não possui, este
método não poderá ser utilizado pois
a classe de referência
é a ClasseNormal.

 Uma
característica importante de se notar ao ver uma classe anônima é
o ponto e virgula (;), isto porque não é comum e não estamos
acostumados colcar no final de uma classe mas é necessário ou o
compilador irá acusar.

 As
classes anônimas podem inclusive implementar ou estender uma
outra classe. Mas veja bem o que acabei de dizer, apenas uma e ou
implementa ou se estende. Não é possível fazer os dois assim como
não é possível implementar mais de uma interface, quanto a
estender uma classe isso já se é previsto. :)

Podemos
então criar uma classe anônima que implemente uma interface da
seguinte forma:



public
interface
InterfaceInternaAnonima {

 public
void
teste();

}

class
Aux {

 void
exemplo(InterfaceInternaAnonima f)
{

  System.out.println("exemplo");

  f.teste();

 }

}

public
class
ClasseInternaAnonima {

 public
static
void
main(String... args)
{

  Aux
b
= new
Aux();

  b.exemplo(new
InterfaceInternaAnonima() {

   public
void
teste() {

    System.out.println("Exemplo
de classe interna anonima");

   }

  });

 }

}

Aproveito
para lhes apresentar a segunda forma de se declarar uma classe
anônima :)

 Aqui,
ao invés de  declararmos a classe como uma variável de instância,
estamos a declarando para passar um parâmetro que por ser uma
interface, exige que implemente ainda o método teste() ou o
compilador acusará erro de método(s) não implementado(s) e para
finalizar esta estrnha forma de se delcarar uma classe, já antecipo
a resposta de sua possível pergunta, não, não é necessário
colocarmos a palavra implements,
o compilador já perceberá que é uma interface e que será uma
classe anônima fazendo desnecessário a colocação da paravra-chave
que define que irá implementar uma interface.




Classes
estáticas
aninhadas




 Último
item a ser discutido aqui, mas não menos importante são as classes
estáticas aninhadas. Elas são muito parecidas com as classes
internas comuns na forma visual, mas seu comportamento é bem
diferente na prática por isso não são consideradas classes
internas “por alguns autores”. Isto porque por definição, o
relacionamento especial entre duas classes (externa e a classe
interna) é de que as duas instâncias compartilham um
relacionamento, em quanto uma classe aninhada estática não possui
esta característica. 


 A
classe estática aninhada não é considerada classe interna, onde
apesar do seu escopo se encontrar dentro de outra classe, é
possível se acessar
como qualquer outro membro estático da classe sem a necessidade de 
uma instanciação.  O
modificador static não
é aceito em classes com excecão neste
caso definindo
que a classe é um membro
estático da classe externa:



 public
class
EstaticaAninhada {

 static
class
InternaEstatica{

  public
void
manobra2(){

   System.out.println("cut-back");

  }

 }

 

 public
static
void
main(String ...args){

  Normal.InternaEstatica1
n
= new
Normal.InternaEstatica1();

  n.manobra();

  

  InternaEstatica
ea
= new
InternaEstatica();

  ea.manobra2();

 }

}

class
Normal{

 static
class
InternaEstatica1{ 


  public
void
manobra(){

   System.out.println("HangFly");

  }

 }

}



Grato
e Criticas a vontade :)

Git=&gt;https://github.com/gmachado1/blog