Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas

Introdução às Classes Abstratas, Interfaces e Exceções em Java, Notas de estudo de Informática

Neste documento, aprenda sobre classes abstratas, interfaces e exceções em java. Saiba como solucionar problemas de herança, implementar interfaces e lidar com diferentes tipos de exceções. Encontre exemplos práticos e compreenda como essas conceitos ajudam a escrever código mais limpo e legível.

Tipologia: Notas de estudo

2011

Compartilhado em 09/03/2011

lau-s-5
lau-s-5 🇧🇷

11 documentos

1 / 21

Documentos relacionados


Pré-visualização parcial do texto

Baixe Introdução às Classes Abstratas, Interfaces e Exceções em Java e outras Notas de estudo em PDF para Informática, somente na Docsity! lavá Starter WAVAV:LZ LIFGOM www .t2ti.com lavá Starter WAVAV:LZ LIFGOM www .t2ti.com Curso Java Starter classe Object sempre é invocado, pois todas as classes estendem dela. Observe o código abaixo referente a classe Veiculo: public class Veiculo { private String marca; private Double capacidadeTanqueCombustivel; public Veiculo(String marca) { this.marca = marca; } //Demais membros... Quando o compilador gerar o bytecode o que nós teremos é o seguinte: public class Veiculo { private String marca; private Double capacidadeTanqueCombustivel; public Veiculo(String marca) { super(); this.marca = marca; } //Demais membros... Observe que a declaração super() indica que o construtor default – construtor public e sem parâmetros – da superclasse está sendo invocado. Isto acontece de forma automática, nós não precisamos nos preocupar. O construtor default é adicionado pelo compilador quando não há construtor declarado explicitamente, isto é, se o programador não declarar um construtor o compilador irá adicionar, implicitamente, um público e sem parâmetros. No entanto se for adicionado explicitamente um construtor o compilador não irá adicionar implicitamente o construtor default, o que significa que se nós criarmos um construtor com parâmetros e estendermos a classe, obrigatoriamente teremos que, explicitamente, invocar o construtor da superclasse passando os parâmetros. Para ficar mais claro vamos estender a classe Veiculo que possui um construtor com parâmetros: public class Jipe extends Veiculo{ public Jipe() { } //Demais membros... O código acima demonstrado não compila. Imagine o compilador tentando www.t2ti.com 5 ! Curso Java Starter adicionar a declaração super() porém sem sucesso. Isto acontece pois não existe construtor sem parâmetros na superclasse, existe apenas um construtor com o parâmetro marca do tipo String. Podemos solucionar o problema apresentado de diversas maneiras, a primeira seria invocando o construtor da superclasse e encaminhando um parâmetro padrão para todas as instâncias da classe Jipe: public class Jipe extends Veiculo{ public Jipe() { super("Marca padrão de jipe"); } //Demais membros... Perceba que no construtor da classe Jipe estamos invocando o construtor da classe Veiculo e passando uma String ("Marca padrão de jipe"), ou seja, todas as instâncias desta classe Jipe possuirão a mesma marca. Outra solução seria a implementação de um construtor na classe Jipe que receba o mesmo parâmetro repassando-o para a superclasse: public class Jipe extends Veiculo{ public Jipe(String marca) { super(marca); } //Demais membros... Desta forma é mantida a lógica implementada pela superclasse. E por fim, uma terceira abordagem seria a mais de um construtor, observe que neste caso os dois construtores desenvolvidos anteriormente foram mantidos: public class Jipe extends Veiculo{ private String modelo; public Jipe(){ super("Marca padrão de jipe"); } public Jipe(String marca) { super(marca); } public Jipe(String marca, String modelo) { super(marca); this.modelo = modelo; } //Demais membros... Observe que, neste último caso, temos um construtor sem parâmetros, um www.t2ti.com 6 Construtor sem parâmetro Invocação do construtor da superclasse Construtor com parâmetro Invocação do construtor da superclasse com repasse do parâmetro recebido Construtor novo com dois parâmetros Curso Java Starter construtor que recebe o mesmo parâmetro da superclasse e outro que recebe dois parâmetros (marca e modelo), ou seja, poderíamos ter N-construtores, um para cada situação. Classes Abstratas Até este momento todas as classes que havíamos desenvolvido eram classes concretas, isto é todas as nossas classes podem originar objetos. Classes concretas são estruturas definidas e prontas para instanciarem objetos. Uma classe abstrata se comporta de forma diferente de uma classe concreta. Uma classe abstrata nunca pode ser instanciada de forma direta, seu maior propósito, a razão da sua existência, é ser estendida. Para que serve esta classe então? Imagine a seguinte situação, nós temos uma hierarquia de classe conforme abaixo: Todos os animais (cachorro, cavalo e preguiça) estendem da classe Animal, no entanto, no nosso, programa a classe Animal por si só não representa nenhum tipo de animal. Isto é, esta classe representa apenas um animal genérico e ela existe apenas para ser estendida dando origem a um animal de fato. Nesta situação é mais adeqüado que seja feita a mudança na classe Animal a fim de torná-la abstrata e inviabilizar a sua instanciação por qualquer parte do programa. Isto é realizado adicionando-se o modificador abstract conforme abaixo: public abstract class Animal { //corpo da classe } Observe que agora a classe Animal não pode ser instanciada indevidamente em nenhum trecho do nosso programa, o exemplo abaixo irá produzir um erro de www.t2ti.com 7 Curso Java Starter tipo e nós devemos utilizar interfaces quando existem determinados comportamentos que sejam similares entre hierarquias de classes diferentes. Veja o método emitirSom() da classe abstrata Animal, agora suponha que no mesmo programa eu tenha uma classe Bola, que por sinal também emite som. Em um determinado momento do programa eu desejo invocar o método emitirSom para alguns objetos conforme a situação abaixo: public void limpar(Object obj) { //Código para limpar uma bola ou um animal... if(obj instanceof Bola) { ((Bola)obj).emitirSom(); } else if(obj instanceof Animal) { ((Animal)obj).emitirSom(); } } Neste programa nós temos um método que efetua a limpeza de qualquer objeto, seja ele um animal ou uma bola, porém caso o objeto seja de um dos dois tipos, Bola ou Animal, estes deverão emitir seus sons característicos. Esta situação não pode ser resolvida através do uso de herança já que a classe Bola e a classe Animal não estão na mesma hierarquia de classes – na verdade até poderia ser resolvida com herança e sobreescrita, mas havemos de convir que colocar a classe Bola e a classe Animal na mesma hierarquia é um erro de projeto – logo, a solução seria a criação da interface EmiteSom conforme abaixo: public abstract interface EmiteSom { public abstract void emitirSom(); } Observe que o uso do abstract é opcional tanto na classe quanto no método pois toda interface é obrigatoriamente abstrata e seus métodos também o são. A classe Animal e a classe Bola ficariam da seguinte forma: public class Bola implements EmiteSom{ public void emitirSom() { System.out.println("Boing, boing..."); } } www.t2ti.com 10 Implementação do método abstrato Curso Java Starter public abstract class Animal implements EmiteSom{ private String nome; //getters e setters... } Perceba o uso da palavra reservada implements que informa ao compilador que esta classe está implementando uma interface. A classe Animal não fornece uma implementação para o método emitirSom(), ao contrário da classe Bola, isto acontece porque a classe Animal é do tipo abstract. Quando uma classe abstrata implementa uma interface ela pode ou não fornecer a implementação dos métodos oriundos da interface. Caso a classe abstrata não forneça a implementação destes métodos (situação existente na classe Animal), obrigatoriamente cada subclasse concreta da classe abstrata irá ter que fornecer a implementação. Por exemplo, a classe Cachorro fica da seguinte forma: public class Cachorro extends Animal { public void emitirSom() { System.out.println("au! au!"); } } Então, podemos interpretar a situação da seguinte forma: “A classe Animal implementa a interface EmiteSom, mas deixou a responsabilidade pela implementação do método para a classe concreta Cachorro”. E agora o nosso mesmo método limpar() utilizando a interface: public void limpar(Object obj) { //Código para limpar uma bola ou um animal... if(obj instanceof EmiteSom) { ((EmiteSom)obj).emitirSom(); } } Perceba que independente do tipo de objeto que vier como parâmetro, desde que ele seja do tipo EmiteSom, eu sei que irá possuir a implementação do método emitirSom() e que portanto o código será executado sem problemas, isto também nos permite acabar com aquelas cadeias indesejáveis de if's deixando o código mais legível. www.t2ti.com 11 Cadê a implementação? Implementação do método Curso Java Starter Exceções Até agora nós criamos pequenos programas sem nos preocuparmos em tratar possíveis erros. No entanto todos aqueles que programam há algum tempo sabem que o tratamento de erros (exceções) é parte fundamental da programação. Vamos começar os nossos estudos conhecendo a forma como uma exceção é apresentada e o seu significado, observe as duas classes abaixo: public class modulo10Main { public static void main(String[] args) { new RecebeArray(args); System.out.println("Término do programa!"); } } public class RecebeArray { public RecebeArray(String[] array) { imprimirPosicao0(array); } public void imprimirPosicao0(String[] array) { System.out.println(array[0]); } } As setas indicam o fluxo de execução até o ponto onde irá acontecer a exceção (estrela) o que ocasiona a quebra no fluxo normal da aplicação. Esta execução pode ser entendida da seguinte forma: Ao invocar o método main, sem o envio de parâmetros, é instanciado um novo objeto RecebeArray e passado como parâmetro do construtor o array vazio, o construtor por sua vez invoca um método desta mesma classe (imprimirPosicao0()) repassando o parâmetro recebido, este método tenta imprimir o elemento da posição 0, primeira posição, e o resultado obtido é uma exceção, já que o array está vazio. Quando esta exceção acontece o programa é encerrado de forma inesperada, perceba que a última linha a ser executada (linha grifada em amarelo) não é percorrida devido ao término inesperado. Podemos observar a visualização da execução desta aplicação na figura a seguir: www.t2ti.com 12 ! Curso Java Starter programa!” não foi apresentada – por uma exceção pois o nosso bloco try/catch não foi capaz de capturá-la, isto aconteceu pois ele foi construído de forma que apenas exceções do tipo java.lang.ArrayIndexOutOfBoundsException sejam tratadas. Para corrigir este problema podemos encadear mais um bloco catch que capture todos os tipos de exceções, vejamos: public class RecebeArray { public RecebeArray(String[] array) { imprimirPosicao0(array); } public void imprimirPosicao0(String[] array) { try{ System.out.println(array[0]); }catch(ArrayIndexOutOfBoundsException e) { System.out.println("Erro: Array vazio, execute o programa novamente" + " passando ao menos um parametro."); }catch(Throwable t) { System.out.println("Mensagem do erro: "+t.getMessage()); t.printStackTrace(); } } } Perceba agora que, no código destacado, adicionamos mais um bloco de catch que captura todos os tipos de exceções – veremos mais a frente como está estruturada a hierarquia de classes de exceções – desta forma caso seja uma exceção do tipo java.lang.ArrayIndexOutOfBoundsException será tratado no primeiro bloco, todos os demais tipos serão tratados no segundo bloco. O código destacado irá imprimir a mensagem (getMessage()) e na seqüência irá imprimir a stacktrace, é importante perceber novamente que após o tratamento da exceção pelo segundo bloco o programa é encerrado normalmente. A seguir temos a execução do novo programa: www.t2ti.com 15 Curso Java Starter Todas as exceções em Java derivam da classe Throwable conforme hierarquia a seguir: Observe que, conforme dito em módulos anteriores, todas as classes em Java estendem de alguma forma – direta ou indiretamente – da classe Object. Nesta imagem estão representadas as três modalidades de exceções existentes na linguagem Java: Unchecked Exception, Checked Exception e Error.  Error: Hierarquia em laranja na imagem, representam situações incomuns, que não são causadas pelo programa, indicam situações que não acontecem usualmente durante a execução de um programa (Ex: Estouro da pilha de execução – StackOverflowError);  Checked Exception: Hierarquia em cinza, representam situações que, geralmente, não são erros de programação e sim indisponibilidade de recursos ou condição necessária para a correta execução inexistente (Ex: Em aplicações distribuídas existe dependência externa de rede de www.t2ti.com 16 Curso Java Starter comunicação – NoRouteToHostException).  Unchecked Exception (RuntimeException): Hierarquia em turquesa (azul escuro), representam situações que, geralmente, identificam erros de programação (programa não é robusto) ou mesmo situações incomuns/difíceis de tratar (Ex: Acessar índice inválido em um array – ArrayIndexOutOfBoundsException); As checked exceptions são tratadas obrigatoriamente, isto é, o compilador só compila a classe se houver um tratamento (bloco try/catch) para aquele tipo de exceção. Segue quadro com relação de algumas das mais comuns exceções: Exceção Quando acontece ArrayIndexOutOfBounds Exception Tentativa de acesso a posição inexistente no array. ClassCastException Tentativa de efetuar um cast em uma referência que não é classe ou subclasse do tipo desejado. IllegalArgumentException Argumento formatado de forma diferente do esperado pelo método. IllegalStateException O estado do ambiente não permite a execução da operação desejada. NullPointerException Acesso a objeto que é referenciado por uma variável cujo valor é null. NumberFormatException Tentativa de converter uma String inválida em número. StackOverflowError Normalmente acontece quando existe uma chamada recursiva muito profunda. NoClassDefFoundError Indica que a JVM não conseguiu localizar uma classe necessária a execução. Jogando (throw) exceções Possivelmente em algum trecho do nosso programa, se uma determinada condição acontecer, nós queiramos lançar uma exceção – por incrível que possa parecer – para informar que a situação esperada não aconteceu. www.t2ti.com 17 Curso Java Starter 5. Modifique a classe abstrata criada no exercício 1 de forma que ela implemente a interface FiguraGeométrica. 6. Implemente os métodos definidos na interface FiguraGeometrica nas classes Quadrado e Retangulo. 7. Modifique o construtor da classe Quadrado de forma que caso seja recebido um valor igual a zero ou negativo seja “jogada” uma exceção do tipo IllegalArgumentException com o seguinte texto: “Valor inválido, o valor esperado é maior que 0 (zero)”. 8. Modifique o construtor da classe Retangulo de forma que caso seja recebido como parâmetro um valor igual a zero ou negativo ou ambos os valores positivos idênticos porém idênticos seja “jogada” duas exceções do tipo IllegalArgumentException com os seguintes textos respectivamente: “Valor inválido, os valores esperados são maior que 0 (zero)” e “Valor inválido, modifique um dos valores a fim de torná-los diferentes”. 9. Crie um programa que solicite a entrada de 2 parâmetros, crie um Quadrado e imprima a área e o perímetro. 10.Modifique o programa desenvolvido no exercício 9. Adicione o tratamento de exceções e caso aconteça uma exceção imprima a stacktrace. Execute o programa forçando uma exceção e observe a stacktrace. 11.Modifique novamente o programa desenvolvido no exercício 9 de forma que caso sejam passados valores inválidos ele trate a exceção e exiba a mensagem em um diálogo (JoptionPane). 12.Crie uma classe abstrata denominada conta corrente. Adicione os métodos sacar, depositar e obter saldo, adicione o atributo saldo total. 13.Estenda a classe desenvolvida no exercício anterior. Crie a classe conta corrente especial que contenha um atributo que represente um limite extra da conta corrente convencional de forma que: 1. O saque debita primeiro o saldo total, na seqüência deve-se debitar o limite do cheque especial; 2. O depósito primeiro deve creditar o limite do cheque especial, até cobrir, e somente após o saldo total. 14.Crie uma exceção que represente o estouro da conta corrente, modifique a classe desenvolvida no exercício 13 de forma que caso seja extrapolado o limite do extra esta exceção seja lançada. 15.Crie um programa que, utilizando as classes desenvolvidas nos exercícios www.t2ti.com 20 Curso Java Starter anteriores (12, 13 e 14), efetue alguns saques e depósitos, tanto sobre o limite extra quanto sobre saldo total, e ainda faça um saque que extrapole todo o valor disponível (limite extra + saldo total). www.t2ti.com 21
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved