Anotações OCJP

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

Mantenha a classe com classes internas

Resolvi começar este artigo com uma bonita citação extraída diretamente de um tutorial da Oracle de Java:

A class is the blueprint from which individual objects are created.

Traduzindo de forma livre e poética o texto acima:

Uma classe é como um padrão pelo qual objetos individuais são criados.

Geralmente utilizamos este padrão em uma ou mais classes de primeiro nível. As classes de primeiro nível, também conhecidas como top level class, são assim chamadas pois estas classes não estão dentro de outra classe.

Já as classes internas são classes que estão dentro de outras classes (logo devem estar abaixo ao menos de uma classe de primeiro nível). O exemplo abaixo explica melhor o que foi dito.

class PrimeiroNivel{
  //uma classe de primeiro nivel
}
class PrimeiroNivel2{
  //outra classe de primeiro nivel
  class Interna{
    //esta e uma classe interna, dentro da classe PrimeiroNivel2
  }
}

As classes internas podem ser dividas entre três categorias (alguém pode se perguntar, e as classes static que estão dentro de outras classes? Falarei delas em um futuro artigo sobre classes estáticas aninhadas), as quais descreverei abaixo:

  • Classe interna: Classe declarada dentro de outra classe. Pode ter todos os modificadores de acesso (public, private, protected ou sem modificador). Tem acesso direto a todos os atributos e métodos da classe de nível mais acima, porém a classe acima não tem acesso direto aos atributos e métodos da classe mais abaixo. Para acessar este tipo de classe e seus membros, só no momento da instância da classe interna.
class PrimeiroNivel2{
  private class InternaPrivada{
    //uma classe de acesso privado, acesso somente dentro da classe de nivel mais acima
  }
  protected class InternaProtegida{
    //uma classe de acesso protegido, so quem esta no package ou por heranca acessa
  }
  public class InternaPublica{
    //uma classe de acesso publico, todas as classes tem acesso por instancia
  }
  class InternaDefault{
    //esta e uma classe de acesso default, so quem esta no package acessa
  }
}
//esta no mesmo package, por isso acessa a classe protegida
public class ClassesInternasAninhadas {
  public static void main(String[] args) {
    //lembre-se sempre de instanciar o objeto de niveis acima ate o primeiro nivel
    //acesso protegido
    PrimeiroNivel2.InternaProtegida cipr = new PrimeiroNivel2().new InternaProtegida();
    //acesso publico
    PrimeiroNivel2.InternaPublica cipu = new PrimeiroNivel2().new InternaPublica();
    //ou acesso default
    PrimeiroNivel2.InternaDefault cipd = new PrimeiroNivel2().new InternaDefault();
  }
}
  • Classe internas locais (de método/construtor/blocos static e de instância (são blocos de código executados durante a carga e a instância da classe respectivamente)): Classe declarada dentro dos casos citados acima. Pode ter somente o modificador padrão de acesso (sem modificador). Tem acesso direto a todos os atributos e métodos da classe de nível mais acima. O acesso destas classes internas é somente dentro destes casos citados (não é possível acessar por exemplo um método de uma classe interna de construtor fora deste construtor).
class ClasseLocal{
  static{
    class ClasseLocalStatic{
      //um bloco static que tem uma classe acessivel apenas a outras classes deste bloco
      void m1(){
      System.out.println("ClasseLocalStatic - m1");
      }
    }
    ClasseLocalStatic c1 = new ClasseLocalStatic();
    c1.m1();
  }
  {
    class ClasseLocalInstancia{
      //um bloco de instancia que tem uma classe acessivel apenas a outras classes deste bloco
      void m1(){
        System.out.println("ClasseLocalStatic - m1");
      }
    }
    ClasseLocalInstancia c1 = new ClasseLocalInstancia();
    c1.m1();
  }
  public ClasseLocal(){
    class ClasseLocalConstrutor{
	  //um construtor que tem uma classe acessivel apenas a outras classes deste construtor
      void m1(){
        System.out.println("ClasseLocalConstrutor - m1");
      }
    }
    ClasseLocalConstrutor c1 = new ClasseLocalConstrutor();
    c1.m1();
  }
  void metodoClasseLocal(){
    class ClassesLocaisMetodo{
    	//um metodo que tem uma classe acessivel apenas a outras classes deste metodo
    	void m1(){
          System.out.println("ClasseLocalMetodo - m1");
        }
    }
    ClassesLocaisMetodo c1 = new ClassesLocaisMetodo();
    c1.m1();
  }
}

public class ClassesInternasAninhadas {
  public static void main(String[] args) {
    //a vida das classes perdura durante a execucao
    //executados bloco static, bloco de instancia e o construtor
    ClasseLocal cl = new ClasseLocal();
    //executado o metodo
    cl.metodoClasseLocal();
  }
}
    • Classe internas anônimas (não estática): Utiliza-se o conceito de classes anônimas para redefinir o comportamento de um método de uma classe ou interface. Não se aplicam modificadores de acesso a classe anônima. Porém esta classe tem acesso apenas as variáveis e métodos final da classe acima que realiza a instância da classe anonima. Por último, a classe anônima possui acesso normal a todas as variáveis e métodos da classe e sua respectiva árvore de herança (já falei de herança em Herança, casting e outros laços de familia) que a classe anônima implementa. O exemplo abaixo explica melhor o que foi dito.
    class Classe1{
      void m1(){System.out.println("Classe1");}
    }
    interface Interface1{
      String m2();
    }
    public class ClassesAnonimas {
      public static void main(String[] args) {
        //reimplementando a classe com classe anonima
        Classe1 c1 = new Classe1(){
          //sobrescreve comportamento original de m1
          void m1() {
            System.out.println("Classe Anonima da Classe1");
          }
        };
        //utilizando o metodo m1
        //com implementacao da classe anonima
        c1.m1();
        //a classe anonima pode usar variaveis
        //do tipo final na classe que a implementa
        final int i = 1;
        Interface1 i1 = new Interface1(){
          //a classe anonima tem obrigacao
          //de sobrescrever o metodo
          public String m2() {
            return "Classe Anonima da Interface" + i;
          }
        };
        System.out.println(i1.m2());
      }
    }
    

    Ao rodar esta classe, o resultado será:

    Classe Anonima da Classe1
    Classe Anonima da Interface1

    Então é isso, bons estudos e até a próxima.

    Anúncios

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: