Boa noite a todos os amigos, neste meu primeiro post do ano volto aqui para pedir ajuda em uma questão que encontrei em um simulado:
class Master{
String doFileStuff() throws FileNotFoundException{
return "a";
}
}
public class Slave extends Master{
public static void main(String[] args) {
String s = null;
try{
s = new Slave().doFileStuff();
}catch(Exception x){
s = "b";
}
System.out.println(s);
}
//o que, inserido independentemente aqui, irá compilar e produzir a saída b
}
Eu marquei as opções A e D, a primeira porque não está lançando nenhuma exceção nova verificada e a segunda por estar lançando a mesma exceção, uma das que lança IOException eu não marquei por ser uma exceção mais genérica e o método não pode lançar e a outra porque não há sobrescrita, mas o teste diz que minha resposta está errada, vocês poderiam por favor me ajudar? Obrigado desde já, e feliz 2012 a todos.
Olá JakeFrog, cara, eu coloquei a pergunta como comentário no código, mas acredito já ter encontrado a resposta, NumberFormatException é uma exceção não verificada e portanto pode ser lançada pelo método que está sobrescrevendo, neste caso além das opções A e D, as opções E e F também compilam, fiz o que deveria ter feito antes de postar, fui olhar na documentação, só gostaria de me certificar se a minha conclusão está certa. valeu.
[quote=sidney.tavares]Boa noite a todos os amigos, neste meu primeiro post do ano volto aqui para pedir ajuda em uma questão que encontrei em um simulado:
class Master{
String doFileStuff() throws FileNotFoundException{
return "a";
}
}
public class Slave extends Master{
public static void main(String[] args) {
String s = null;
try{
s = new Slave().doFileStuff();
}catch(Exception x){
s = "b";
}
System.out.println(s);
}
//o que, inserido independentemente aqui, irá compilar e produzir a saída b
}
Eu marquei as opções A e D, a primeira porque não está lançando nenhuma exceção nova verificada e a segunda por estar lançando a mesma exceção, uma das que lança IOException eu não marquei por ser uma exceção mais genérica e o método não pode lançar e a outra porque não há sobrescrita, mas o teste diz que minha resposta está errada, vocês poderiam por favor me ajudar? Obrigado desde já, e feliz 2012 a todos.[/quote]
Override é quando você usa a mesma assinatura de um método, mas varia a sua implementação. Assim, se você deseja fazer um override, não pode haver outras exception além das declaradas pelo método pai.
Bem, a letra A define um novo método, por causa da falta da FileNotFoundException. As letras B, D, E e F seguem o mesmo raciocínio. A única que muda é a letra C, pois você chama na main new Slave().doFileStuff(), sem passar qualquer parâmetro para o objeto. Assim, será chamado o método original, que foi herdado pela classe filha.
Quando fazer uma sobrescrita de um método que sinaliza uma exceção você deve lembrar:
[list]Pode lançar as mesmas checked exceptions que foi declarada no método original.[/list]
[list]Pode lançar uma parte dessas exceções.[/list]
[list]Pode lançar subclasses da exceção sinalizada.[/list]
[list]Pode lançar qualquer runtime exceptions.[/list]
[quote=joaoluizjoaquim]As respostas certas são:
A
D
E
F
Explicação:
Quando fazer uma sobrescrita de um método que sinaliza uma exceção você deve lembrar:
[list]Pode lançar as mesmas checked exceptions que foi declarada no método original.[/list]
[list]Pode lançar uma parte dessas exceções.[/list]
[list]Pode lançar subclasses da exceção sinalizada.[/list]
[list]Pode lançar qualquer runtime exceptions.[/list][/quote]
A letra B esta incorreta porque o método sobrescrito não pode lançar uma exceção verificada nova ou mais abrangente do que o metodo original, neste caso IOException seria a exceção mais abrangente e deveria ter sido lancada na classe Master, acho que pra simplificar fica assim: FileNotFoundException e filha de IOException.
A letra B esta incorreta porque o método sobrescrito não pode lançar uma exceção verificada nova ou mais abrangente do que o metodo original, neste caso IOException seria a exceção mais abrangente e deveria ter sido lancada na classe Master, acho que pra simplificar fica assim: FileNotFoundException e filha de IOException.[/quote]
Esqueci que uma FileNotFoundException é derivada de uma IOException…
Uma correção…o que está acontecendo com a letra B é um overload seguida de um override…o override ocorre por que o método tem o mesmo tipo de retorno e parâmetro (nenhum, no caso), enquanto que o overload ocorre quando uma nova exceção é assinada no método. Nesse caso, o overload sobrescreveu o método da classe pai.
Override é sobrescrever. Overload é sobrecarregar.
Cara, acho que você ta errado, se fosse sobrecarga compilaria, nao compila exatamente por ser sobrescrita, ou override,o que define a assinatura do método seria a lista de argumentos, e neste caso essa lista não foi alterada, ou seja, o método não tem argumentos. Para ser sobrecarregado ele deveria estar declarado assim:
Cara, acho que você ta errado, se fosse sobrecarga compilaria, nao compila exatamente por ser sobrescrita, ou override,o que define a assinatura do método seria a lista de argumentos, e neste caso essa lista não foi alterada, ou seja, o método não tem argumentos. Para ser sobrecarregado ele deveria estar declarado assim:
O método foi sobrescrito. Disse errado!
Um método é sobrecarregado quando somente o seu parâmetro muda, em quantidade, ordem ou tipo. O tipo de retorno nem entra.
Eu quis comprovar fazendo o seguinte. Pode-se notar que um objeto Slave recebe uma instância da classe Slave. Assim, primeiramente eu verifica se o método chamado se encontra em seu contexto (abrangendo os métodos herdados). Se eu criasse um objeto Master apontando para uma instância da classe Slave e depois invocasse o método doFileStuff(), primeiramente seria verificado se o método existe em Master para depois verificar se o mesmo foi override em Slave. Se fossem métodos diferentes e não o mesmo sobrescrito, ele invocaria o método da classe Master e depois iria ver que não existiria o mesmo sobrescrito em Slave e imprimiria “a”. Mas isso não ocorreu. Ele imprimiu “b” da classe filha, contantando que realmente uma mudança de exceção somente não faz o método mudar.
Eu só não sei o porquê de não ter aceitado uma exceção mais abrangente que a primeira. Você sabe o motivo?
Bem, o motivo está na hierarquia, como IOException está acima de FileNotFoundExcepetion, a regra para sobrescrita de métodos diz que o método que sobrescreve não pode lançar uma exceção mais abrangente do que o método original, se isso acontecer o código não compila, não é que o método em si muda, mas uma regra da linguagem está sendo quebrada, esse assunto, sobrescrita e sobrecarga confunde mesmo, mas para essa questão em específico o que está sendo testado é se conhecemos as regras de sobrescrição e no caso da opção B esta regra está sendo quebrada, não sei se consegui me fazer entender, mas se ainda tiver dúvida estamos aí, abraço.
Bem, o motivo está na hierarquia, como IOException está acima de FileNotFoundExcepetion, a regra para sobrescrita de métodos diz que o método que sobrescreve não pode lançar uma exceção mais abrangente do que o método original, se isso acontecer o código não compila, não é que o método em si muda, mas uma regra da linguagem está sendo quebrada, esse assunto, sobrescrita e sobrecarga confunde mesmo, mas para essa questão em específico o que está sendo testado é se conhecemos as regras de sobrescrição e no caso da opção B esta regra está sendo quebrada, não sei se consegui me fazer entender, mas se ainda tiver dúvida estamos aí, abraço.[/quote]
simplificando, é uma regra sobre exceções, metodo sobrescrito não pode lançar exceção de tipo mais generico que o metodo de origem.