É 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