Subclasse não consegue acessar método da superclasse

36 respostas
S

Eu tenho a classe QuadradoDiferente que é subclasse da classe Quadrado e elas estão em pacotes diferentes.
Na classe Quadrado eu tenho um método que está com o modificador “protected”.
Ao tentar acessar esse método da QuadradoDiferente, a compilação falha.

Alguém poderia me explicar porque isso acontece? Já que QuadradoDiferente é subclasse de Quadrado.

Grata,

36 Respostas

rogelgarcia

Você pode acessar o membro herdado na própria instancia, mas não de uma instancia diferente.

Exemplo:

public class Quadrado {

    protected metodo(){}

}

public class QuadradoDiferente extends Quadrado {

     public metodo2(){
            super.metodo(); //ok
            metodo(); // ok
            Quadrado x = new Quadrado();
            x.metodo(); //erro
     }
}

Seria isso?

B

A classe Quadrado está com o modificador public?

S

rogelgarcia:
Você pode acessar o membro herdado na própria instancia, mas não de uma instancia diferente.

Exemplo:

public class Quadrado {

    protected metodo(){}

}

public class QuadradoDiferente extends Quadrado {

     public metodo2(){
            super.metodo(); //ok
            metodo(); // ok
            Quadrado x = new Quadrado();
            x.metodo(); //erro
     }
}

Seria isso?

Seria quase isso.

Na classe Quadrado eu tenho o método:

protected void mostra() {
		System.out.println("Imprime algo");
	}

Já na QuadradoDiferente eu tenho o método:

public void mosta() {
		System.out.println("A área é: ");
		super.mostra();
	}

Ou seja, nesse pedaço eu já faço que vc falou, certo?

Mas o problema na verdade está aqui:

public static void main(String args[]) {
		Quadrado quad = new Quadrado(1, 1, 1);
		quad.mostra();
	}

é no quad.mostra(); que tenho o erro.

Gostaria de saber porque isso acontece e o que poderia fazer para contornar isso.

S

A classe está como public.

E o método que quero acessar está como protected.

Alsberg

O modificador protected permite que você acesse de uma subclasse e/ou de uma classe do mesmo pacote.

PORÉM…

se você está em outro pacote, e o método é protected, você pode acessar o método protected SOMENTE ATRAVÉS DE HERANÇA, e não instanciando um objeto da classe

então ao invés de x.metodo();

faça super.metodo();

rogelgarcia

Então… o problema é o que mencionei mesmo… Você só pode acessar o método protected da própria instancia.

Para acessar outra instancia, deveria ser public a visibilidade.

Alsberg

na verdade se você nao sobrecarregou o metodo, nem precisa do super.metodo(). faça apenas metodo();

o super.metodo() seria somente em caso de voce ter sobrecarregado seu metodo na subclasse mas quisesse acessar a versao dele da superclasse

G

rogelgarcia:
Então… o problema é o que mencionei mesmo… Você só pode acessar o método protected da própria instancia.

Para acessar outra instancia, deveria ser public a visibilidade.

acho q os dois estão equivocados!

nel

Não se pode acessar um método com o modificador de acesso protected de um pacote diferente da super classe, mesmo que a classe que executa o acesso ao método seja filha, simples assim. Se quer que o método seja acessível a qualquer um, ele deve ser modificado para public, senão terá esse “limitador”.

Abraços.

G

mude:
Quadrado quad = new Quadrado(1, 1, 1);

para

QuadradoDiferente quad = new QuadradoDiferente(1, 1, 1);

G
nel:
Não se pode acessar um método com o modificador de acesso protected de um pacote diferente da super classe, mesmo que a classe que executa o acesso ao método seja filha, simples assim. Se quer que o método seja acessível a qualquer um, ele deve ser modificado para public, senão terá esse "limitador".

Abraços.

então isso aki não funcionaria?

package Pack1;

public class Quadrado {

	public Quadrado(int a, int b, int c) {
	}
	
	protected void mostra() {  
        System.out.println("Imprime algo");  
    }  
	
}
import Pack1.Quadrado;


public class QuadradoDiferente extends Quadrado {

	public QuadradoDiferente(int a, int b, int c) {
		super(a, b, c);
		// TODO Auto-generated constructor stub
	}

   public static void main(String args[]) {  
        QuadradoDiferente quad = new QuadradoDiferente(1, 1, 1);  
        quad.mostra();  // protected void mostra(). lembra?   
    } 	
}
nel

Altere o pacote de Pack1 para pack2 e veja se funciona. Querendo ou não, é o mesmo pacote, talvez eu tenha me expressado mal.
Tem de pertencer ao pacote em si, se começa com pack1, tem que ou estar ali ou para a frente, se for anterior ou diferente disso, não funciona.

G
nel:
Altere o pacote de Pack1 para pack2 e veja se funciona. Querendo ou não, é o mesmo pacote, talvez eu tenha me expressado mal. Tem de pertencer ao pacote em si, se começa com pack1, tem que ou estar ali ou para a frente, se for anterior ou diferente disso, não funciona.

e assim?

package Pack1;

public class Quadrado {

	public Quadrado(int a, int b, int c) {
	}
	
	protected void mostra() {  
        System.out.println("Imprime algo");  
    }  
	
}
package Pack2;
import Pack1.Quadrado;


public class QuadradoDiferente extends Quadrado {

	public QuadradoDiferente(int a, int b, int c) {
		super(a, b, c);
		// TODO Auto-generated constructor stub
	}

	public static void main(String args[]) {  
        QuadradoDiferente quad = new QuadradoDiferente(1, 1, 1);  
        quad.mostra();  
    } 	
}

melhor q conjecturar, é testar.

turim

Ao utiliza o modificador de acsso protected seus métodos somente são acessíveis por subclasses (mesmo sendo de outro pacote), ou classes do mesmo pacote.

Se você somente herdar, também não conseguirá acessar o método a partir de outro pacote, a não ser que subscreva o método e altere seu nível de acesso para public, o Java permite isso.

Você pode modificar o nível de acesso para mais visível.

No seu caso, se o método mostra é protected você nunca irá conseguir acessá-lo em outro pacote.

Aqui tem um artigo legal sobre isso.

Valeu.

Alsberg

publique as classes inteiras (incluindo os imports, claro) e poderemos ver onde é o erro exatamente

nel

Vou me redimir e corrigir algo muito importante. O método modificador protected aceita o acesso desde que o mesmo seja realizado a partir de uma classe filha, independente de pacote/projeto. O mesmo só é válido para o modificador default/friendly.

Foi um equívoco de minha parte. Responder as pressas faz com que falemos bobagem. Mas GilsonNunes, o ideal é simplesmente corrigir um erro de um colega do fórum, responder a dúvida de quem participou e não simplesmente provarmos teorias, essa pode ser facilmente tirada lendo a especificação Java, é claro. De qualquer forma, fico grato pela observação.

sula.fenix, pode ler aqui se quiser: http://docs.oracle.com/javase/specs/

Abraços a todos.

G

turim:
Ao utiliza o modificador de acsso protected seus métodos somente são acessíveis por subclasses (mesmo sendo de outro pacote), ou classes do mesmo pacote.

Se você somente herdar, também não conseguirá acessar o método a partir de outro pacote, a não ser que subscreva o método e altere seu nível de acesso para public, o Java permite isso.

Você pode modificar o nível de acesso para mais visível.

No seu caso, se o método mostra é protected você nunca irá conseguir acessá-lo em outro pacote.

Aqui tem um artigo legal sobre isso.

Valeu.

vc testou esse exemplo ai?

pô pessoal! é só testar.

turim

GilsonNunes

Sim, como o nel, disse é parte da especificação.

nel

sula.fenix, se fez toda a declaração corretamente, criando uma instancia da classe filha você poderá acessar normalmente o método pai, independente de pacote/projeto em que a classe filha esteja alocada (obviamente, fique atenta ao(s) import(s)).

Abraços.

turim

Só acrescentando, se você somente herdar a classe, uma instância da classe filha não conseguirá acessar o método protected herdado a partir de um pacote diferente.

A não ser que subscreva e tranforme ele em public.

G

turim:
GilsonNunes

Sim, como o nel, disse é parte da especificação.


e não rodou não?

olha a tabela do link q vc postou.

Access Levels
Modifier____Class Package Subclass World
public_______Y____Y________Y_____Y
protected____Y____Y________Y_____N
no modifier__ Y____Y________N_____N
private______Y____N________N_____N

ta vendo o subclass?

turim

o que eu disse está errado ?

viniciusalvess
package A;

public class ClasseA {

	protected void printProtected(){
		System.out.println("protected");
	}
	
	void printDefault(){
		System.out.println("Default");
	}
	
}
package B;

import A.ClasseA;

public class ClasseB extends ClasseA {

	public void testeComInstancia(ClasseB b){
		b.printProtected();
	}
	
	
	public void testeComThis(){
		this.printProtected();
	}
	
	
}

Mas eu fiz o teste aqui e acessou, pelo fato de que a subclasse acessa os membros com modificador protected da super classe atravéz de herança , independente se é o mesmo pacote ou não.

viniciusalvess

turim:
Só acrescentando, se você somente herdar a classe, uma instância da classe filha não conseguirá acessar o método protected herdado a partir de um pacote diferente.

A não ser que subscreva e tranforme ele em public.

protected consegue sim , o default não consegue em pacote diferente , teste o código que postei acima.

turim

Eu quiz dizer a nível de instância.

Se você criar uma instância da classe filha em outro pacote, não conseguirá acessar o método protected.

Como foi o caso da pessoa que criou esse tópico.

isso quad.mostra();, ela não irá conseguir fazer.

viniciusalvess

turim:
Eu quiz dizer a nível de instância.

Se você criar uma instância da classe filha em outro pacote, não conseguirá acessar o método protected.

Claro , nesse caso o modificador de acesso deveria ser public.

G

turim:
Eu quiz dizer a nível de instância.

Se você criar uma instância da classe filha em outro pacote, não conseguirá acessar o método protected.

Como foi o caso da pessoa que criou esse tópico.

isso quad.mostra();, ela não irá conseguir fazer.

o q vc quiz dizer com herdar aki então?

nel

turim:
Eu quiz dizer a nível de instância.

Se você criar uma instância da classe filha em outro pacote, não conseguirá acessar o método protected.

Como foi o caso da pessoa que criou esse tópico.

isso quad.mostra();, ela não irá conseguir fazer.

Consegue cara…é isso que estamos tentando dizer. Olha o código que o GilsonNunes postou.
O protected em comparação ao public possui uma diferença bem básica, a obrigatoriedade de que a classe que estará acessando o método (que é o caso em questão) protected seja uma classe filha, simples assim. Enquanto no public, não há necessidade de relação de herança.

turim

viniciusalvess:
turim:
Eu quiz dizer a nível de instância.

Se você criar uma instância da classe filha em outro pacote, não conseguirá acessar o método protected.

Claro , nesse caso o modificador de acesso deveria ser public.

Então, talvez eu não tenho sido claro, mas essa era a dúvida inicial, creio eu.

Da forma que foi colocado eu não conseguiria:

package C;  

public class Main {


	public static void main(String[] args) {
		ClasseB instancia = new ClasseB();
		
		instancia.printProtected();

	}

}

Teria um erro de compilação. Como o caso da sula.fenix.

nel

Não cara, não dá erro de compilação.

viniciusalvess

Dará erro sim , o post anterior do Turin.
Nesse caso o Turin está correto ! O que não é o caso inicial do tópico.

S

Obrigada galera.
Acho que entendi.

S

Nossa, não pensei que essa minha dúvida fosse gerar tantos comentários.
Mas vamos lá.
Eu não preciso fazer com que o código funcione, eu preciso explicar porque não funciona.
A pergunta do exercício é: Se QuadradoDiferente é subclasse de Quadrado, por que a compilação falha?

Segue o código:

package geometria;

	public class Quadrado {
	float a, b, c;
	
	public Quadrado () {
		
	}

	public Quadrado(float ax, float ay, float ar) {
		this.a = ax;
		this.b = ay;
		this.c = ar;
	}

	protected void mostra() {
		System.out.println("(" + this.a + "," + this.b + "," + this.c + ")");
	}

}
package geometria.borda;

import geometria.*;

public class QuadradoDiferente extends Quadrado {

	public void mostra() {
		System.out.println("A área é: ");
		super.mostra();
	}

	public static void main(String args[]) {
		Quadrado quad = new Quadrado(1, 1, 1);
		quad.mostra();
	}
}

Como o método mostra() na classe Quadrado está como protected, no main da QuadradoDiferente, ocorre erro na linha: quad.mostra();

nel

Dará erro sim , o post anterior do Turin.
Nesse caso o Turin está correto ! O que não é o caso inicial do tópico.

Dá erro porque está tentando acessar um método protected com a instância da própria classe Pai, só não havia ficado claro no código isso pra mim.
É o mesmo caso da sula.fenix, que instancia a própria classe Pai. Se fosse a instancia da classe filho, funcionaria perfeitamente.

S

Graças às respostas de vocês eu mandei a seguinte resposta para o meu exercício:

Como a classe está em outro pacote, e o método na classe Circulo é protected, só é possível acessar esse método através de herança, e não instanciando um objeto da classe.

E o professor considerou certa!

Valeu galera!

S

[Resolvido]

Criado 1 de março de 2012
Ultima resposta 16 de mar. de 2012
Respostas 36
Participantes 8