Duvidas com Exceptions, e Polimorfismo

14 respostas
danielbussade

Olá a todos no Forum, achei estas duas questões no site da Caelum, e gostaria que você me ajudassem a tirar estas dúvidas;

Questão 1:
Pq este programa não roda?

class Acao {
  public void executa() {
  	System.out.println("Executando a ação");
  }
}
class ExecutaVenda extends Acao {
  public void executa() {
  	vende();
  }
  public void vende() {
  	System.out.println("Vendendo");
  }
}
class Programa {
  public static void main(String[] args) {
  	Acao acao = new ExecutaVenda();
  	acao.vende();
  }
}

Questão2:
As exceptions que sempre somos obrigados a colocar um try/catch ou declará-la no throws são:

A)filhas de CheckedException
B)filhas de RuntimeException
C)filhas de Exception
D)filhas de Exception desde que não sejam filhas de RuntimeException
E)filhas de Throwable
F)filhas de Error desde que não sejam filhas de RuntimeException
G) todas

Eu marquei letra C, mas a correta era letra D, ai surgiu a dúvida. Como uma exception, pode ser filha de duas classes ao mesmo tempo? sendo que o Java não aceita Herança Múltipla, e mais as duas Classes RuntimeException e Exception não são filhas de Throwable, se alguem puder explicar melhor, porque fiquei totalmente confuso.

Att

14 Respostas

Ataxexe

Para a questão 1, tente compilar o programa e ver o que acontece.

Na questão 2, não é que exista herança múltipla. Se você olhar na documentação da classe RuntimeException, verá que ela é filha de Exception, verá, também, que ambas são filhas de Throwable.

Isso significa que você é obrigado a declarar em um throws ou em um catch toda e qualquer exceção que não seja filha, direta ou indiretamente, de uma RuntimeException.

Por exemplo: você deverá, obrigatoriamente, declarar uma exceção do tipo IOException, mas não será necessário declarar uma exceção do tipo NullPointerException.

Espero ter ajudado.

Um abraço!

Foxlol

Na questão 1 vc está declarando uma variável de referência do tipo Acao.
A classe Acao não possui um método vende. Mesmo que esta variável esteja apontando para um objeto ExecutaVenda que o tem, vc não tem como acessá-lo. Por isso o erro.

Quanto a questão 2, não existe herança múltipla. O fato é que Exception é superclasse de RuntimeException, porém existem outras subclasses de Exception que não são necessariamente filhas de RuntimeException. As chamadas Checked Exceptions.

E sim, Exception e RuntimeException são filhas de Throwable:
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/RuntimeException.html

danielbussade

Obrigado aos dois. Só para ficar mais claro, quando declaro uma referência não importa em que classe eu der New os metodos que conseguirei acessar, é somente os que tiver na classe da qual eu declarei a referência é isso?
Outra coisa então se eu jogo no throw, uma exception do tipo RuntimeException, e ela é filha de exception, herda as características dela,eu tbm teria que tratar ela com try e catch, acontece que não preciso tratar.
E quanto eu declaro no throw, uma exception da Exception, eu so obrigado a tratar, poderia me explicar melhor isto?

Att

Ataxexe

Para a primeira

Exatamente, o java não se preocupa com o tipo “real” da variável, no exemplo abaixo:

Acao acao = new ExecutaVenda();

O tipo da variável é Acao, portanto, você pode colocar qualquer classe filha dela nessa variável, mas somente os atributos e métodos da classe Acao poderão ser utilizados. Isso é uma bênção! Você pode fazer um método que receba uma variável do tipo List e não se preocupar qual é o tipo real dessa variável (um ArrayList, uma LinkedList ou uma outra qualquer que implemente a interface List).

Quanto à segunda

É exatamente o que a gente explicou antes, a exceção RuntimeException, por ser filha de Throwable, pode ser declarada em uma cláusula throws, mas não é obrigada a ser capturada em um try/catch.

danielbussade

Obrigado, agora eu entendi. Eu so posso jogar no Throws as classes que são filhas direta ou indiretamente de Throwable.
Por isso que quanto jogo Exception, ele me obriga a tratar pq pode ser qualquer uma das classes filhas de Exception, entao eu tenho que tratar, mas se eu disser que ela é do tipo RuntimeException, mesmo RuntimeException sendo filha de Exception eu não preciso tratar, no caso classes com NullPointerException etc…

Valeu mesmo, tirou uma dúvida e tanto!

Att

LPJava

pensa assim… o que nao extends a RuntimeException é uma exceção verificada… e tenho que tratar ou declarar… fica mais facil… que vc ficar tentando descobrir no especifico… entao se extends a RuntimeExceptio - nao verificada os demais é do tipo verificada :smiley:

sergiotaborda

Realmente a pergunta está mal formulada. A resposta certa seria: “Descendentes de Throwable que não sejam descendentes de RuntimeException”. Mas de entre as hipoteses dadas, D é realmente a mais perto da verdade.

A classe pode ser filha de duas classes ao mesmo tempo no sentido que se C é filha de B e B é filha de A, então C é filha de A.
A palavra “descendente” deve ser usa em vez de filha, porque além de ser tecnicamente mais correto, não causa esse tipo de confusão.

danielbussade
É verdade pensar deste jeito é mais prático. O que ta me confundindo é o seguinte, se a classe

RuntimeException é filha de Exception, ela herda todos seus atributos, e métodos públicos e protegidos, então o que diferencia a classe RuntimeException, da Exception, sendo que uma eu trato com try e catch e a outra não??

Mas se eu pensar assim, o que não for filha de RuntimeException eu trato, realmente é bem mais prático, além de não gerar confusão.

Valeu!

Att

peczenyj

Ela não é.

RuntimeException está no ‘mesmo nível’ que Exception, ambas são filhas de Throwable.

danielbussade

Posso até estar enganado,mas olha só na documentação das API’s do java mostra que RuntimeException é filha de Exception, diretamente e de Throwable indiretamente.

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html

Att

Foxlol

Ela não é.

RuntimeException está no ‘mesmo nível’ que Exception, ambas são filhas de Throwable.

java.lang.Object
  extended byjava.lang.Throwable
      extended byjava.lang.Exception
          extended byjava.lang.RuntimeException
peczenyj

Ah chupei bala, confundi com Error :oops:

Sobre as exceptions indico este excelente artigo (são 3 partes)

LPJava

Ela não é.

RuntimeException está no ‘mesmo nível’ que Exception, ambas são filhas de Throwable.

não… ela nao está no mesmo nivel nao… ela é filha sim de exception porem é um tipo nao verificada…
olha o desenho em anexo como é visualizado pela JVM.


sergiotaborda

danielbussade:
É verdade pensar deste jeito é mais prático. O que ta me confundindo é o seguinte, se a classe
RuntimeException é filha de Exception, ela herda todos seus atributos, e métodos públicos e protegidos, então o que diferencia a classe RuntimeException, da Exception, sendo que uma eu trato com try e catch e a outra não??

O que distingue uma da outra é a propria classe. É como vc perguntar o que distingue Cliente de ClienteEspecial.
É como se a JVM fizesse um “intanceof” das classes das exceções e obrigasse a ser cheked ou não conforme.

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