Press enter to see results or esc to cancel.

Modificadores de acesso em Java

Antes de falarmos sobre os modificadores de acesso, precisamos entender como funcionam os pacotes. Caso você não saiba ou queira lembrar como funcionam os pacotes na linguagem Java, veja este post: Pacotes Java

São 4 os modificadores de acesso básicos da linguagem Java: private, padrão, protected e public. Eles servem para tornar componentes da sua aplicação mais ou menos acessíveis por outras partes do seu programa.

Todas as classes declaradas neste post fazem uso apenas do modificador public. As classes também podem fazer uso dos outros modificadores de acesso, mas neste primeiro momento veremos apenas como os seus membros funcionam com cada um deles.

public

O modificador de acesso public é o menos restritivo de todos. Ele permite que qualquer outra parte da sua aplicação tenha acesso ao componente marcado como public.

Dentro do mesmo pacote

Veja a definição das classes Carro e Motor:

package garagem;
public class Carro {
	public String marca;
	public String cor;
	public Motor motor;

	public void ligar()
	{
		this.motor.darPartida();
	}

	public String toString()
	{
		return marca + " " + cor + " " + motor.potencia;
	}
}
package garagem;
public class Motor {
	public int potencia;
	public void darPartida(){}
}

A classe Carro faz uso da classe Motor. Na classe Carro temos acesso à propriedade potencia e ao método darPartida() da classe Motor.

1

A classe Carro tem acesso a todos os membros marcados como public da classe Motor mesmo que as duas classes estejam em pacotes distintos.

Dentro de pacotes diferentes

Vamos colocar a classe Motor no pacote garagemdovizinho e fazer a importação na classe Carro:

package garagemdovizinho;
public class Motor {
	public int potencia;
	public void darPartida(){}
}
package garagem;
import garagemdovizinho.Motor;
public class Carro {
	public String marca;
	public String cor;
	public Motor motor;

	public void ligar()
	{
		this.motor.darPartida();
	}

	public String toString()
	{
		return marca + " " + cor + " " + motor.potencia;
	}
}

2

Mesmo com a classe Motor dentro do um pacote diferente, a classe Carro continua conseguindo acessar o método darPartida() e a propriedade potencia da classe Motor.

Classes derivadas

Membros marcados com o modificador de acesso public também são acessíveis por classes derivadas. Veja a declaração da classe Fusca que está no pacote garagem e a declaração da classe BrasiliaAmarela que está no pacote garagemdovizinho. Ambas as classes são derivadas da classe Carro:

package garagem;
public class Fusca extends Carro {

	public Fusca()
	{
		this.cor = "Branco";
		this.marca = "VW";
		this.ligar();
		this.toString();
	}
}
package garagemdovizinho;
import garagem.Carro;

public class BrasiliaAmarela extends Carro {
	public BrasiliaAmarela() {
		this.cor = "Amarelo";
		this.marca = "VW";
		this.ligar();
		this.toString();
	}
}

3

De todos os modificadores de acesso, o public é o menos restritivo. Veja o resumo da acessibilidade na imagem abaixo:

4

protected

Os membros das classes marcados com o modificador de acesso protected serão acessíveis por classes e interfaces dentro do mesmo pacote e por classes derivadas mesmo que estejam em pacotes diferentes.

Dentro do mesmo pacote

Veja a declaração das classes Carro e Motor dentro do pacote garagem:

package garagem;
public class Motor {
	public int potencia;
	protected void darPartida(){}
}
O método darPartida() da classe Motor está marcado com o modificador de acesso protected.
package garagem;
public class Carro {
	protected String marca;
	protected String cor;
	public Motor motor;

	protected void ligar()
	{
		this.motor.darPartida();
	}

	public String toString()
	{
		return marca + " " + cor + " " + motor.potencia;
	}
}
Os membros marca, cor e ligar() da classe Carro estão marcados com o modificador de acesso protected.

Veja a ilustração abaixo:

1

O método darPartida() da classe Motor é acessível pela classe Carro.

Dentro de pacotes diferentes

Vamos mover a classe Motor para o pacote garagemdovizinho e observar as mudanças. Veja a declaração das classes Carro e Motor:

package garagemdovizinho;
public class Motor {
	public int potencia;
	protected void darPartida(){}
}

package garagem;
import garagemdovizinho.Motor;
public class Carro {
	protected String marca;
	protected String cor;
	public Motor motor;
	
	protected void ligar()
	{
		this.motor.darPartida(); // O método darPartida() do tipo Motor não é visível.
	}
	
	public String toString()
	{
		return marca + " " + cor + " " + motor.potencia;
	}
}

5

A classe Carro não compila e recebemos a mensagem de que o método darPartida() do tipo Motor não é visível. Um membro marcado com o modificador de acesso protected só é visível para outras classes e interfaces localizadas dentro do mesmo pacote ou por seus herdeiros. Veremos como as classes derivadas se comportam com o uso de membros protected a seguir.

Classes derivadas

As classes derivadas têm acesso aos membros marcados como protected na sua classe mãe independentemente do pacote onde essas duas classes estejam localizadas. Veja a declaração das classes Fusca e BrasiliaAmarela abaixo:

package garagem;
public class Fusca extends Carro {

	public Fusca()
	{
		this.cor = "Branco";
		this.marca = "VW";
		this.ligar();
		this.motor.darPartida(); // O método darPartida() do tipo Motor não é visível.
		this.motor.potencia = 100;
		this.toString();
	}
}

package garagemdovizinho;
import garagem.Carro;

public class BrasiliaAmarela extends Carro {

	public BrasiliaAmarela() {
		this.cor = "Branco"; 
		this.marca = "VW"; 
		this.ligar();
		this.motor.darPartida();
		this.motor.potencia = 100;
		this.toString();
	}
}

Apenas o método darPartida() da classe Motor não é acessível pela classe Fusca. Todos os membros das classes Carro e Motor são acessíveis pela classe BrasiliaAmarela. Veja mais detalhes na imagem a seguir:

6

O modificador de acesso protected é mais restritivo do que o modificador public, mas é menos restritivo do que os modificadores padrão e private. Veja a imagem abaixo com o resumo do comportamento do modificador protected:

7

padrão

O modificador de acesso padrão, também conhecido como acessibilidade de pacote, é o modificador atribuído aos membros da classe que não foram marcados explicitamente com um outro modificador de acesso. Membros com acessibilidade de pacote só podem ser acessados por outras classes ou interfaces definidas dentro do mesmo pacote.

Dentro do mesmo pacote

Veja a definição da classe Carro e Motor dentro do pacote garagem com alguns dos seus membros com a acessibilidade de pacote:

package garagem;
public class Motor {
	public int potencia;
	void darPartida(){}
}

O método darPartida() tem a acessibilidade padrão.
package garagem;
public class Carro {
	String marca;
	String cor;
	public Motor motor;
	
	void ligar()
	{
		this.motor.darPartida();
	}
	
	public String toString()
	{
		return marca + " " + cor + " " + motor.potencia;
	}
}
As variáveis de classe marca, cor e o método ligar() têm a acessibilidade padrão.

1

Como as duas classes estão dentro do mesmo pacote, o método darPartida(), mesmo tendo a acessibilidade de pacote, continua sendo acessível pela classe Carro.

Dentro de pacotes diferentes

Ao colocar a classe Motor dentro do pacote garagemdovizinho, a classe Carro não consegue mais ter o acesso ao método darPartida() da classe Motor. Veja:

package garagemdovizinho;

public class Motor {
	public int potencia;
	void darPartida(){}
}

package garagem;
import garagemdovizinho.Motor;
public class Carro {
	String marca;
	String cor;
	public Motor motor;
	
	void ligar()
	{
		this.motor.darPartida(); // O método darPartida() do tipo Motor não é visível.
	}
	
	public String toString()
	{
		return marca + " " + cor + " " + motor.potencia;
	}
}

Perdemos o acesso ao método darPartida() da classe Motor.

5

A compilação da classe Carro falha e recebemos a mensagem de que o método darPartida() do tipo Motor não é visível.

Classes derivadas

Com classes derivadas a regra continua a mesma, só as classes derivadas declaradas dentro do mesmo pacote têm acesso aos membros com acessibilidade de pacote da classe mãe. Veja a definição das classes Fusca e BrasiliaAmarela abaixo:

package garagem;
public class Fusca extends Carro {

	public Fusca()
	{
		this.cor = "Branco";
		this.marca = "VW";
		this.ligar();
		this.motor.darPartida(); // O método darPartida() do tipo Motor não é visível.
		this.motor.potencia = 100;
		this.toString();
	}
}

 Apesar da variável de classe motor do tipo Motor estar visível, o método darPartida() não está.
package garagemdovizinho;
import garagem.Carro;

public class BrasiliaAmarela extends Carro {

	public BrasiliaAmarela() {
		this.cor = "Branco"; // O campo Carro.cor não é visível.
		this.marca = "VW"; // O campo Carro.marca não é visível.
		this.ligar(); // O método ligar() do tipo Carro não é visível.
		this.motor.darPartida();
		this.motor.potencia = 100;
		this.toString();
	}
}

Repare que na classe Carro, a qual a classe BrasiliaAmarela tem um relacionamento de herança, o método darPartida() da classe Motor não está visível. Mas na classe BrasiliaAmarela, o mesmo método é visível.

Veja na imagem abaixo o detalhamento de como estão as nossas classes e pacotes:

8

Observe que apesar das classes Fusca e BrasiliaAmarela terem acesso à classe Motor por herdarem da classe Carro, a acessibilidade aos membros da classe Carro por essas duas classes filhas é diferente. A classe Fusca só tem acesso à variável de classe potencia, enquanto a classe BrasiliaAmarela tem acesso à variável de classe potencia e ao método darPartida().

O modificador de acesso padrão é mais restritivo do que o modificador public e protected, mas ele é menos restritivo do que o modificador private. Veja o resumo da acessibilidade do modificador padrão abaixo:

9

private

O modificador de acesso private é o mais restritivo modificador de acesso. Todo membro de uma classe definido com o modificador private só é acessível para a própria classe. Não importa a localização dentro de pacotes ou se a classe foi herdada ou não, um membro private só é acessível dentro da mesma classe em que ele foi declarado.

Veja a declaração das classes Carro, Motor, Fusca e BrasiliaAmarela abaixo:

package garagem;
import garagemdovizinho.Motor;

public class Carro {
	private String marca;
	private String cor;
	public Motor motor;
	
	private void ligar()
	{
		this.motor.darPartida(); // O método darPartida() do tipo Motor não é visível.
	}
	
	public String toString()
	{
		return marca + " " + cor + " " + motor.potencia;
	}
}

package garagemdovizinho;

public class Motor {
	public int potencia;
	private void darPartida(){}
}

package garagem;

public class Fusca extends Carro {

	public Fusca()
	{
		this.cor = "Branco"; // O campo Carro.cor não é visível.
		this.marca = "VW"; // O campo Carro.marca não é visível.
		this.ligar(); // O método ligar() do tipo Carro não é visível.
		this.motor.darPartida(); // O método darPartida() do tipo Motor não é visível.
		this.motor.potencia = 100;
		this.toString();
	}
}

package garagemdovizinho;
import garagem.Carro;
public class BrasiliaAmarela extends Carro {

	public BrasiliaAmarela() {
		this.cor = "Branco"; // O campo Carro.cor não é visível.
		this.marca = "VW"; // O campo Carro.marca não é visível.
		this.ligar(); // O método ligar() do tipo Carro não é visível.
		this.motor.darPartida(); // O método darPartida() do tipo Motor não é visível.
		this.motor.potencia = 100;
		this.toString();
	}
}

Repare que todo membro marcado com o modificador private não é acessível por outras classes.

10

Veja o resumo do comportamento do modificador de acesso private na imagem a seguir:

11

Conclusão

Os modificadores de acesso auxiliam na organização dos componentes da sua aplicação ao tornar os membros das classes mais ou menos acessíveis por outras partes do seu programa.

Os modificadores de acesso em ordem do mais restritivo para o menos restritivo são:

  1. private
  2. padrão ou acessibilidade de pacote
  3. protected
  4. public
Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInEmail this to someone
Comments

Leave a Comment