• Nenhum resultado encontrado

LINGUAGEM DE PROGRAMAÇÃO I

N/A
N/A
Protected

Academic year: 2019

Share "LINGUAGEM DE PROGRAMAÇÃO I"

Copied!
91
0
0

Texto

(1)

INFORMÁTICA

(2)
(3)

Governador | Eduardo Campos

Vice-Governador | João Soares Lyra Neto

Secretário de Educação | Anderson Stevens Leônidas Gomes

Secretário Executivo de Educação Profissional | Paulo Dutra

Gerente Geral da Educação Profissional | Luciane Pulça

Gestor de Educação a Distância | Marcos Paulo de Assis Castro

Coordenador do Curso | Almir Pires

Professor Conteudista | Márcio Bueno

Equipe Central de Educação a Distância

Andre Fellipe Pinto | Andréia Guerra | Augusto Andrade | Eber Gomes | George Bento | Jannine Moreno | Maria de Lourdes Cordeiro Marques | Maria

Helena Cavalcanti | Mauro de Pinho Vieira | Pedro Luna

(4)

4

Informática | Linguagem de Programação I | Volume 02

SUMÁRIO

1.APROFUNDANDO EM JAVA ... 5

2.APROFUNDANDO ORIENTAÇÃO A OBJETOS ... 22

3.ESCREVENDO MELHORES CÓDIGOS... 53

(5)

5

Informática | Linguagem de Programação I | Volume 02

1. APROFUNDANDO EM JAVA

Objetivos

Compreender métodos de acesso e modificadores. Entender melhor os detalhes de implementação de Java. Aprender o que são atributos e métodos de classe.

Métodos de Acesso e Modificadores

Você já viu que métodos são utilizados para criar o comportamento dos objetos em Java. No exemplo da classe Televisao da aula 3 (figura 3.1), os

métodos aumentarVolume, diminuirVolume e trocarCanal são

implementados de uma forma bem ingênua. Portanto, é necessário aperfeiçoar estas implementações.

A figura 4.1 mostra as novas implementações destes métodos. Considerando que o volume vai de 0 até 100, na linha 36 foi adicionado um if para só aumentar o volume, caso ele seja menor que 100 e na linha 41 foi adicionado outro if para só diminuir o volume se ele for maior que 1. Na linha 46 está sendo feita uma verificação para só permitir canais entre 2 e 99.

(6)

6

Informática | Linguagem de Programação I | Volume 02

Métodos que alteram os valores dos atributos são chamados de métodos modificadores. É comum existir métodos modificadores para os seus atributos

com o nome de “set” seguido do nome do atributo, como no exemplo do

método setVolume da figura 4.2.

Figura 4.2: Captura de tela do Netbeans 6.8: Método setVolume

Fonte: Conteudista

Por exemplo, o método trocarCanal poderia ser renomeado para

setCanal, pois ele simplesmente altera o valor do canal por um novo canal, e ficaria dentro do estilo de programação utilizada por todos os programadores Java.

Em contrapartida, os métodos aumentarVolume e diminuirVolume não poderiam se chamar setVolume, pois todo método “set” tem que seguir o seguinte padrão: deve retornar void e receber como parâmetro um valor do

mesmo tipo do atributo. Veja abaixo a sintaxe dos métodos “set”:

void setNomeDoAtributo (tipo novoValor) {

// código para verificar se o novo valor é válido

e

// alterar o atributo

}

(7)

7

Informática | Linguagem de Programação I | Volume 02

É importante observar que ao utilizar métodos modificadores é possível garantir que os atributos sempre terão valores válidos, diminuindo a quantidade de erros no seu programa.

Como os atributos devem na maioria das vezes serem criados como private, então é necessário que exista algum método de acesso para que você possa saber que valor está armazenado. Por exemplo, é impossível saber qual o volume atual ou o canal atual de uma televisão criada a partir da classe da figura 3.1, pois atributos volume e canal são privados e não existe nenhuma forma de descobrir os seus valores (isto é, não existe nenhum método oferecendo esta funcionalidade).

Para resolver este problema é que existem os métodos “get”, isto é, métodos

que acessam e retornam os conteúdos dos atributos correspondentes. A figura 4.3 apresenta os métodos getCanal e getVolume.

Figura 4.3:Captura de tela do Netbeans 6.8: Método getCanal e getVolume

Fonte: Conteudista

A sintaxe padrão dos métodos “get” é:

tipo getNomeDoAtributo() {

return nomeDoAtributo;

}

Como os métodos “set” e “get” são bem padronizados, a maioria das IDE‟s

fornecem uma forma automatizada de criar estes tipos de métodos. A seguir,

veja como é possível agora criar os métodos “get” e “set” para os atributos

(8)

8

Informática | Linguagem de Programação I | Volume 02

Primeiro passo é clicar com o botão direito em qualquer parte do seu código fonte dentro da sua classe, apontar para o submenu Refatorar, e então clicar na opção Encapsular campos... conforme exibida na figura 4.4.

Figura 4.4: Captura de tela do Netbeans 6.8: Selecionando a opção Refatorar  Encapsular campos... Fonte: Conteudista

A caixa de diálogo Encapsular campos (figura 4.5) é aberta e é nela que você

selecionará quais os métodos “set” e “get” que você deseja criar. Neste exemplo, estão selecionados os métodos “set” e “get” dos atributos marca e

modelo, pois são os que serão gerados automaticamente. Observe também nesta caixa de diálogo que o Netbeans 6.8 também identificou que já foram

(9)

9

Informática | Linguagem de Programação I | Volume 02

estão sem seleção, porém tem um círculo preenchido mostrando os nomes dos métodos já existentes).

Observe que existe uma opção que é “Utilizar método de acesso uniforme quando o campo é acessível” que está marcado. Quando esta opção estiver

ativada, o Netbeans 6.8 irá substituir todos os comandos de atribuição que existirem para os atributos selecionados pelos métodos “set”. Neste exemplo,

esta opção ficará ativada e você visualizará como os construtores serão alterados automaticamente.

Figura 4.5:Captura de tela do Netbeans 6.8: Caixa de diálogo Encapsular campos Fonte: Conteudista

Para confirmar a criação dos métodos “set” e “get” é preciso clicar no botão

Refatorar. A figura 4.6 exibe os métodos criados automaticamente. As linhas de 85 a 87, 92 a 94, 99 a 101 e 106 a 108 possuem os comentários padrões

dos métodos “set” e “get”. Perceba que os métodos getMarca (linhas 88 a 90)

(10)

10

Informática | Linguagem de Programação I | Volume 02

Note que na linha 95 o parâmetro marca possui o mesmo nome do atributo marca, então existe um problema que é como diferenciar o atributo marca do parâmetro marca. Para resolver este problema utilizamos a palavra-reservada this que representa o objeto atual como no comando this.marca = marca;. Então this.marca está referenciando o atributo marca do objeto atual, e marca está referenciando o parâmetro marca da função.

Alguns programadores sempre utilizam a palavra-chave this para acessar os atributos e métodos nas implementações de uma classe para deixar mais claro o código. Então, a linha 89 da figura 4.6 poderia ser return this.marca; ao invés de simplesmente return marca;. Quando não há problemas de conflito entre o nome do parâmetro e o atributo é opcional utilizar o this, porém quando este conflito, então o this passa a ser obrigatório como nas linhas 96 e 110.

Figura 4.6: Captura de tela do Netbeans 6.8: Métodos “set” e “get” criados automaticamente

(11)

11

Informática | Linguagem de Programação I | Volume 02

Testando uma Classe

Se você criou a classeTestes como solicitada na seção 3.2, então você tem

a classeTestescom apenas o métodomainsem nenhum código. Você irá

utilizar estemainpara realizar alguns testes utilizando a classeTelevisao. A primeira providência será copiar todo o código do mainque está dentro da classe Televisao para o main que está na classe Testes. A figura 4.7 mostra o resultado desta cópia. Veja que as linhas 13, 14, 21 e 22 apresentam erros, isto é, o código que funcionava no main da classe Televisaonão funciona nomainda classeTestes.

Existe uma razão óbvia para que este código não funcione na classe Testes:

encapsulamento. Como os atributos são privados, eles só podem ser acessados diretamente se o código for escrito dentro da própria classe. Como agora o código está em outra classe, não é mais possível acessar diretamente estes atributos. Portanto, é necessário utilizar os métodos getCanal() e getVolume(). Por este motivo, é interessante fazer testes de uma classe utilizando omainde uma outra classe.

Figura 4.7:Captura de tela do Netbeans 6.8: Classe Testes com o mesmo main da classe Televisao

(12)

12

Informática | Linguagem de Programação I | Volume 02

Bom, agora que você reforçou o entendimento da diferença entre o modificador private (dos atributos) e public (dos métodos get e set), considere agora esta nova classe Testes (figura 4.8).

Figura 4.8: Captura de tela do Netbeans 6.8: Classe Testes (códigos suprimidos)

Fonte: Conteudista

A classe Testes (figura 4.8) possui além do main, outros dois métodos estáticos

(static). Estes métodos estáticos são os equivalentes às funções que existiam

em C, pois não é necessário nenhum objeto para utilizá-los. Por exemplo, para utilizar o métodoaumentarVolume é necessário que exista um objeto Televisao criado, porém para utilizar o método trocarCanal não é necessário criar nenhum objeto Testes.

Na realidade estes métodos são utilizados pelo main. Veja que o main foi escrito antes do método exibirDetalhes e trocarCanal, porém em Java mesmo assim é possível utilizá-lo no main. Para isto ser possível em C, era necessário escrever os protótipos destas duas funções antes da escrita do main, lembra?

(13)

13

Informática | Linguagem de Programação I | Volume 02

parâmetros de tipos primitivos (int, double, char, etc...) são sempre passados como valor e parâmetros de tipos objetos (String, Televisao,

etc...) são sempre passados como referência. Portanto, qualquer alteração no

objeto referenciado pelo parâmetro tv será refletido no parâmetro real (o parâmetro passado ao utilizar o método).

:

Figura 4.9: Captura de tela do Netbeans 6.8: Métodos estáticos definirTamanho e trocarCanal

Fonte: Conteudista

O método exibirDetalhes simplesmente mostra na tela os detalhes do objeto Televisao, porém para isto é necessário que você vá na classe Televisão e

selecione que quer criar automaticamente o método “get” do atributo ligada, como você fez na seção 4.1. Porém você irá perceber que os métodos “get”

(14)

14

Informática | Linguagem de Programação I | Volume 02 o “is”. Neste exemplo, o método isLigada é criado, ao invés do método

getLigada.

Observe que o método isLigada está sendo utilizado na linha 49 da figura 4.9, enquanto que os outros métodos “get” estão sendo utilizados nas linhas 53 a

56.

(15)

15

Informática | Linguagem de Programação I | Volume 02

Figura 4.10Captura de tela do Netbeans 6.8: Método main da classe Testes

(16)

16

Informática | Linguagem de Programação I | Volume 02

Neste exemplo, se ele digitar um valor errado, então será solicitado que ele digite novamente um canal, então ele perceberá que é preciso informar um valor correto. Uma outra solução seria simplesmente informar canal inválido e não solicitar um novo valor.

Quando o usuário digitar um valor correto, a condição do do-while ficará falsa e o canal do objeto referenciado por tvserá alterado (linha 68 da figura 4.9). Como o objeto referenciado por tvé o mesmo objeto referênciado por tv1que foi passado para o método trocarCanal (linha 34 da figura 4.10), então

qualquer alteração feita através da variável tv será também percebida pela

variável tv1.

O main exibido na figura 4.10 solicita inicialmente que o usuário digite a marca e o modelo da televisão (linhas 12 a 15), e isto só será solicitado apenas uma vez, pois estes comandos estão fora do comando de repetição do-while(linhas 17 a 43). Estedo-whileestá sendo utilizado para exibir o estado atual da televisão (linha 18) e um menu com opções para o usuário escolher o que ele quer fazer (ligar a televisão, alterar o canal e o volume, ou sair do programa).

Observe que para chamar um método estático não é necessário um objeto daquele tipo, pois você utiliza diretamente a classe (linhas 18 e 34 da figura 4.10). Então, o métodoexibirDetalhesfoi executado utilizando o seguinte

comando:Testes.exibirDetalhes(tv1);. Vale salientar que como você

está chamando métodoexibirDetalhes dentro da própria classe Testes,

então o “Testes.” seria opcional. Porém, é recomendado que ao utilizar métodos estáticos sempre coloque também o nome da classe, mesmo quando é opcional, como neste exemplo.

(17)

17

Informática | Linguagem de Programação I | Volume 02

<Atividades de aprendizagem:

1. Altere o programa anterior para que mostre uma mensagem de opção inválida, caso o usuário digite um valor inválido.

2. Altere os métodos alterar o canal e o volume da televisão para só aceitar qualquer alteração caso a televisão esteja ligada. Se a televisão estiver desligada, não é necessário informar nada para o usuário. Basta que você acrescente um if nos métodos modificadores da classe Televisao, ou então, acrescente uma outra condição aos if’s já existentes.>

Palavra-reservada

this

Anteriormente você viu um dos uso da palavra-chavethis, ao utilizá-la para diferenciar um atributo de um parâmetro quando ambos têm o mesmo nome (linhas 96 e 110 da figura 4.6).

Porém, existem uma utilização da para a palavra-chave this quando você estiver trabalhando com construtores. Observe os construtores das figuras 3.5 e 3.6, você vai notar que o construtor da figura 3.6 teria o seu código reduzido se fosse possível reaproveitar o código do construtor da figura 3.5. Este é um exemplo de como utilizar o this em construtores. Veja na figura 4.11 como o construtor que tem dois parâmetros é chamado dentro do construtor padrão.

Figura 4.11: Captura de tela do Netbeans 6.8: Construtor utilizando a palavra-chave this

Fonte: Conteudista

Os parâmetros marca e modelo no construtor padrão estão sendo inicializados com string vazia, então como o construtor exibido na figura 3.5 recebe a marca e o modelo como parâmetros, então para reaproveitar o código anterior, são passadas duas strings vazias utilizando a palavra-chave this.

(18)

18

Informática | Linguagem de Programação I | Volume 02

construtor, senão há um erro de compilação. Observe que a única função disto é a inicialização dos atributos, isto é, o outro construtor não tem papel de construir nada, só de inicializar os atributos.

Atributos e Métodos de Classe

Atributos de classe são variáveis que são compartilhadas por todos objetos

de uma classe. Por exemplo, se você quisesse que cada objetoTelevisao

tivesse um número de série, então seria necessário criar um novo atributo para armazenar o número de série e também uma variável que armazenasse quantos objetos televisões tivessem sido criados.

O atributo número de série seria diferente para cada objeto, então é um atributo de objeto, porém a quantidade de televisões criadas só possui um único valor, portanto não seria um atributo de objeto, e sim um atributo de classe. Na hora de declarar o atributo é necessário colocar a palavra-chave staticpara informar que este atributo seja de classe. Veja a sintaxe abaixo:

modificadorDeAcesso static tipo nomeDoAtributo =

valorInicial;

No exemplo da classe Televisao veja na figura 4.12 as alterações necessárias para a inclusão do número de série: inclusão de um novo atributo

de objeto numeroSerie (linha 10), criação do atributo de classe

qtdTelevisoes (linha 11) e sua incialização com o valor zero, incremento do atributo qtdTelevisoes sempre que um objeto for criado (linha 19), inicialização do novo atributo numeroSerie com o valor da quantidade de

televisões existentes (linha 20) e a criação de um método “get‟ para o atributo

número de série (linhas 23 a 25).

(19)

19

Informática | Linguagem de Programação I | Volume 02

É possível que o atributo qtdTelevisoes seja acessado sem colocar o nome da classe antes, porém é recomendado que os atributos de classes sejam utilizados colocando o nome da classe como na linhas 19 e 20 da figura 4.12.

Figura 4.12: Captura de tela do Netbeans 6.8: Parte do código da classe Televisao

Fonte: Conteudista

Para se criar constantes em Java são utilizados atributos de classes que não podem ser modificados. Para isto, é necessário utilizar a palavra-reservada final. Veja a sintaxe abaixo:

modificDeAcesso static final tipo NOME_CONSTANTE =

valorInicial;

As linhas a seguir mostram a definição de duas constantes para a classe Televisao:

(20)

20

Informática | Linguagem de Programação I | Volume 02

Por convenção, nomes de constantes em Java são escritas todas em maiúsculas, e se necessário, utilizar o caractere de sublinhado para separar os nomes de constantes compostos, como no exemplo acima.

Neste exemplo, foram utilizadas constantes privadas, porém como nenhum outro código pode alterar o valor de uma constante, então não há problemas em declarar constantes como públicas.

Os métodos de classe são métodos que não precisam de um objeto para serem executados, e por isso, só podem acessar os atributos estáticos de uma classe. Veja na figura 4.13 um método estático para a classe Televisao que retorna a quantiade de televisões criadas até o momento. Como este método é estático ele pode acessar o atributo estático qtdTelevisoes, porém se ele tentasse acessar qualquer outro atributo da classeTelevisaoiria gerar um erro de compilação.

Figura 4.13: Captura de tela do Netbeans 6.8: Método estático getQtdTelevisoes

Fonte: Conteudista

(21)

21

Informática | Linguagem de Programação I | Volume 02

RESUMO

Nesta aula você aprendeu para que servem os métodos “get” e “set” e como

criá-los automaticamente no Netbeans 6.8. Você também viu como criar um main para testar as classes que você tenha criado. Também aprendeu a utilização das palavras-reservadas this (para acessar atributos, métodos e construtores) e static (para criar atributos e métodos de classe).

<Atividades de aprendizagem:

1. Crie uma classe Retangulo que possua como atributos altura e

largura do tipo double.

2. Crie os métodos “get” e “set” para os atributos da classeRetangulo.

Lembre-se que só é permitido um valor positivo para a largura e a altura

(não pode ser nem zero, nem negativo).

3. Crie dois construtores: o padrão que inicializa os atributos com largura 2

e altura 1, e o construtor com dois parâmetros que recebe dois parâmetros

para inicializar os dois atributos. Se por acaso for passado parâmetros inválidos, utilize os valores como no construtor padrão.

4. Crie o método area() que calcule a área deste retângulo.

(22)

22

Informática | Linguagem de Programação I | Volume 02

2. APROFUNDANDO ORIENTAÇÃO A OBJETOS

Objetivos

Aprofundar o conhecimento de orientação a objetos. Entender o que é uma interface.

Aprender o poder da heranaça e sua implementação em Java. Diferenciar entre uma interface e uma classe abstrata.

Conhecer a classe Object e alguns de seus métodos.

Interfaces

Criar interfaces em Java é similar a escrita de um contrato, onde você especifica o que deve ser feito, porém não informa como deve ser feito. Imagine que você deseja criar um padrão que todas as televisões devessem respeitar, porém em nenhum momento você quisesse restringir a tecnologia ou como as televisões fossem criadas. Em Java, você definiria uma interface que toda televisão devesse implementar. Por exemplo, veja a interface TV apresentada na figura 5.1.

Figura 5.1: Captura de tela do Netbeans 6.8: Interface TV

(23)

23

Informática | Linguagem de Programação I | Volume 02

Na interfaceTVsó estão exibidas as assinaturas dos métodos que toda televisão precisa ter, em nenhum momento é informado como estes métodos devem ser implementados, portanto qualquer fabricante de televisão pode criar uma televisão com a tecnologia que quiser, desde que possua estas funcionalidades (e também com estes mesmos nomes de métodos) pode afirmar que é do tipoTV.

Então, se um fabricante utilizar a tecnologia plasma e outro fabricante utilizar a tecnologia de LEDpara fabricar umaTV, não vai haver o menor problema se eles respeitarem o contrato definido, isto é, a interface definida.

Este tipo de coisa acontece bastante no mundo real, por exemplo, quando os fabricantes pararam de fazer vídeos cassetes e começaram a fazer tocadores de DVD para que os usuários não tivessem nenhuma dificuldade nesta mudança, eles continuaram utilizando a mesma interface, apesar de internamente a tecnologia ser totalmente diferente. O usuário continuou utilizando os meus botões no controle remoto: tocar (play), pausar (pause), parar (stop), próximo (next), anterior (previous), etc. A interface para um

“tocador de vídeo” foi respeitada, independentemente se é um vídeo cassete,

um tocador de DVD ou um tocador de Blu-ray.

No exemplo da classe Televisao utilizada durante este curso, ela não respeita a interface TV, pois ela não possui os métodos aumentarCanal e

diminuirCanal, ela só tem o setCanal. Portanto, se a classe não respeitar algo da interface o Java irá informar isto através de um erro de compilação. Portanto, estes métodos precisam ser incluídos para que seja possível fazer com que a classe Televisao implemente a interface TV. Uma outra alteração necessária é a seguinte: a interface televisão só possui um método ligar, isto significa que ele também serve para desligar, então será preciso remover o método desligar e alterar o método ligar para que ele tenha estas duas funcionalidades.

(24)

24

Informática | Linguagem de Programação I | Volume 02

verde com a letra I maiúcula o início de cada método pertencente à interface TV.

(25)

25

Informática | Linguagem de Programação I | Volume 02

Figura 5.2: Captura de tela do Netbeans 6.8: Classe Televisao implementando a interface TV

(26)

26

Informática | Linguagem de Programação I | Volume 02

Interfaces só podem incluir assinaturas de métodos (que não sejam privados) e constantes. Um outro detalhe é que uma classe pode implementar várias interfaces, e para isto, basta separar as interfaces com vírgulas. Veja a sintaxe abaixo:

modificadorDeAcesso nomeDaClasse implements Interface1, ... A figura 5.3 mostra um diagrama de classes UML contendo a classe

(27)

27

Informática | Linguagem de Programação I | Volume 02

Figura 5.3:Diagrama de classes contemplando a classe Televisao implementando a interface TV

Fonte: Conteudista

<Saiba Mais: O diagrama apresentado na figura 5.3 pode ser criado com ferramentas como: SDE for NetBeans da Visual Paradigm, JD eveloper da Oracle e astah* da Change Vision, entre outras>

<Atividades de aprendizagem:

1. Atualize o seu projeto do Netbeans para que ele tenha também a interface TV exibida na figura 5.3.

(28)

28

Informática | Linguagem de Programação I | Volume 02 3. Altere os métodos aumentarVolume, diminuirVolume, aumentarCanal, diminuirCanal e setCanal para que eles utilizem as constantes definidas na interface TV exibidas na figura 5.3.>

Utilizando Interface como um Tipo

O main que está exibido na figura 5.4 cria uma televisão (linha 6), liga esta televisão (linha 7), muda o seu canal para 77 (linha 8) e aumenta o seu volume duas vezes (linhas 9 e 10).

Figura 5.4:Captura de tela do Netbeans 6.8: Utilização de interface como um tipo de dados Fonte: Conteudista

A linha 6 da figura 5.4 declara uma variável tv1 do tipo TV a faz referenciar um um objeto do tipo Televisao recém-criado. Portanto, ao utilizar a variável tv1 é possível acessar qualquer método definido na interface TV.

Imagine agora que existe uma outra classe chamada TelevisaoDigital que também implementa a interface TV. Se você quisesse executar o mesmo código exibido na figura 5.4 com a nova classe, a única alteração seria substituir o new Televisao() por new TelevisaoDigital(), pois como a televisão digital também implementa a interface TV, todos os códigos das linhas 7 a 10 irão funcionar corretamente.

(29)

29

Informática | Linguagem de Programação I | Volume 02

alterar no seu código a linha que cria o objeto e todo o resto do seu código funcionará corretamente.

Um exemplo mais concreto desta vantagem é o seguinte: imagine que você sempre executa os seguintes comandos toda vez que chega em casa à noite: liga a televisão, muda para o seu canal predileto e aumenta o volume da televisão. Se você comprar agora uma televisão integrada que é uma televisão com um tocador de DVD e substituir a sua televisão antiga, se a nova tiver a mesma interface, você continuará executando a mesma sequência de comandos, como se nada tivesse mudado.

Porém, existe também um problema de utilizar um objeto do tipo Televisao através de uma variável do tipo da interface TV, que é não poder utilizar todas a funcionalidade disponível na classe Televisao. Se você comparar os

métodos disponíveis na interface TV e na classe Televisao é possível notar que a classe Televisao possui um método a mais que é o setVolume, que não pode ser utilizado com uma variável do tipo TV.

Esse é o problema da perda de informação: a funcionalidade existe para aquele objeto, porém não é possível acessá-la, pois você está o está referenciando utilizando uma variável de outro tipo. O Java mostra este tipo de erro como um erro de compilação (veja a linha 11 da figura 5.5).

(30)

30

Informática | Linguagem de Programação I | Volume 02

Conversão entre Tipos

Uma forma de resolver o problema da perda da informação é fazendo uma conversão de tipo que em linguagem de programação se chama cast.

Veja a sintaxe de como fazer o cast de um tipo para outro:

(novoTipo) variavel

Você só deve fazer este tipo de conversão quando o tipo for compatível, ou então haverá um erro de execução no momento em que o programa estiver rodando. Veja na linha 11 da figura 5.6 a utilização do cast para poder

acessar a funcionalidade existente no objeto Televisao. Observe a utilização de parênteses extras para poder acessar o método setVolume.

Figura 5.6Captura de tela do Netbeans 5.8: Realizando conversão entre tipos Fonte: Conteudista

No exemplo da figura 5.6 não houve nenhum problema em utilizar o cast, pois

é um programa bem simples, e a conversão foi feita corretamente. Porém, existem situações em que não é possível saber com certeza se o objeto referenciado é do tipo que se quer realizar a conversão, e nestes casos pode ocorrer um erro de execução.

Para que nunca aconteça um erro de execução é possível utilizar o operador instanceof que verifica se um objeto é do tipo desejado. Este operador retorna um true ou false e a sua sintaxe é a seguinte:

variavel instanceof NomeDoTipo

(31)

31

Informática | Linguagem de Programação I | Volume 02

notar que o operador instanceof testa realmente o objeto referenciado por tv1 e não apenas o tipo da variável tv1.

Figura 5.7: Captura de tela do Netbeans 6.8: Utilização do operador instanceof

Fonte: Conteudista

Redefinindo ou Estendendo uma Interface

Às vezes, você sente a necessidade de incluir um novo método numa interface, porém é importante avaliar todos os prós e contra antes de fazer uma alteração destas.

Lembre-se que uma interface é um contrato que foi definido e que provavelmente muitas outras classes implementaram todos os métodos deste contrato. Portanto, se você alterar este contrato muitas classes passarão a não compilar mais. E todos os programadores que implementaram a sua interface ficarão com muita raiva e precisarão alterar os seus códigos.

Lógico que existem casos em que isto é inevitável, e você terá que alterar uma interface e arcar com a consequência de precisar alterar também todas as classes que implementam esta interface. Portanto, é necessário que você analise bastante todas as funcionalidades necessárias de uma interface para não ter problemas posteriores.

Uma outra forma de resolver este problema é deixar a interface já criada do jeito atual e criar uma nova interface estendendo a funcionalidade da primeira. Como exemplo, suponha que analisando a interface TV foi percebido que era necessário também incluir o método mute (sem som), porém como nem toda televisão tem um botão para esta funcionalidade, achou melhor criar uma nova interface chamada TVcomMute que tivesse também todas as funcionalidades da interface TV.

(32)

32

Informática | Linguagem de Programação I | Volume 02

TVcomMute é também do tipo TV, isto é, se você tivesse escrito a interface TVcomMute sem estender a interface TV, seriam dois tipos diferentes, e assim, não poderia realizar nenhum cast entre eles.

Figura 5.8: Captura de tela do Netbeans 6.8: Interface TVcomMute estendendo TV

Fonte: Conteudista

Assim, agora é possível ter televisões que implementam a interface TV e outras televisões que implementam a interface TVcomMute. As televisões que implementam a funcionalidade mute podem informar que implementam a interface TVcomMute, pois automaticamente também implementam a interface TV. Você pode pensar como se TVcomMute fosse um subtipo de TV.

(33)

33

Informática | Linguagem de Programação I | Volume 02

Figura 5.9: Captura de tela do Netbeans 6.8: Trecho da classe Televisaoimplementando TVcomMute Fonte: Conteudista

Na linha 5 da figura 5.9 não é mais necessário informar que a classe

(34)

34

Informática | Linguagem de Programação I | Volume 02

Uma outra possibilidade de implementar o mute, era o de criar um atributo booleano mute e a sua funcionalidade seria idêntica a do atributo ligada (variando entre true e false), e não haveria nenhuma alteração no valor do volume da televisão.

Na figura 5.10 o exemplo da figura 5.4 foi estendido para você entender melhor a utilização da interface TVcomMute e a utilização de cast entre os

tipos Televisao, TV e TVcomMute e até a linha 15 não há nenhuma alteração.

Figura 5.10: Captura de tela do Netbeans 6.8: Utilização de cast e da interface TVcomMute

Fonte: Conteudista

Na linha 16 da figura 5.10 o operador instanceof é utilizado para saber se o objeto referenciado pela variável tv1 é do tipo TVcomMute, caso ele seja, então as linhas de 17 a 20 serão executadas. Na linha 17 é criada uma nova variável tv2 do tipo TVcomMute e ela passa a referenciar o mesmo objeto referenciado pela tv1, observe que é necessário realizar um cast. Utilizando a

(35)

35

Informática | Linguagem de Programação I | Volume 02

é criada a variável tv3 do tipo TV e esta variável agora irá referenciar o objeto apontado por tv2, observe que agora não foi necessária a realização de um

cast, pois como TVcomMute estende TV, então a conversão é feita

implicitamente. Finalmente na linha 20, a televisão é desligada utilizando a variável tv3.

É importante notar que apenas um objeto foi criado, e existiram três variáveis (tv1, tv2 e tv3) que referenciavam este único objeto. E apesar de ser o mesmo objeto, apenas através da variável tv2 era possível acessar o método mute diretamente. Se você quisesse acessar o método mute utilizando as variáveis tv1 ou tv3 seria necessário realizar o cast para TVcomMute. Lembre-se ainda

que se você quisesse acessar o método setVolume disponível no objeto criado, nenhuma das variáveis poderiam acessá-lo diretamente, pois seria necessário um cast para o tipo Televisao.

<Atividades de aprendizagem:

1. Crie uma interface Comparavel que possua um único método com a seguinte assinatura: int compara (Comparavel outroObjeto);

2. Altere a classe Retangulo feito no exercício da aula 4 para que ela implemente a interface Comparavel. A implementação deste método deve retornar -1 quando o objeto atual for menor que o outroObjeto, 0 quando eles forem iguais e +1 quando o objeto atual for maior que o outroObjeto recebido como parâmetro). Para saber se um objeto é maior ou menor que outro utilize as suas áreas para fazer esta comparação (e para isto será necessário converter o outroObjeto que é do tipo Comparavel para o tipo Retangulo). 3. Faça um main que crie dois retângulos com informações digitadas pelo usuário e imprima qual destes objetos é maior. Observação: você só deve declarar variáveis do tipo Comparavel neste main.>

Herança

(36)

36

Informática | Linguagem de Programação I | Volume 02

A classe pai também é chamada de classe base ou superclasse, enquanto que a classe filho é chamada também de classe derivada ou subclasse. Com exceção da classe Object que não possui nenhuma superclasse, toda classe em Java possui uma única superclasse direta, isto é, possui uma única classe pai, portanto em Java só existe a chamada herança simples. Se uma classe não definir qual a sua classe pai, então implicitamente a sua superclasse é a classe Object.

Uma classe pode ser derivada de uma outra classe que por sua vez também possui uma outra superclasse, portanto é possível criar uma hierarquia de classes em Java, como pode ser visualizada na figura 5.11.

Figura 5.11: Hierarquia de classes do Java Fonte: Conteudista

A classe Object é uma classe que possui métodos bases que todas as classes em Java implementam, como equals(Object obj) e toString(), por exemplo.

A palavra-chave utilizada para informar que uma classe herda de outra em Java é extends. Ela é a mesma utilizada no caso das interfaces, porém em interfaces não existe código para ser herdado. Uma outra diferença é que uma interface pode estender de várias outras (herança múltipla), enquanto que uma classe só pode estender de uma outra (herança simples). Veja a seguir a sintaxe para declarar que uma classe estende outra:

(37)

37

Informática | Linguagem de Programação I | Volume 02

Imagine que agora você quer uma televisão que tem todas as funcionalidades da Televisao implementada até o momento, porém quer que ela também possa gravar a programação e depois tocar a programação gravada. Para isto, as implementações destas funcionalidades serão bem simplificadas, só para ser possível entender como implementar herança em Java.

A figura 5.12 apresenta o código da classe TelevisaoGravadora que herda da classe Televisao. Esta classe possui um atributo que é a quantidade de gravações realizadas e o outro é um array que realmente armazena as gravações (linhas 5 e 6).

Figura 5.12:Captura de tela do Netbeans 6.8: Classe TelevisaoGravadora

(38)

38

Informática | Linguagem de Programação I | Volume 02

Na classe TelevisaoGravadora da figura 5.12 alguns métodos estão suprimidos para que você possa se concentrar inicialmente na definição da classe e como criar os construtores. Na linha 3 você vê a informação que a classe TelevisaoGravadora herda todos os atributos e métodos da classe Televisao (a palavra-chave extends). Como o código de inicialização é necessário para vários construtores, foi criado o método privado init (linha 21 a 28) para inicializar os atributos extras da classe TelevisaoGravadora. Como a classe TelevisaoGravadora herdou todos os atributos da classe Televisao, também é necessário inicializar os atributos herdados. Para isto, utiliza-se os construtores da classe pai para que eles sejam inicializados. Se nenhum constutor da classe pai é chamado explicitamente, então implicitamente o construtor padrão é chamado, como foi o caso dos construtores definidos nas linhas de 8 a 10 e de 12 a 14 da figura 5.12. Já o construtor definido nas linhas de 16 a 19, o construtor com dois parâmetros da classe pai foi chamado explicitamente (veja a linha 17).

Do mesma forma que é possível utilizar a palavra-chave this para chamar um outro construtor da mesma classe, é possível utilizar a palavra-chave super para chamar um construtor da classe pai. Isso é feito desta maneira, pois em Java constutores não são herdados. Se for utilizar a palavra-chave super para chamar o construtor da classe pai, então é necessário que ele seja o primeiro comando do construtor, senão haverá um erro de compilação. Por isso, não existe como você chamar dentro de um mesmo construtor um construtor da classe pai (com o super) e outro construtor da mesma classe (com o this), pois não tem como eles dois serem o primeiro comando do construtor.

Uma observação importante a ser feita é que se por acaso a classe pai não tiver construtor padrão, você precisa explitamente chamar um outro construtor, pois se você não fizer esta chamada, o Java implicitamente irá chamar o construtor padrão, e como ele não existe, haverá um erro de compilação.

(39)

39

Informática | Linguagem de Programação I | Volume 02

Neste exemplo, a classe TelevisaoGravadora não possui acesso direto aos atributos canal e volume, entre outros. Porém, é possível acessá-los

indiretamente, pois existem os métodos “get” e “set” para estes atributos. Isto quer dizer que quando você cria um objeto do tipo TelevisaoGravadora, internamente ele possui os atributos privados da classe Televisao, porém eles só serão acessíveis através de métodos públicos disponíveis na sua superclasse.

A figura 5.13 mostra as implementações dos métodos que foram suprimidos na figura 5.12. Observe que nas linhas 32 e 33 foi necesário utilizar os métodos getCanal e getVolume, pois os atributos canal e volume da classe Televisao não poderiam ser acessados diretamente. O método gravar (linhas 30 a 36) apenas guarda a mensagem de que canal e em que volume a televisão estava na hora que foi solicitada a gravação. O método reproduzirTudo (linhas 38 a 41) mostra na tela todas as gravações armazenadas. E finalmente, o método apagarTudo remove todas as strings

armzenadas.

Figura 5.13: Captura de tela do Netbeans 6.8: Algusn métodos da classe TelevisaoGravadora

Fonte: Conteudista

(40)

40

Informática | Linguagem de Programação I | Volume 02

TelevisaoGravadora, a não ser que seja feito um cast para esta classe.

Lembre-se que este cast só deve ser feito se for feita uma verificação antes

com o operador instanceof.

Redefinição de Métodos e Polimorfismo

Um método pode ser redefinido (override) numa subclasse se for criado um método com a mesma assinatura e tipo de retorno da superclasse.

Para demonstrar este conceito a figura 5.14 mostra um novo método da classe Televisao chamado imprimeStatus que imprime a marca, o modelo, se a televisão está ligada ou desligada, e se estiver ligada também exibe qual o canal e o volume atual.

Figura 5.14: Captura de tela do Netbeans 6.8: Método imprimeStatus da classe Televisao

Fonte: Conteudista

(41)

41

Informática | Linguagem de Programação I | Volume 02

Figura 5.15Captura de tela do Netbeans 6.8: Método imprimeStatus da classe TelevisaoGravadora

Fonte: Conteudista

(42)

42

Informática | Linguagem de Programação I | Volume 02 Figura 5.16:Captura de tela do Netbeans 6.8: main exibindo polimorfismo

Fonte: Conteudista

(43)

43

Informática | Linguagem de Programação I | Volume 02

Figura 5.17: Captura de tela do Netbeans 6.8: Execução do main da figura 5.16

Fonte: Conteudista

Os conceitos de sobrecarga e polimorfismo podem confundir, porém são bem distintos: na sobrecarga a escolha do método a ser executado depende da quantidade e/ou dos tipos dos parâmetros de chamada (normalmente métodos definidos na mesma classe), enquanto que no polimorfismo a escolha esta escolha depende do tipo do objeto (obrigatoriamente definidos em classes diferentes dentro da mesma hierarquia).

Classes Abstratas

São um tipo especial de classe que pode ou não ter métodos abstratos e não podem ser instanciadas, isto é, você não pode utilizar new para criar um objeto deste tipo. Uma clase abstrata pode ser estendida, então uma subclasse sua para não ser abstrata precisa implementar todos os métods abstratos da sua superclasse.

Um método abstrato é um método que é declarado sem a sua implementação, da mesma forma que os métodos são declarados em uma interface. Implicitamente, todos os métodos de uma interface são abstratos, por isso não é necessário colocar a palavra-reservada abstract. Veja a seguir a sintaxe de um método abstrato:

(44)

44

Informática | Linguagem de Programação I | Volume 02

A figura 5.18 mostra uma classe abstrata contendo os métodos abstratos area (linha 21) e desenhar (linha 23). É importante notar que uma classe abstrata pode conter outros métodos com código, isto é, métodos concretos, como o moverPara (linhas 16 a 19). As classes abstratas também podem ter construtores que neste caso têm o papel de inicializar os atributos do objeto (veja os construtores nas linhas 7 a 9 e 11 a 14).

A clase Retangulo que você criou nas atividades de aprendizagem no final da aula 4 pode ser alterada para estender a classe FiguraGeometrica apresentada na figura 5.18. Esta classe ainda precisa incluir os métodos getX() e getY(). A classe Retangulo pode ser uma classe concreta (não abstrata), pois ela implementa o método area(), que estava definido como abstrato na classe FiguraGeometrica.

Figura 5.8:: Captura de tela do Netbeans 6.8: Classe abstrata FiguraGeometrica

(45)

45

Informática | Linguagem de Programação I | Volume 02

A definição de métodos abstratos em uma classe obriga que as suas subclasses precisem implementar este método, ou esta subclasse precisa também ser abstrata. Veja a Figura 5.19 uma hierarquia da classe abstrata FiguraGeometrica. Portanto, cada uma das suas subclasses precisam implementar o método area. Observe que a classe FiguraGeometrica é a única classe abstrata (apenas ela está em itálico).

Figura 5.19: Hierarquia de classes exibindo as subclasses de FiguraGeometrica

Fonte: Conteudista

(46)

46

Informática | Linguagem de Programação I | Volume 02 Figura 5.20: Diagrama UML das classes FiguraGeometrica e Retangulo

Fonte: Conteudista

(47)

47

Informática | Linguagem de Programação I | Volume 02

Classe Object

Como todas as classes em Java herdam direta ou indiretamente da classe Object é importante entender que existem alguns métodos nesta classe que você precisa implementar na sua subclasse se desejar utilizá-los.

Os métodos que será visto neste curso são: equals e toString, os outros ficam como atividade de pesquisa para você.

Método equals()

O operador de igualdade em Java (==) só deve ser utilizado quando comparar tipos primitivos (int, float, double, char, ...), pois quando ele é utilizado para comparar objetos o seu comportamento é um pouco diferente.

O operador == testa se as duas váriaveis sendo testadas referenciam o mesmo objeto (isto é, testam a sua identidade), enquanto o método equals serve para testar se dois objetos são iguais, isto é, todos os atributos possuem os mesmos valores.

(48)

48

Informática | Linguagem de Programação I | Volume 02 Figura 5.21Captura de tela do Netbeans 6.8: Main mostrando diferença entre identidade e igualdade

Fonte: Conteudista

(49)

49

Informática | Linguagem de Programação I | Volume 02

Figura 5.22: aptura de tela do Netbeans 6.8: Saída da execução do programa da figura 5.21 Fonte: Conteudista

Portanto, se você quisesse que dois objetos fossem iguais se eles fossem da mesma marca e mesmo modelo, então você poderia redefinir o método equals para que ele se comporte da maneira que você deseja (veja a assinatura deste método na linha 131). Observe na figura 5.23 a redefinição do método equals para a classe Televisao, onde só são considerados os atributos marca e modelo para determinar a igualdade de duas televisões. Primeira coisa que tem que ser feita é verificar se o objeto obj recebido como parâmetro é também uma Televisao (linha 132), se não for então já retorna false (linhas 136 e 137). Se for uma televisão então é necessário testar se a marca e o modelo são iguais (linha 134), e para isto é necesário fazer um cast

da classe Object para a classe Televisao (linha 133). É importante notar que na linha 134, como você está testando dois objetos do tipo String (que é uma classe) novamente é utilizado o método equals ao invés do ==.

Figura 5.23:Captura de tela do Netbeans 6.8: Método equals da classe Televisao

(50)

50

Informática | Linguagem de Programação I | Volume 02

Na linha 131 o Netbeans 5.8 apresenta um aviso (não chega a ser um erro), que está faltando a redefinição do método outro método da classe Object que é o hashCode. Se você quiser, é só clicar neste aviso e solicitar que o Netbeans crie o código deste método para você. Normalmente é solicitado que você também redefina o método hashCode quando você redefine o método equals.

Método toString()

Este é um método que tem como objetivo transformar o objeto atual em uma String. Normalmente, esta String possui uma representação textual do objeto. Por exemplo, para a classe Retangulo, uma representação textual poderia

ser: “Retângulo com centro (x,y) e tamanho (largura x altura)”.

A figura 5.24 apresenta um exemplo de codificação do método toString para a classe Retangulo. Observe na linha 12 a assinatura do método toString. As linhas 13 e 14 geram a String correspondente utilizando os atributos x e y (atributos privados da classe pai, por isso a necessidade da utilização dos

métodos “get”) e largura e altura (atributos desta classe, e por isso não é necessário a utilização dos métodos “get”).

Figura 5.24:Captura de tela do Netbeans 5.8: Método toString() da classe Retangulo

Fonte: Conteudista

Veja na figura 5.25 um main utilizando o método toString implicitamente. Na linha 8, quando o objeto r1 é impresso na tela, internamente o que é impresso é a representação textual deste objeto. Na linha 9, quando utiliza o operador de concatenação de String (+) para concatenar uma String com o objeto r2, então internamente é como o método toString() tivesse sido realmente

(51)

51

Informática | Linguagem de Programação I | Volume 02

Figura 5.25:Captura de tela do Netbeans 6.8: Utilização do método toString() implicitamente

Fonte: Conteudista

Ao executar o programa da figura 5.25 você tem na tela a saída exibida na figura 5.26. Onde é possível visualizar a representação textual dos dois retângulos criados no programa da figura 5.25 (linhas 6 e 7).

Figura 5.26:Captura de tela do Netbeans 6.8: Execução do programa exibido na figura 5.25 Fonte: Conteudista

Portanto, é sempre conveniente redefinir o método toString para as classes que você criar, pois fornecem uma forma simples e rápida de converter um objeto da sua classe em uma String.

(52)

52

Informática | Linguagem de Programação I | Volume 02 Figura 5.27:Captura de tela do Netbeans 6.8: Execução do programa exibido na figura 5.25 sem a redefinição

do método toString da figura 5.24 Fonte: Conteudista

RESUMO

Nesta aula você aprendeu um dos principais conceitos de orientação a objetos que é herança e seus conceitos relacionados interface e herança. Com isto é possível reutilizar código e criar classes com propósitos bem definidos. Isto é, ao invés de criar uma super classe que tenha todo o código necessário, é possível criar uma classe base com funcionalidades comuns a outras classes e assim ir criando uma hierarquia de classes para solucionar o seu problema. Você também viu para que serve os métodos equals e toString definidos na classe Object.

<Atividades de aprendizagem:

1. Crie a classe FiguraGeometrica que tenha todos os métodos, atributos e construtores apresentados na figura 5.20, além dos métodos getX() e getY(). 2. Altere a classe Retangulo para que tenha todos os métodos, atributos e construtores apresentados na figura 5.20.

3. Crie a classe Circulo da figura 5.19, contendo o atributo raio e implementando dois construtores e o método área.

4. Crie a classe Triangulo da figura 5.19, contendo os atributos base e altura e implementando dois construtores, os métodos “get” e “set” para estes

atributos e o método área.

5. Implemente o método toString para todas as classes implementadas nas questões anteriores com as informações que você acha importante.

(53)

53

Informática | Linguagem de Programação I | Volume 02

3. ESCREVENDO MELHORES CÓDIGOS

Objetivos

Aprender como tratar erros em Java.

Entender a diferença entre exceções checadas e não checadas.

Aprender o que são pacotes.

Saber como trabalhar com arquivos em Java.

Exceções

Uma exceção em Java é um evento que ocorre durante a execução normal do programa, fazendo com que o fluxo de execução do programa seja quebrado.

O que acontece em Java é que quando um método encontra um erro, ele cria um objeto para cuidar deste erro, este objeto contém informações sobre o erro, seu tipo e o estado do programa quando o erro aconteceu.

Depois que o método cria este objeto, ele repassa para o sistema de execução do Java (runtime). Esse processo de criar e repassar este objeto de

erro para o runtime é chamado de levantar uma exceção (throwing an exception).

Quando o runtime recebe este objeto, ele tenta achar algum método

que trate esta exceção. Os possíveis métodos que podem tratar esta exceção deve estar na pilha de execução, isto é, deve ser um método que tenha chamado direta ou indiretamente o método levantou a exceção.

A execução de qualquer programa em Java inicia no main. Dentro do main é feita uma chamada a um método metA que por sua vez chama um método metB que então chama um método metC onde ocorreu um erro. Veja na figura 6.1 estas chamadas.

(54)

54

Informática | Linguagem de Programação I | Volume 02

terminaria e aí a execução iria para o método metA. Este método executaria até que terminasse e então a execução voltasse para o main. Observe que poderia haver mais chamadas de métodos neste processo, isto é, o método metB poderia chamar os métodos metD e metE, antes de terminar e a execução voltar para o método metA.

Figura 6.1:Pilha de execução – seta significa chamada a um método Fonte: Conteudista

(55)

55

Informática | Linguagem de Programação I | Volume 02

Figura 6.2Pilha de execução – retorno (exceptional ou normal) dos métodos Fonte: Conteudista

Se por um acaso, na pilha de execução não houvesse nenhum método que fizesse o tratamento do erro, então o programa terminaria abruptamente. Portanto, sempre é interessante tratar erros nos códigos em Java para que nunca o programa termine de forma excepcional.

(56)

56

Informática | Linguagem de Programação I | Volume 02 Figura 6.3: Captura de tela do Netbeans 6.8: Código referente ao fluxo exibido nas figuras 6.1 e 6.2

Fonte: Conteudista

Algumas considerações a serem feitas sobre o código da figura 6.3: não é necessário que sejam métodos de classe, poderiam ser métodos de objetos e também podem ser utilizadas outros tipos de exceções (não apenas a da classe Exception).

Algumas exceções e erros são levantadas pelas próprias classes do Java (e sua API), como por exemplo, se você fizer uma divisão de dois números e o denominador for zero, então será lançada automaticamente uma exceção aritmética, ou então se você tentar gravar em um arquivo somente para leitura será lançada uma exceção de entrada e saída. Porém, outras exceções são levantadas pelo próprio programador do método, quando detecta uma situação anormal.

(57)

57

Informática | Linguagem de Programação I | Volume 02

programa será encerrado prematuramente com uma mensagem de erro como exibida na figura 6.5.

Figura 6.4Captura de tela do Netbeans 6.8: Exemplo de leitura de valores numéricos Fonte: Conteudista

Na primeira linha em vermelho da figura 6.5 é possível ver que ocorreu uma exceção do tipo InputMismatchException, pois o usuário digitou

a palavra “olá!” quando estava se esperando um número inteiro.

Figura 6.5 Captura de tela do Netbeans 6.8: Execução do programa da figura 6.4 com uma digitação inválida Fonte: Conteudista

(58)

58

Informática | Linguagem de Programação I | Volume 02

try {

// código que pode gerar erros

} catch (TipoDaExcecao nomeDaVariavel) {

// código que será executado se o erro acima

ocorrer

}

A figura 6.6 apresenta o código da figura 6.4 adicionando a cláusula try/catch. Dentro da clásula try é colocado o código que pode gerar algum erro, porém assumindo o fluxo normal do programa, isto é, neste exemplo, é solicitada a digitação de um número inteiro, depois um real e finalmente estes dois números são impressos na tela (linhas 13 a 17). Dentro da clásula catch é colocado o código a ser executado caso aconteça o erro (linha 19) especificado pelo catch (linha 18).

Figura 6.6Captura de tela do Netbeans 6.8: Tratando a exceção InputMismatchException

Fonte: Conteudista

(59)

59

Informática | Linguagem de Programação I | Volume 02

Agora se o usuário digitar um valor inválido não aparecerá mais a mensagem

de erro exibida na figura 6.5, aparecerá a mensagem: “Exceção capturada: ...”

conforme especificada na linha 19 da figura 6.6 e o programa encerrará de forma normal. Veja na figura 6.7 a saída da execução do programa da figura 6.6 onde o usuário digita um valor inválido.

Figura 6.7 Captura de tela do Netbeans 6.8: Execução do programa da figura 6.6 com uma digitação inválida Fonte: Conteudista

Uma outra vantagem em utilizar exceções em no código é porque torna o fluxo do programa bem mais fácil de entender, pois você não precisa ficar colocando um monte de if/else no meio do seu código só para verificar se ocorreu ou não um erro. Observe na figura 6.8 uma nova execução do código da figura 6.6, porém agora o usuário digita um valor inteiro válido e um valor real inválido – o real digitado é inválido, pois foi digitado com ponto (.), ao invés de vírgula (,). Não foi necessário colocar um if/else para a digitação do inteiro e outro if/else para a digitação do número real para testar se os valores foram corretos ou não. Pois, utilizando o tratamento de exceção, quando há um erro em qualquer parte do código da cláusula try, a execução é interrompida naquele ponto (sem executar o resto do código que está dentro da cláusula try), e passa-se a executar o código da cláusula catch correspondente ao erro capturado.

(60)

60

Informática | Linguagem de Programação I | Volume 02 Fonte: Conteudista

O código da figura 6.9 foi baseado no da figura 6.6, porém agora as duas variáveis são inteiras (linha 9) e foi adicionada uma divisão (linha 16). Portanto, é possível ter o problema de divisão por zero dependendo do valor que o usuário digitar.

<Saiba Mais: Quando você estiver utilizando o tipo float ou double, não

haverá um exceção informando que houve uma divisão por zero, pois quando um número for dividido por zero o resultado será Infinity. Se por acaso, houver a tentativa de dividir zero por zero, então o resultado será NaN (abreviação de Not a Number, que significa Não é um Número). Isto é assim, pois como float e double tem representação para estes casos especiais, então nenhuma exceção é levantada.

É preciso ficar atento para estes casos, pois para isto, seria melhor utilizar um if para saber se o divisor é diferente de zero.>

(61)

61

Informática | Linguagem de Programação I | Volume 02

Figura 6.9 Captura de tela do Netbeans 6.8: Utilizando várias cláusulas catch

Fonte: Conteudista

Na figura 6.10 está a saída da execução do programa da figura 6.9, onde o usuário digitou zero para o segundo número. Veja que apareceu o nome completo da exceção (java.lang.ArithmeticException) e o problema que aconteceu (/ by zero).

Figura 6.10 Captura de tela do Netbeans 6.8: Saída do programa 6.9 Fonte: Conteudista

(62)

62

Informática | Linguagem de Programação I | Volume 02

compilador não obriga o programador a tratar este tipo de exceção, pois são as runtime exceptions.

Existem outros tipos de exceções que o compilador obriga que o programador trate ou repasse a exceção. Elas são as chamadas exceções checadas (checked exceptions) e precisam necessariamente estender a

classe Exception (ou uma subclasse dela que não seja subclasse de RuntimeException).

Veja na figura 6.11 a hierarquia de classes relacionadas com tratamento de erros em Java. A classe Throwable é a classe pai de todas os erros e exceções que podem acontecer em Java. A classe Error é a classe pai de todos os erros que podem acontecer, normalmente quando um erro acontece (normalmente relacionado com a máquina virtual Java) o programa é abortado prematuramente e o programador não tem como prever este tipo de problema, portanto não são checados pelo compilador.

A classe Exception é a classe pai de todas as exceções e são sempre checadas pelo compilador, com a exceção da classe RuntimeException e suas subclasses. As exceções do tipo RuntimeException não são checadas, pois normalmente são ocasionadas por erros de programação que poderiam ser evitados, como por exemplo, acessar um ponteiro nulo, ou acessar uma posição inválida de um vetor ou matriz.

Isto é, se o programador escreveu o seu código corretamente, então nunca deveria ocasionar uma exceção do tipo RuntimeException, e por isso o compilador não checa estes tipos de exceções.

(63)

63

Informática | Linguagem de Programação I | Volume 02

Figura 6.11 Parte da hierarquia de exeções em Java Fonte: Conteudista

Portanto, quando você estiver desenvolvendo a sua aplicação, você extenderá a classe Exception para criar as suas próprias exceções.

Voltando ao exemplo da classe Televisao, quando o usuário tentar trocar de canal, ou mudar o volume da televisão com ela desligada uma exceção será levantada. Então, para isto é necessário criar uma classe que estende a classe Exception. Veja na figura 6.12 a classe ExcecaoTelevisaoDesligada. A classe Exception possui um atributo que armazena um mensagem informativa sobre o erro. Portanto, a classe ExcecaoTelevisaoDesligada utiliza o construtor da classe Exception para

incializar este atributo com a mensagem “Televisao desligada” concatenada

com uma informação extra que foi passada para este construtor (linha 5).

Figura 6.12 Captura de tela do Netbeans 6.8: Classe ExcecaoTelevisaoDesligada

(64)

64

Informática | Linguagem de Programação I | Volume 02

Depois de criada a exceção é necessário utilizá-la nos métodos aumentarCanal e diminuirCanal, entre outros.

Veja a nova implementação do método aumentarCanal na figura 6.13. Na linha 73 aparece a informação que este método pode levantar uma exceção chamada ExcecaoTelevisaoDesligada.

O teste é realizado na linha 74 para saber se a televisão está ou não ligada, caso a televisão esteja desligada então uma exceção é levantada

(linha 75). Observe que foi criado um objeto da classe

ExcecaoTelevisaoDesligada passando como parâmetro para o construtor a

frase “ao tentar aumentar o canal” que completa a informação de porque a exceção foi levantada, então a frase completa que estará armazenada será

“Televisão desligada ao tentar aumentar o canal”, e ela será exibida quando o

usuário tentar aumentar o canal com a televisão desligada. Esse objeto que foi criado e que encapsula as informações do erro ocorrido é então levantado (throw) e pode ser visto na linha 75. Preste bem atenção para não confundir o

throws utilizado na linha 73 com o throw da linha 75, o primeiro (com a letra „s‟

no final) é utilizado nas assinaturas dos métodos e são apenas para informar

que o método gera ou repassa aquele erro, enquanto que o throw (sem o „s‟)

é utilizado onde aconteceu o problema e serve para levantar uma exceção.

Figura 6.13 Captura de tela do Netbeans 6.8: Método aumentarCanal levantando uma exceção Fonte: Conteudista

Como o método aumentaCanal faz parte da interface TV, então é necessário alterar a interface TV para que os seus métodos informem que podem levantar a exceção ExcecaoTelevisaoDesligada. Basta adicionar à todos os métodos que levantam esta exceção o seguinte complemento:

(65)

65

Informática | Linguagem de Programação I | Volume 02

Observe na figura 6.14 um main que utiliza uma cláusula try/catch ao utilizar um objeto da classe Televisao. Na linha 8 a televisão é criada, e como padrão, ela é criada desligada. Ela é então ligada (linha 9) tem o seu canal aumentado (linha 10) e o seu volume alterado para 7 (linha 11). A televisão é desligada (linha 12) e há uma tentativa de aumentar o seu canal na linha 13, porém uma exceção é gerada pelo método aumentarCanal e o fluxo é direcionado para o catch da linha 15 e a mensagem da linha 16 é então exibida para o usuário.

Figura 6.14 Captura de tela do Netbeans 6.8: Teste gerando a ExcecaoTelevisaoDesligada

Fonte: Conteudista

Na figura 6.15 é exibida a saída da execução do programa da figura 6.14. Note que a mensagem da linha 14 da figura 6.14 não foi impressa na tela, pois como aconteceu a exceção na linha 13, o fluxo foi execução foi direto para a linha 15 por causa do catch.

(66)

66

Informática | Linguagem de Programação I | Volume 02

Utilizando este tipo de exceção que herda da classe Exception, se você esquecer de informar no método que ele pode levantar aquela exceção, como ela é checada, então o seu programa nem compila.

Como dá mais trabalho utilizar exceções checadas, pois é necessário utilizar try/catch ou escrever os throws nas assinaturas dos métodos para fazer o programa compilar, então muitos programadores se sentem tentados a utilizar a classe RuntimeException ou uma subclasse dela, pois como não são checadas, não é necessário ter tanto trabalho.

Porém, a recomendação é que você não utilize RuntimeException, pois deixam uma falsa ilusão que o seu código não possui métodos que levantam exceções. Quem ler o seu código vai ter a impressão que não são levantadas exceções, pois não tem escrito isto nas assinaturas dos métodos. Uma vantagem de utilizar as exceções checadas é justamente porque o compilador lhe avisa que você esqueceu de uma exceção, então ou você irá tratá-la ou explicitamente dirá que não vai tratar (através do throws na assinatura do método).

Para terminar o assunto de exceções, existe uma outra cláusula que pode ser utilizada com o try/catch que é a finally. Esta cláusula é adicionada ao final de todas as catch que existam e o código que tiver dentro dela sempre será executado, independentemente se houve ou não alguma exceção.

(67)

67

Informática | Linguagem de Programação I | Volume 02

Figura 6.16 Captura de tela do Netbeans 6.8: Utilização da cláusula Finally Fonte: Conteudista

Na figura 6.17 você pode ver a saída da execução do programa da figura 6.16, constatando que foram exibidas as mensagens das linhas 16, 18 e 20 deste programa.

Figura 6.17 Captura de tela do Netbeans 6.8: Saída do programa da figura 6.16 Fonte: Conteudista

Imagine que na linha 11 da figura 6.16 substituíssemos o número “7” pela divisão “7 / 0”, então acontecerá um erro que não foi tratado e por isso o

Imagem

Figura 4.4: Captura de tela do Netbeans 6.8: Selecionando a opção Refatorar  Encapsular campos..
Figura 4.5:Captura de tela do Netbeans 6.8: Caixa de diálogo Encapsular campos  Fonte: Conteudista
Figura 4.8: Captura de tela do Netbeans 6.8: Classe Testes (códigos suprimidos)  Fonte: Conteudista
Figura 4.9: Captura de tela do Netbeans 6.8: Métodos estáticos definirTamanho e trocarCanal  Fonte: Conteudista
+7

Referências

Documentos relacionados

A data de validade é um guia não só para quem consome saber até quando o produto está em condições de ser vendido, é bom para fabricantes - que evitam ter a imagem

“Existe uma imagem dupla de preconceito: nos anos cinquenta era a invisibilidade de não poder dizer que era índio para não sofrer discriminação, razão pela qual muitos se

Quase 70% das mulheres entrevistadas a partir dos 40 anos de idade tiveram um pedido médico para realização de mamografia, e esse percentual foi mais alto entre as que tinham plano

Another objective was to evaluate the level or the occurrence and severity of postoperative sensitivity in the restorations performed using these six respective

Neste panorama, o principal objetivo desse estudo é entender a importância da competitividade de destinos turísticos pontuando quais políticas tem sido adotadas

The efficiency of extraction of phenolic compounds with water was demonstrated once more by the fact that the aqueous extract, under the same conditions of concentration and reaction

Compreendendo- se que o estudo dos eventos do século XX podem ser relevantes e esclarecedores para a compreensão da história e da sociedade de hoje, e levando-se em conta o

1 — As empresas que oferecem redes de comunica- ções públicas ou serviços de comunicações eletrónicas acessíveis ao público são obrigadas a disponibilizar ao público, bem