Páginas

sexta-feira, 1 de março de 2013

Diferenças entre modificador de acesso default e protected.



É comum acharmos que os modificadores de acesso default e protected possuem exatamente as mesmas características, ou seja, terem escopo de pacote apenas, mas isso é um erro.

A primeira diferença entre os modificadores, mas essa eu acredito que você já saiba, é que não podemos atribuir o modificador protected a uma classe, esse é restrito a métodos e variáveis de instância.

Exemplo classe default:

class ClasseDefault{

       public static void main(String[] args){
             System.out.println("Classe Default");
       }
}


Para que uma classe tenha nível de acesso default essa não deve possuir nenhum modificador atribuído.

ATENÇÃO a seguinte sintaxe não existe default class ClasseDefault{...} caso você cometa esse sacrilégio receberá como castigo o erro abaixo:

ClasseDefault.java:1: error: class, interface, or enum expected default class ClasseDefault{

E como falei no inicio não se pode aplicar o modificador protected em uma classe, caso tente o compilador dirá em alto e bom som:

modifier protected not allowed here protected class…

Agora, a diferença mais importante é a seguinte:

Enquanto que, um método default só pode ser acessado por classes pertencentes ao mesmo pacote da classe que contém o método, um método protected pode ser acessado por qualquer classe que HERDE a classe que contém o método protected mesmo que tais classes estejam em pacotes diferentes. Ficou confuso? Vamos a um exemplo:

Supondo a seguinte classe:

package br.com.contextotec.pacoteA;

public class ClasseA {

       protected void metodoProtected() {
             System.out.println("Metodo Protected");
            
       }

       void metodoDefault(){
             System.out.println("Metodo Default");
       }
}

Note que temos dois métodos, um protected e outro default.

Se criarmos uma nova classe, em um pacote diferente e, por meio de uma variável de referência tentar acessar os métodos da ClasseA não conseguiremos, veja o exemplo:

package br.com.contextotec.pacoteB;

import br.com.contextotec.pacoteA.ClasseA;


public class ClasseB {
      
       public static void main(String[] args) {
             ClasseA classeA = new ClasseA();

             classeA.metodoDefault();
             classeA.metodoProtected();
            
       }

}

Ao tentar compilar essa classe receberemos não uma, mas duas mensagens de erro:

                The method metodoDefault() from the type ClasseA is not visible
                The method metodoProtected() from the type ClasseA is not visible

Agora, vamos tentar acessar os métodos por herança, cruzemos os dedos:

package br.com.contextotec.pacoteB;

import br.com.contextotec.pacoteA.ClasseA;

public class ClasseC extends ClasseA{

       public void metodoTest(){
             this.metodoProtected();
       }
      
}

Se tentarmos compilar a ClasseC teremos sucesso, pois como dito, um método protected torna-se acessível por herança mesmo que herdado por classes pacotes diferentes.

Agora o que aconteceria se criássemos uma nova classe que, através de uma instância da ClasseC tentasse acessar o método metodoProtected?

package br.com.contextotec.pacoteB;

public class ClasseD {
       public static void main(String[] args) {
             ClasseC classeC = new ClasseC();
            
             classeC.metodoProtected();
       }
      
}

Receberíamos o erro: The method metodoProtected() from the type ClasseA is not visible.

Mas por que isso ocorre visto que a ClasseD está no mesmo pacote da ClasseC? Isso corre porque o método quando herdado pela ClasseC torna-se private, sendo assim não pode ser acessado de uma variável de referencia, porém, se a ClasseD herdasse a ClasseC o método estaria disponível.

Você também pode, caso precise tornar o método público, efetuar a sobrescrita do método, alterando o modificador protected para public dentro da ClasseC da seguinte forma:

public class ClasseD extends ClasseA{

       @Override
       public void metodoProtected() {
             super.metodoProtected();
       }
      
}

Lembrando que, quando sobrescrevemos um método podemos alterar seu modificador de acesso desde que seja para um menos restritivo, nunca o contrário. 

Nenhum comentário:

Postar um comentário