herança

Galera minha dúvida eu acho que é bem simples, por exemplo:

class Pessoa{

    Pessoa(){
        System.out.println(getValue());

    }

    public int getValue(){

        return -1;
    }

}


public class Funcionario extends Pessoa{
    
     public int getValue(){

        return 2;
     }
    public static void main (String [] args){

        Funcionario func=new Funcionario();

    }


}

por que a saída gerada será 2 e não -1?

Porque você alterou o compartamento do método que foi herdada da superclasse…

Quando você herda classes, herda todos os comportamentos(métodos) da mesma, mas pode alterar para refinar o comportamento…

Se você tivesse apenas feito o extends, instanciado o Funcionario e chamado o método, iria ter a saída -1. Como você alterou o método na sua subclasse, a saída será conforme a sua alteração…

[quote=Ruttmann]Porque você alterou o compartamento do método que foi herdada da superclasse…

Quando você herda classes, herda todos os comportamentos(métodos) da mesma, mas pode alterar para refinar o comportamento…

Se você tivesse apenas feito o extends, instanciado o Funcionario e chamado o método, iria ter a saída -1. Como você alterou o método na sua subclasse, a saída será conforme a sua alteração…

[/quote]

mas no caso quando eu instancio a classe Funcionario o construtor dele implicitamente chama o construtor da superclasse, e dentro do construtor da superclasse é que ocorre o chamada do metodo getValue().

Mas você sobrescreveu o método getValue() na classe Funcionário.

class Pessoa{  
  
    char sexo='m';    

    Pessoa(){  
        System.out.println(getValue()); 
        System.out.println(sexo); 
  
    }  
  
    public int getValue(){  
  
        return -1;  
    }  
  
}  
  
  
public class Funcionario extends Pessoa{  
  
     char sexo='f'
      
     public int getValue(){  
  
        return 2;  
     }  
    public static void main (String [] args){  
  
        Funcionario func=new Funcionario();  
  
    }  
  
  
}  

Adicionei o atributo sexo nas duas classes, sei que é errado fazer isso, duplicação de código totalmente desnecessária, porém foi só a título de exemplo.
No caso a saída gerada será:
2
m
Por que então a saída não foi:
2
f

Porque a classe funcionário que herda de pessoa e não o contrário, logo quando você altera o comportamento do método da classe funcionário, essa alteração só servirá para ela e subsequentemente para seus filhos, mas o getValue de pessoa continuará sendo igual visto que ele é a classe Pai. Esse é um dos princípios de herança você tem uma classe Pai que tem um método X, que soma 1+1 , dai você cria uma classe filha que tem o mesmo método X porém ele soma 1+2, logo você utiliza um método mais genérico da classe Pai, e especializa para suas classes filhas, entendeu?

[quote=dntalemao][code]
class Pessoa{

char sexo='m';    

Pessoa(){  
    System.out.println(getValue()); 
    System.out.println(sexo); 

}  

public int getValue(){  

    return -1;  
}  

}

public class Funcionario extends Pessoa{

 char sexo='f'
  
 public int getValue(){  

    return 2;  
 }  
public static void main (String [] args){  

    Funcionario func=new Funcionario();  

}  

}
[/code]

Adicionei o atributo sexo nas duas classes, sei que é errado fazer isso, duplicação de código totalmente desnecessária, porém foi só a título de exemplo.
No caso a saída gerada será:
2
m
Por que então a saída não foi:
2
f
[/quote]

Os métodos são sobrepostos nas subclasses, porém as variáveis são sombreadas (ou ocultas). A diferença entre os dois comportamentos é q na sobreposição o q importa para qual método será executado é o tipo do objeto, enquanto q no sombreamento é usado o tipo da referência. No seu exemplo é executado o método da subclasse pois o tipo do objeto é funcionário, e é usada a variável da superclasse pq a classe Pessoa não enxerga a variável q está sendo sombreada na subclasse (não ocorre polimorfismo). Mudando um pouco o código:

Pessoa func = new Funcionario();
System.out.println(func.getValue()); // imprime 2 (pois o objeto é do tipo Funcionario)
System.out.println(func.sexo);      // imprime m (pois a referência é do tipo Pessoa)

[quote=Andersonrms][quote=dntalemao][code]
class Pessoa{

char sexo='m';    

Pessoa(){  
    System.out.println(getValue()); 
    System.out.println(sexo); 

}  

public int getValue(){  

    return -1;  
}  

}

public class Funcionario extends Pessoa{

 char sexo='f'
  
 public int getValue(){  

    return 2;  
 }  
public static void main (String [] args){  

    Funcionario func=new Funcionario();  

}  

}
[/code]

Adicionei o atributo sexo nas duas classes, sei que é errado fazer isso, duplicação de código totalmente desnecessária, porém foi só a título de exemplo.
No caso a saída gerada será:
2
m
Por que então a saída não foi:
2
f
[/quote]

Os métodos são sobrepostos nas subclasses, porém as variáveis são sombreadas (ou ocultas). A diferença entre os dois comportamentos é q na sobreposição o q importa para qual método será executado é o tipo do objeto, enquanto q no sombreamento é usado o tipo da referência. No seu exemplo é executado o método da subclasse pois o tipo do objeto é funcionário, e é usada a variável da superclasse pq a classe Pessoa não enxerga a variável q está sendo sombreada na subclasse (não ocorre polimorfismo). Mudando um pouco o código:

Pessoa func = new Funcionario(); System.out.println(func.getValue()); // imprime 2 (pois o objeto é do tipo Funcionario) System.out.println(func.sexo); // imprime m (pois a referência é do tipo Pessoa) [/quote]

essa era exatamente minha dúvida, obrigado!
valeu ae pessoal.