Dúvida sobre herança e reescrita de atributo

14 respostas
danielbussade
public class Principal {   
  public static void main ( String args[] ) {   
    Classe2 n = new Classe2();   
    System.out.println(n.getN1());   
  
  }   
}   
  
class Classe1 {   
  protected int num1=1;   
  
  public int getNum1() {   
    return num1;   
  }   
}   
  
class Classe2 extends Classe1 {   
  protected int num1=2;   
}

Alguém pode explicar porque este código retorna 1, e não 2 que seria o correto. Eu não reescrevi o método mas resscrevi o atributo!! Então quando herdei de Classe1 o metodo getNum1 não foi pra “dentro da classe2”, então porque ele não retornou 2??

Alguém pode me esclarecer?

Obrigado!

14 Respostas

ViniGodoy

Porque não existe reescrita de atributo. O que acontece é que você agora tem 2 atributos, em dois escopos diferentes, sendo que o inferior apenas esconde o superior (mas não o substitui).

Entretanto, o seu método não foi sobrescrito e continuará vendo a propriedade do atributo original.

Via de regra, não faça isso. Como você mesmo notou, gera um código confuso.

Marcio_Nogueira

Para sobreescrever métodos algumas regras devem ser observadas:
A assinatura (parâmetros) devem ser do mesmo tipo.
O modificador de acesso não pode ser mais restritivo que o do método a ser sobreescrito.
O tipo de retorno deve ser o mesmo.

S

Sua classe 2 é:

Classe2 extends Classe1 { protected int num1=2; public int getNum1() { return super.getNum1(); } }

Pra retornar o num1 de Classe2, troque o corpo do método por return num1;

danielbussade

Classe2 extends Classe1 { protected int num1=2; public int getNum1() { return super.getNum1(); } }

Agora sim entendi, quando herdo um método e não reescrevo ele executa tudo da mãe, mesmo se eu tiver um atributo com o mesmo nome e do mesmo tipo!!

Valeu obrigado a todos tiraram uma dúvida e tanto!!

Attt

LPJava

cuidado para vc nao se confudir… apenas os metodos sao herdados… as variaveis nao… se a subclasse nao subscrever o metodo sempre vai executar o da class Pai(super). Lembra da regra tudo que o pai faz o filho tb faz.

CarlosEduardoDantas

só pra frisar… apenas os métodos são subscritos, variáveis não… tanto métodos quanto variáveis são herdados…

danielbussade

Só pra finalizar, então quando herdo de uma classe os metodos e variáveis d a classe mãe não vão para “dentro” da classe filha, simplesmente só me dá uma maneira de acessar os métodos.
Ex:

classe Pai {
    protected String nome;
    public String metodoA(){
        return nome;
   
    }
    
}

//É como se minha classe Filha estivesse assim
classe Filho extends Pai {
   // Não existe o atributo nome???
   public String metodoA() { 
     return super.metodoA;
   }  
}

Tudo que eu fizer nesta classe com o atributo nome, estou mexendo então na classe Mãe, correto???

Att

LPJava

só pra frisar… apenas os métodos são subscritos, variáveis não… tanto métodos quanto variáveis são herdados…
a questão é que a subclasse pode acessar a variavei da superclasse… essa questao de herdar variaveis… nao é uma boa principalmente para scjp pq ela tenta confudir… olha uma questao da certificacao

class A{
int x=10;
}
class B extends A{
int x =20;
}

ai lembro que tinha as opções:

  • nao compila
  • altera o valor das variaveis X tanto da classe A e da B.
  • Compila e executa normalmente.

entao nesse caso se vc mandar imprimir X na classe B ele imprime 20, se usar o super ele vai imprimir da superclasse, com o valor 10.
Isso é um detalhe… apenas… que tem a respeito de variaveis.

CarlosEduardoDantas

sim sim… apenas corrigi pq vc trocou as palavras qdo disse que variaveis não sao herdadas… no seu codigo, se chamar super.x na subclasse, imprime 10, logo, x é herdado mesmo tendo criado um atributo com o mesmo nome na subclasse.

danielbussade

Vou aproveita o tópico pra tirar mais uma dúida sobre herança:
Olhem este código:

public class Pai {
	protected String nome;
	
	public Pai() {
		System.out.println("Criei um pai.");
	           }
	
	public String getNome(){
		return nome;
	}
}

public class Filho extends Pai {
	
	public Filho() {
		System.out.println("Criei um filho");

		}

}

public class Principal {
	public static void main(String[] args) {
		Filho f1= new Filho ();
		
	}

}

A saída é:
Criei um pai
Criei um filho.

Eu sei que o compilador coloca automaticamente o construtor da classe mãe dentro do construtor da classe filha era como se minha classe filha estivesse assim:

public class Filho extends Pai {
	
	public Filho() {
                                super();   //chama o construtor do pai
		System.out.println("Criei um filho");

		}

}

Agora ai eu me pergunto, se na classe pai então ela támbém coloca o construtor default da classe Object, ou seja então cada vez que crio um objeto filho, na verdade criei três objetos, Filho, Pai, e Object???

Será que pode me esclarecer melhor??

Obrigado!!

danielbussade

sim sim… apenas corrigi pq vc trocou as palavras qdo disse que variaveis não sao herdadas… no seu codigo, se chamar super.x na subclasse, imprime 10, logo, x é herdado mesmo tendo criado um atributo com o mesmo nome na subclasse.

Será que pode me explicar melhor, como você mesmo disse se u chamar x puro na classe filha ele imprime 10, isto significa que o x está “dentro” da classe filha ou é só um modo de abreviar na verdada chamada que está acontecendo é super.x.
Pode me esclarecer!!

Obrigado

LPJava

só pra frisar… apenas os métodos são subscritos, variáveis não… tanto métodos quanto variáveis são herdados…

a questão é que a subclasse pode acessar a variavei da superclasse… essa questao de herdar variaveis… nao é uma boa principalmente para scjp pq ela tenta confudir… olha uma questao da certificacao

class A{
int x=10;
}
class B extends A{
int x =20;
}

ai lembro que tinha as opções:

  • nao compila
  • altera o valor das variaveis X tanto da classe A e da B.
  • Compila e executa normalmente.

entao nesse caso se vc mandar imprimir X na classe B ele imprime 20, se usar o super ele vai imprimir da superclasse, com o valor 10.
Isso é um detalhe… apenas… que tem a respeito de variaveis.

danielbussade

Olha só vou dar um exemplo :

public class Pai {
	protected String nome;
	
	public Pai() {
		System.out.println("Criei um pai.");
	}
	
	public String getNome(){
		return nome;
	}

}
//Esse seria o desenho da SubClasse

public class Filho extends Pai {
      super.nome      //O atributo não está aqui está na classe mãe 
                             //tudo que eu mexer com ele na verdade estou mexendo no objeto pai
	
	public Filho() {
		System.out.println("Criei um filho");
	         }
	
	public String getNome() {
		return super.nome;
	}
	

}

//Ou seria assim

public class Filho extends Pai {
     protected String nome//O atributo pertence a esta classe 
                                       //tudo que eu mexer com ele nao influencia na classe pai
	
	public Filho() {
		System.out.println("Criei um filho");
	         }
	
	public String getNome() {
		return super.nome;
	}
	

}

Alguém pode me explicar??

Obrigado!!

LPJava

hum… so nao é acessado… nesse caso… é nao sabia q ele herdado. .acha que so no caso de a subclasse nao ter uma variavel do mesmo tipo e o mesmo nome… vivendo e apredendo :smiley:

Criado 28 de outubro de 2007
Ultima resposta 29 de out. de 2007
Respostas 14
Participantes 6