Subscrição - Classes internas

9 respostas
D

Opa =)

Porque ele nao compila (Unhandled Exception)? Pelo q eu entendi, ele executará os métodos da classe filha...

import java.io.IOException;

public class classe {

	static class A {
		void metodo() throws IOException {
			System.out.println("a");
			throw new IOException();
		}
	}

	static class B extends A {
		void metodo(){
			System.out.println("b");
		}
	}

	public static void main(String[] args) {
		A a = new B();
		a.metodo(); //Essa merda deveria invocar o método da classe B.. pq ele nao compila? FDP DE MERDA!
	}
}

Obrigado

9 Respostas

sergiotaborda

Não compila porque o java não deixa o programador cometer erros grosseiros.
Ao sobre-escrever um método a sua assinatura tem que ter exactamente as mesmas propriedades do método sobre-escrito.
Como o método original lança uma IOEXception o método novo tb tem que lançar.
Como não está lançando , o java está avisando-o que falta a exceção (Unhandled Exception).

D

Não tem a ver com isso, amigo…

O erro apresentado é UNHANDLED EXCEPTION…
A subscrição foi aceita e está longe de ser um erro grosseiro =)

T

Nao posso testar o código, mas não é preciso, vou responder pela lógica do seu código.

IOException herda de java.lang.Exception. A API do Java diz que toda exceção que herda de Exception, que não seja uma RuntimeException é do tipo checked. E diz ainda que toda checked exception deve capturar ou declarar que lança a exceção.

Você declarou que classe.A.metodo() lança uma IOExeption. Isto está correto, e diferente do que o sergiotaborda falou, o método que sobreescrever este método NÃO precisa ter uma assinatura exatamente igual, o que o método que sobreescrever nunca pode fazer é declarar novas checked exceptions.

Por exemplo, o código está correto:
static class A {   
        void metodo() throws java.io.IOException {   
            System.out.println("a");   
            throw new IOException();   
        }   
    }   
  
    static class B extends A {   
        void metodo() throws java.lang.StringIndexOutOfBoundsException
{   
            System.out.println("b");   
        }   
    }

O nosso metodo() sobreescreverá o metodo() da classe A num ambiente polimórfico e não há erro de compilação.

Voltando ao seu código, para resolver seu problema voce tem que lembrar que apesar da versão chamada pelo JVM ser classe.B.metodo(), a versão que o compilador vê é classe.A.metodo(), e como você declarou que LANÇA UMA CHECKED EXCEPTION no metodo() da classe.A então voce deve tratar está possibilidade com um bloco try {}catch().
Acredito que o seguinte código vai compilar a exibir b:

import java.io.IOException;   
  
public class classe {   
  
    static class A {   
        void metodo() throws IOException {   
            System.out.println("a");   
            throw new IOException();   
        }   
    }   
  
    static class B extends A {   
        void metodo(){   
            System.out.println("b");   
        }   
    }   
  
    public static void main(String[] args) {   
        A a = new B();   
       try{ 
         a.metodo(); //tratando checked exceptions que O COMPILADOR vê
       }catch(IOException ioe){System.err.println("Exceção jamais lançada em tempo de execução");}
    }   
}
D

Excelente! Mto obrigado pela explicação!

O mesmo ocorreria em classes externas!

[]'s

sergiotaborda

du123:
Não tem a ver com isso, amigo…

O erro apresentado é UNHANDLED EXCEPTION…
A subscrição foi aceita e está longe de ser um erro grosseiro =)

É , desculpa aí, foi mal. Eu vi tudo ao contrário. :oops:
Tudo, excepto o termo relativo a escrever o mesmo metodo em classes diferentes que é sobre-escrever. :roll:

o termo é override = escrever em/por cima = escrever sobre = sobre-escrever

O ifem é para criar uma palavra só como em ingles e com semelhança a subescrever, mas poderia escrever separado :wink:

tem o overload = carregar em/por cima = carregar sobre = sobrecarregar

D

Nao tenho certeza… mas pelo q eu sei, sobrecarregar o método (mesmo nome, mesma classe) é sobrescrever… reescrever na classe filha é subscrição…

Essa é a abordagem da K&B ao menos…

LPJava

bom vc ta chamando um metdo que lança uma excecao verificada entao deve declarar ou tratar a exceção.
Outro vc precisa encapsular a class Externa com a class interna… no caso de static nao precisa da instancia…

vc pode fazer isso:

new classe().A().metodo();

agora nao esqueça das regras de exceções… sempre quando tiver um codigo… olhe tudo que está nele e nao apenas a sua funcionalidade por exemplo… esse seu codigo ai é sobre classe interna…mas a regra de exceções… nesse caso deve ser lembrada…eheh o exame é cheio disso…95% das questoes é assim… dar ideia que a classe executa uma coisa… mais ele quer testar outra… boa questao para o exame… o cara olha e pensa que vai rodar… tudo certinho se nao se ligar nas regras de exceções!

flw!

sergiotaborda

du123:
Nao tenho certeza… mas pelo q eu sei, sobrecarregar o método (mesmo nome, mesma classe) é sobrescrever… reescrever na classe filha é subscrição…

Essa é a abordagem da K&B ao menos…

Tlv essa seja a abordagem do tradutor da K&B, porque em inglês existe uma distinção clara (override vs overload)
Não faz sentido que sobrecarregar seja o mesmo que sobre-escrever porque quando vc sobrecarrega vc não está redefinindo o codigo original, não está escrevendo por cima dele. Está escrevendo “ao lado”.
Mas como não conheço a tradução não posso dizer mais. Só sei que não usaria essas palavras como sinonimos.

Override = sobre-escrever = declarar métodos não estáticos com a mesma assinatura em classes diferentes.
Overload = sobrecarregar = declarar métodos não estáticos com nomes iguais e assinatura diferente na mesma classe ou hierarquia.
Redefinition = redefinição = declarar métodos estáticos com a mesma assinatura em classes diferentes.

LPJava

resumindo:

  • apenas os metodos(instancia) são herdados.
  • os metodos static sao redefinidos mais nao herdados, eles pertence a class e nao a instancia
  • variaveis nao sao herdadas
  • sobrecarga: dois metodos com mesmo nome no mesmo local porem com argumentos diferentes. se alterar apenas o tipo do metodo e manter o nome, isso nao é sobrecarga e o codigo nao complica(com exceção de retorno covariantes do java 5).

A regra geral é essa. Apesar da tradução está com pequenos… erros mas a segunda edição ta otima… em relação a edição K&B nao afeta nos estudos nao… ao contrario da ed.1.

Criado 14 de outubro de 2007
Ultima resposta 15 de out. de 2007
Respostas 9
Participantes 4