Вы находитесь на странице: 1из 241

Programao Orientada a Objetos

Prof. Oswaldo Borges Peres


O material aqui exposto fruto do trabalho no s meu, mas principalmente, de muitos professores da Escola de Informtica. Com pequenas excees, eu praticamente juntei e formatei esta apresentao. Agradeo a ajuda de todos os professores que forneceram este material. Sem suas contribuies no seria possvel montar este material a tempo.

Aula 01 Objetivos:
l l l

Conceitos introdutrios de Programao Orientada a Objetos (POO) Criao de Classes Instanciao de objetos

O que uma Classe?


Uma classe um tipo de modelo que define como so os objetos que pertencem a esta classe. como se fosse um projeto que os objetos devem seguir para serem considerados como pertencentes classe. Neste projeto esto definidos as caractersticas (que chamamos de atributos) e os comportamentos que representam as operaes que os objetos dessa classe podem realizar (chamamos a isso de mtodos).

Exemplos de Classes:
Os animais podem ser classificados em classes, tais como mamferos, aves, peixes, etc. Cada uma dessas classes tem suas caractersticas e comportamentos comuns, que poderiam ser relacionados (descritos) como atributos e mtodos dessas classes.

Exemplos de atributos:
Uma classe pessoa, por exemplo, pode ter atributos como nome , endereo, identidade, ou seja, caractersticas (dados) especficas de cada pessoa.

Exemplos de mtodos:
Uma classe peixe pode ter um mtodo nadar, uma classe pessoa pode ter um mtodo andar ou um mtodo falar, pois estes so comportamentos (aes) tpicos destas classes.

O que um objeto?
Como vimos, uma classe uma representao de uma entidade do mundo real. Um objeto uma ocorrncia (chamamos a isso de uma instncia) de uma determinada classe.

Exemplos de objetos:
l

Matheus um objeto da classe pessoa. Thor (o peixinho do Matheus) um objeto da classe peixe.

Outros exemplos de objetos:


Classes
Carro Gol Palio Corsa Joo Maria Carlos Demisso Cadastro Vendas

Objetos

Empregado

Formulrio

Interface, mensagens e encapsulamento


Vamos explorar mais um dos exemplos acima. Como vimos, podemos ter carro como sendo uma classe. As caractersticas ou atributos poderiam ser a cor, o modelo, a potncia do motor e assim sucessivamente. Os comportamentos ou funcionalidades, poderiam ser ligar e desligar, abrir e fechar a porta, acelerar e frear, e outras aes (operaes) que fossem consideradas teis para descrever um carro.

Interface
Os atributos e mtodos da classe carro constituem o que chamamos de interface dessa classe com o mundo externo. Um objeto da classe carro s ser acessvel por outro objeto atravs de seus mtodos, de forma que a interface da classe carro deve definir todos os comportamentos desejveis a um objeto desta classe.

Encapsulamento
O fato dos objetos esconderem sua forma de funcionamento um conceito importante em OO, e est ligado existncia da interface. Somente a classe carro conhece a forma de funcionamento (implementao) de seus mtodos. o que chamamos de encapsulamento . Ou seja, conhecemos as caractersticas e as funcionalidades de um carro, mas no sabemos (nem precisamos saber) quais tcnicas e processos os projetistas utilizaram para a construo do projeto, ou seja para implementar a forma de funcionamento de seus mtodos.

Mensagens
Uma vez que tenhamos definido a interface da classe carro e que tenhamos um objeto dessa classe, como fazer para que ele execute a operao ligar? Devemos enviar uma mensagem para esse carro (ligue!) e ele executar a operao. Ns (externamente ao objeto) que pedimos ao objeto para que execute essa operao, sem precisar saber como o carro faz para ligar (que tipo de algoritmo ele usa para isso). O mesmo ocorre se quisermos saber a cor do carro. Simplesmente perguntamos (qual a sua cor?) e o carro responde (naturalmente precisaramos ter criado um mtodo que respondesse a isso). Onde e como ele armazena a informao da cor no relevante. Apenas sabemos que ele capaz de armazenar seus atributos e inform-los quando necessitarmos deles.

Representao do problema - UML


Para estudarmos a Programao Orientada a Objetos (POO), necessrio que entendamos a Modelagem Orientada a Objetos (MOO). Essa tcnica representa as estruturas atravs de uma linguagem padro, conhecida como UML (Unified Modeling Language), usada para a criao de modelos que representam os problemas do mundo real. A UML classifica os objetos envolvidos no domnio do problema e define as formas como os mesmos se relacionam. No o nosso foco uma abordagem profunda dos conceitos e ferramentas da UML. Utilizaremos apenas os principais elementos da MOO, que so necessrios para dar andamento POO. Para implementao utilizaremos a linguagem Java.

Representao do problema - UML


l

Na UML as classes so representadas na forma de caixas com, no mximo, trs compartimentos. O primeiro deles contm o nome da classe (sempre no singular e com a primeira letra em maisculo), o segundo contm a lista de atributos e o terceiro contm a lista de operaes. Veja a classe carro: A UML (e o Java) sugere que todos os nomes de atributos e mtodos se iniciem com letra minscula. Na classe Carro foram criados trs atributos: dois do tipo String, marca e cor e o terceiro, motorEstado, um booleano que indica se o motor est desligado ou ligado.

Representao do problema - UML


Alm dos atributos da classe, queremos tambm criar mtodos que contenham as operaes que objeto poder realizar. Um carro pode fazer muitas coisas, mas, para manter a simplicidade, vamos criar inicialmente apenas trs mtodos: O primeiro o mtodo ligaMotor, que muda o estado do motor para ligado, isto , para true e depois exibe uma mensagem de aviso. O segundo o mtodo desligaMotor, que muda o estado do motor para desligado, isto , para false e depois exibe uma mensagem de aviso. O terceiro mtodo, mostraAtributos, exibe os valores dos atributos de um objeto ou instncia da classe Carro.

Exemplo:
l

Edite o texto abaixo que contm os atributos e mtodos da classe Carro : public class Carro { String marca; String cor; boolean motorEstado; void ligaMotor() { motorEstado = true; System.out.println("O motor foi ligado."); } void desligaMotor() { motorEstado = false; System.out.println("O motor foi desligado."); } void mostraAtributos() { System.out.println("O carro tem a cor " + cor + "e eh da marca " + marca); if (motorEstado == true) System.out.println("O motor jah estah ligado."); else { System.out.println("O motor estah desligado."); } }

Exemplo(Continuao)
Crie tambm um objeto dessa classe. Em Java podemos fazer isso adicionando o mtodo main classe Carro e nele instanciando efetivamente um objeto da classe Carro (comando new). public static void main (String args[]) { Carro meuCarro = new Carro(); // instancia o objeto meuCarro.marca = "Palio"; // inicia o atributo marca meuCarro.cor = "azul"; // inicia o atributo cor System.out.println("Mostrando os atributos:"); meuCarro.mostraAtributos(); //mensagem para o objeto
l

System.out.println("---------"); System.out.println("Ligando o motor..."); meuCarro.ligaMotor(); //mensagem para ligar o carro System.out.println("Mostrando os atributos:"); meuCarro.mostraAtributos(); System.out.println("---------"); System.out.println("Desligando o motor..."); meuCarro.desligaMotor(); System.out.println("Mostrando os atributos:"); meuCarro.mostraAtributos(); }

Exemplo (Continuao)
l

Salve o texto acima como Carro.java. A seguir, para compilar o cdigo criado, usaremos o compilador javac : abra uma tela de comandos do Windows, v para o diretrio onde foi salvo o arquivo Carro.java e digite: javac Carro.java O programa deve compilar normalmente (se no reconhecer o comando necessrio alterar o path da mquina para incluir o diretrio onde se encontra o compilador javac). Ser gerado um arquivo Carro.class. A seguir, vamos executar o arquivo com o comando: java Carro

Desafios
l l

1. Crie o objeto outroCarro da classe carro com a marca Gol e a cor prata. 2. Insira um novo atributo rotacaoMotor e inicie-o com zero. O mtodo ligaMotor deve atualizar esse atributo para 1000 e o mtodo desligaMotor deve atualiz-lo para zero. 3. Crie um novo mtodo acelerar que some 100 ao valor corrente do atributo rotacaoMotor. Crie tambm o desacelerar, que subtraia 100. 4. A partir do arquivo criado, desmembre-o em dois. O arquivo j existente, de nome Carro, s com a classe Carro sem o mtodo main. E outro arquivo, denominado principal, s com o mtodo main. 5 . Crie uma classe Quadrado que tenha um atributo lado e mtodos para informar a rea e o permetro. Varie a arquitetura

Dicas sobre a instalao do Java


l

O SDK, Software Development Kit O SDK no um ambiente visual de programao. composto apenas de ferramentas que devem ser utilizadas atravs da linha de comando (no Windows, em uma janela DOS). Atualmente chamado de J2SE, Java 2 Standard Edition. Deve ser usado um editor de texto qualquer como o Notepad, mas existem alguns editores que incorporam funes de compilao e execuo como o Textpad, o JCreator ou o BlueJ (todos necessitam do SDK para estas funes). Existem ambientes de desenvolvimento integrados como o NetBeans, o Eclipse, o JBuilder da Borland ou o Visual Caf da Symantec, mas vamos preferir o caminho mais indicado para aprendizagem de JAVA, que utilizar apenas um editor de texto e o SDK.

Dicas sobre a instalao do Java


l

Instalao do SDK (verso 1_5_0_07):

Executar o arquivo jdk-1_5_0_07-windows-i586-p.exe (ou a verso mais atual que estiver disponvel em java.sun.com). Sero instalados, no diretrio que voc escolher, o JAVA 2 SDK (diretrio ..\jdk1.5.0_07), que contm o compilador e o interpretador JAVA, e o JRE (JAVA Runtime Environment), no subdiretrio ..\jre1.5.0_07, que contm o JVM (JAVA Virtual Machine) e o plugin JAVA para os seus navegadores. Descompactar o arquivo \ jdk1.5.0_07\src.zip no prprio diretrio. As ferramentas do SDK devero ser acessadas a partir de qualquer diretrio de trabalho, por isso teremos que adicionar o diretrio bin do SDK ao PATH. No Windows acione o menu propriedades do MeuComputador e, na aba Avanados, escolha o boto Variveis de Ambiente e edite o PATH de variveis do sistema para incluir o diretrio ..\jdk1.5.0_07\bin. Reiniciar o computador.

Dicas sobre a instalao do Java


l

Sobre os Nomes de Arquivos JAVA

Os nomes de arquivos em JAVA so nomes de arquivos extensos, maiores que o padro DOS 8.3 (nome com oito caracteres e extenso com trs), pois a extenso deve ser .java" e o nome do arquivo deve ser o mesmo nome da classe, em geral com mais de oito caracteres. JAVA Case Sensitive, ou seja, diferencia maisculas e minsculas. Devemos ento tomar cuidado ao escrever um nome de arquivo ou de classe JAVA.

Dicas sobre a instalao do Java


Exemplo 2.1: Welcome.java (modificado de: Core Java 2, vol.1, pgina 29) public class Welcome { public static void main (String[] args){ String[] greeting = new String[2]; greeting[0]="Welcome to Core JAVA"; greeting[1]="by Cay Horstmann and Gary Cornell"; int i; for (i = 0; i < greeting.length; i++) System.out.println(greeting[i]); } }
l

Dicas sobre a instalao do Java

Salvar o arquivo com o nome Welcome.java (o programa tem que ter o mesmo nome da classe, escrito da mesma maneira e com extenso .java). Usar a opo Salvar com o tipo: Todos os arquivos (*.*), salvando em um diretrio criado para os exemplos JAVA. Abrir uma janela de comando e executar os seguintes: l cd seudiretorio [ENTER] l javac Welcome.java [ENTER] l java Welcome [ENTER] O programa javac o compilador JAVA. Ele compila o arquivo Welcome.java gerando o arquivo Welcome.class. O programa java o interpretador JAVA. Ele interpreta os bytecodes que o compilador colocou no arquivo classe. Pronto. Se tudo funcionou, seu compilador est bem instalado e estamos prontos pra continuar nossos estudos.

Aula 02 Objetivos:
l l l l

Reforar o conceito de encapsulamento Apresentar mtodos parametrizados Introduzir os nveis de acessibilidade de atributos e mtodos Esclarecer o uso dos construtores

Recordando...
Na aula passada criamos uma classe Carro, na qual havia alguns atributos e mtod os. Na classe que usamos para instanciar e testar um objeto da classe Carro, que chamamos de classe Principal, iniciamos diretamente os atributos do objeto meuCarro, logo aps instanci-lo. Entretanto, esta NO a forma mais adequada de fazer isso. De fato, ao projetarmos uma classe, devemos ter em mente que o conceito de encapsulamento muito importante na POO. Isto significa que os mtodos da classe devem, geralmente, ser os nicos responsveis pelo acesso aos atributos da classe. Isso esconde o modo de funcionamento da classe, privilegiando o uso da interface da classe como forma nica de acesso, o que facilita o teste, a manuteno e a reusabilidade das mesmas.

Uma forma mais adequada


Para evitarmos iniciar os atributos da classe fora da mesma, devemos criar mtodos na prpria classe que faam esse acesso, tanto de escrita quando de leitura, sempre que necessrio. Podemos alterar a classe Carro, introduzindo um mtodo configurarCarro, que seja responsvel pela iniciao dos atributos. Entretanto, como passar os valores que desejamos para os atributos do carro? A resposta : atravs de argumentos no mtodo. Ao enviarmos uma mensagem para um objeto da classe Carro atravs do mtodo configurarCarro, devemos especificar os valores desejados para o carro (que chamamos de parmetros correspondentes aos argumentos). Ou seja, o mtodo configurarCarro deve estar apto a receber esses parmetros como argumentos e atribu-los aos atributos do carro (por vezes os termos parmetros e argumentos so usados indiferentemente, mas argumentos so tipos formais e parmetros so valores reais).

Uma forma mais adequada(Cont...)


O cdigo a seguir prepara o mtodo configurarCarro para receber os argumentos desejados para a classe Carro: void configurarCarro(String m, String c, boolean e) { marca = m; cor = c; motorEstado = e; } Na classe Principal, para realizar a chamada do mtodo, agora devemos passar os parmetros adequados aos argumentos, da seguinte forma: meuCarro.configurarCarro("Palio","azul",false); Edite, compile e teste o funcionamento da alterao do cdigo.

Uma forma mais adequada(Cont...)


Na parte de Desafios da aula 1 foram criados o atributo rotacaoMotor e os mtodos acelerar e desacelerar. Estes mtodos tambm podem ser reescritos para receber como parmetros os valores a serem somados ou subtrados do atributo rotacaoMotor. A incluso do atributo fica assim: int rotacaoMotor; O cdigo dos mtodos acelerar e desacelerar fica assim: void acelerar(int parcela) { rotacaoMotor += 100; System.out.println(Motor foi acelerado para "+ rotacaoMotor+RPM."); } void desacelerar(int parcela) { rotacaoMotor -= 100; System.out.println(Motor foi desacelerado para "+rotacaoMotor+"RPM."); } E as chamadas dos mtodos na classe principal ficam assim: System.out.println("---------"); System.out.println("Acelerando o motor..."); meuCarro.acelerar(100); System.out.println("---------"); System.out.println("Desacelerando o motor..."); meuCarro.desacelerar(100); Edite, compile e teste o funcionamento da alterao do cdigo.

Definindo a acessibilidade (Visibilidade)


De fato, a correo feita no cdigo da classe Carro foi positiva, mas no impede o uso indevido dos atributos por uma classe externa. Para tanto, devemos utilizar o recurso de definir a acessibilidade do elemento (classe, atributo ou mtodo). Fazemos isso, em Java, usando as palavras reservadas public, private, package e protected na declarao. Os atributos e mtodos public constituem a interface da classe e so acessveis a qualquer mtodo de qualquer classe externa. Os atributos e mtodos private so de acesso exclusivo dos mtodos da classe. Os de acessibilidade protected so passveis de acesso por mtodos de classes que herdem da classe que os definiu (trabalharemos esse conceito mais adiante). O nvel package, que assumido como padro quando nenhum nvel de acessibilidade explicitamente definido (o que o caso do nosso exemplo da aula passada), define o atributo ou mtodo como acessvel para qualquer mtodo de classe dentro do mesmo pacote (este conceito tambm

Definindo a acessibilidade (Visibilidade)


No nosso caso, desejamos restringir o acesso aos atributos da classe Carro. Para tanto, vamos defini-los como private. Altere assim o cdigo: private String marca; private String cor; private boolean motorEstado; private int rotacaoMotor; Agora tente acessar os atributos como feito na aula passada...Pois , a linguagem impede o acesso dessa forma, pois ela passou a ser errada.

Mais sobre parametrizao set e get


Alm de passarmos parmetros para os mtodos de uma classe durante uma mensagem, podemos tambm receber dados dos mtodos chamados. Uma forma de faz-lo definir um valor de retorno para um mtodo chamado. Os campos private de uma classe s podem ser manipulados por mtodos dessa classe. Qualquer objeto de outra classe (um cliente, portanto), que deseje acessar um campo private da classe servidora, deve chamar os mtodos public que a esta oferea para manipular seus campos private. As classes costumam oferecer mtodos public para permitir aos clientes da classe configurar (set - atribuir) ou obter (get - obter) valores das variveis private. Os nomes desses mtodos no precisam comear com set ou get, mas essa conveno de atribuio de nomes altamente recomendada em Java. Por exemplo, podemos criar um mtodo getRotacaoMotor que retorne o valor do atributo rotacaoMotor. Assim: int getRotacaoMotor () { return rotacaoMotor;

Mais sobre parametrizao set e get (Cont...)


Para chamarmos o mtodo, poderamos usar este cdigo: System.out.println("Rotacao do motor = " + meuCarro. getRotacaoMotor () + " RPM."); Da mesma forma, caso quisssemos criar um mtodo setRotacaoMotor que configurasse o valor do atributo rotacaoMotor, ele seria assim: int setRotacaoMotor (int r) { rotacaoMotor = r; } e a atribuio de uma valor rotao teria, portanto, a seguinte sintaxe: meuCarro.setRotacaoMotor (1000)

Criando objetos com o uso de construtores


A criao do mtodo configurarCarro foi uma boa idia para melhorar o encapsulamento da classe. Entretanto, ainda no a melhor forma de iniciar os valores dos atributos. Melhor seria utilizarmos um mtodo especial, que chamamos Construtor. O construtor de uma classe um mtodo automaticamente chamado quando instanciamos um objeto dessa classe. Em Java, o mtodo construtor tem o mesmo nome da classe e chamado quando usamos o comando new. Reparando bem, no exemplo da classe carro temos: new Carro(); o que sugere que estamos chamando um mtodo chamado Carro (o uso dos parntesis um indicativo disso). Entretanto onde est este mtodo que no foi declarado? A resposta que a linguagem pressupe que toda classe tem um construtor padro (default), que no possui argumentos e inicia os atributos numricos com zero e os atributos lgicos com false. Entretanto, podemos definir explicitamente o construtor da classe, fazendo com que ele seja responsvel pela iniciao de atributos da classe com valores distintos dos valores padro. Assim, podemos ter: public Carro () { marca = "Palio"; cor = "azul"; motorEstado = true; rotacaoMotor = 1000; }

Criando objetos com o uso de construtores(Cont...)


Bem, o construtor um mtodo como os demais e, portanto, tambm pode receber argumentos. Assim, poderamos melhorar o nosso construtor permitindo que recebesse como parmetros os valores a serem postos inicialmente em alguns atributos. Um cdigo possvel seria: public Carro (String m, String c) { marca = m; cor = c; motorEstado = true; rotacaoMotor = 1000; } Uma classe pode possuir mais de um construtor. Eles devem ter o mesmo nome e diferenciar-se apenas pelo nmero de argumentos que recebem. Isto chamado de sobrecarga de construtor (veremos o assunto sobrecarga de mtodos, em detalhes, mais frente). Desta forma, podemos ter diferentes construtores, permitindo flexibilizar a criao e a iniciao dos atributos dos objetos em diferentes situaes que se faam necessrias.

Desafios
l l

l l

Crie mtodos set e get para todos os atributos private da classe Carro. Crie um novo construtor que receba tambm o estado em que o motor deve ser iniciado e inicie a rotao de acordo com o estado passado como argumento: 0 (para motor desligado) ou 1000 (para motor ligado). Para a classe Quadrado, criada no desafio da aula passada, crie tambm mtodos get e set para o atributo lado. Crie uma classe Livro, que possua atributos para nome, autor, edio, editora e ano de publicao. Os atributos devem ser privados e devem possuir mtodos de acesso. Deve haver um mtodo que imprime os atributos correntes do livro. Deve haver um construtor padro que inicia os atributos com o valor desconhecido e a seguir imprime uma mensagem de saudao com os atributos correntes. Deve haver construtores alternativos para instanciar os objetos da classe Livro com os respectivos parmetros correspondentes aos atributos. Adicionalmente, crie um programa principal que instancie diferentes livros chamando os diferentes construtores e os mtodos get e set dos atributos que se fizerem necessrios.

Aula 03: Objetivos


l l l l

Introduzir o conceito de herana Criar uma hierarquia de classes Detalhar o funcionamento da herana Rever o uso dos modificadores de acesso

Recordando...
Nas aulas passadas criamos uma classe Carro, que apresentava alguns atributos (cor, marca, motorEstado) e alguns mtodos (acelerar, desacelerar, etc). Se quisssemos criar uma outra classe Caminhao, certamente vrias caractersticas, tanto atributos como comportamentos (mtodos), seriam parecidos ou mesmo iguais aos da classe Carro. Caso semelhante ocorreria se quisssemos criar um carro eltrico. Nestas situaes, ao invs de criarmos uma srie de classes, desvinculadas umas das outras, mas com vrias coisas em comum, a MOO utiliza um conceito que permite criar uma relao entre as classes.

Herana
O conceito de herana permite estabelecer uma hierarquia entre as classes. um mecanismo que permite a uma classe herdar as operaes e os atributos de outra classe. Com o uso da herana, quando se escreve uma classe necessrio especificar apenas no que ela diferente da classe-me, classe-base ou superclasse. O mecanismo da herana d acesso automtico s informaes contidas na classe base. Atravs da herana, uma classe possui imediatamente toda a funcionalidade de uma classe j existente. A classe que herda caractersticas da outra chamada subclasse ou classe-filha e a classe que fornece a herana chamada superclasse ou classe-me. A herana , portanto, o compartilhamento de atributos e operaes entre classes, baseado em um relacionamento hierrquico do tipo pai-filho (ou me-filho), em que a classe pai possui definies que podem ser utilizadas nas classes filhas. Estas funcionam como uma especializao da classe pai (as filhas estendem a sua utilizao bsica da classe pai para outras utilizaes mais especializadas).

Herana
A seguir uma figura ilustrativa do conceito de herana:

Herana
Uma superclasse direta a superclasse a partir da qual a subclasse herda explicitamente. Uma superclasse indireta qualquer superclasse acima da superclasse direta. Desta forma, no exemplo acima, Mamifero e uma superclasse direta de SerHumano e Animal uma superclasse indireta de SerHumano.

Herana em Java
Todas as classes, tanto as que so escritas pelo programador quanto aquelas da biblioteca de classes do Java, so organizadas em uma hierarquia. No topo da hierarquia de classes est a classe Object. Todas as classes so herdeiras desta superclasse. Object a classe mais geral da hierarquia, ela define o comportamento herdado por todas as classes da hierarquia de classes do Java. Em Java, uma classe pode ter apenas uma superclasse (Java no suporta herana mltipla, como a existente em C++, por exemplo), mas cada classe pode ter um nmero ilimitado de subclasses. Se a superclasse tiver comportamentos e atributos que sua classe precisa, voc no precisa redefini-la ou copiar esse cdigo para ter o mesmo comportamento e atributos. Sua classe recebe automaticamente as caractersticas de sua superclasse. Essa superclasse tambm recebe da sua superclasse e assim por diante, formando uma cadeia at o inicio da hierarquia. Sua classe , portanto, uma combinao de todos os recursos das classes que esto acima dela na hierarquia, assim como de seus prprios recursos.

Herana em Java
Em Java, indicamos que uma classe herda caractersticas de outra atravs da palavra reservada extends. O cdigo abaixo ilustra isso:
public class Animal { ... } public class Mamifero extends Animal { ... }

Herana em Java
Voltemos ao exemplo da classe Carro. Poderamos criar um projeto mais completo, com uma classe mais geral chamada Veculo. A figura ao lado ilustra como poderamos estruturar o projeto. Na classe Veculo definiramos apenas caractersticas ou operaes comuns a qualquer subclasse, tais como: cor, marca, etc. Abaixo da classe Veculo, as subclasses Carro e Caminho teriam atributos e operaes especficos de cada uma. Utilizando a herana possvel definir uma caracterstica ou uma operao apenas uma vez na hierarquia. A partir da ela reutilizada automaticamente por cada subclasse.

Herana em Java
Quando se cria uma nova instncia de uma classe, criado um espao para cada atributo definido na classe corrente e nas superclasses. Os mtodos funcionam de modo semelhante: os novos objetos tm acesso a todos os nomes de mtodos de sua classe e de suas superclasses. Isso determinado dinamicamente, quando um mtodo utilizado em um programa que est em execuo. Ao chamar um mtodo de um objeto em particular, o interpretador Java procurar primeiramente na classe do objeto por esse mtodo. Se o mtodo no for encontrado, o interpretador procurar na superclasse dessa classe e assim por diante, at que a definio do mtodo seja encontrada

Herana em Java
Suponhamos, por exemplo, que tenha sido declarada a seguinte classe:
class poligono{ int cx, cy; // coordenadas do centro do polgono }

Agora suponhamos que pretendamos criar uma classe que tenha as dimenses do quadrado, alm das coordenadas do centro. Basta fazer:
class Quadrado extends Polgono { int lado; // Comprimento do lado do quadrado }

Herana em Java
A classe Quadrado uma classe derivada da classe Polgono, da qual herda todos os dados e os mtodos nela contidos. Um problema com herana que uma subclasse pode herdar mtodos que ela no necessita ou que no deveria ter. Mesmo quando um mtodo adequado a uma subclasse, essa subclasse precisa freqentemente de uma verso personalizada de mtodo. Nesses casos, a subclasse pode sobrescrever (redefinir) o mtodo da superclasse com uma implementao mais adequada. Observaes sobre acessibilidade na estrutura de herana: l Todos os membros de superclasse public e protected mantm seu modificador de acesso quando se tornam membros da subclasse. l Os mtodos de subclasse podem referir-se a membros public e protected herdados da superclasse simplesmente utilizando os nomes dos membros. Quando um mtodo de subclasse sobrescrever um mtodo de superclasse, o mtodo da superclasse pode ser acessado a partir da subclasse precedendo o nome do mtodo da superclasse com a palavra-

Herana em Java
Para observarmos um relacionamento entre superclasse e subclasse, utilizaremos uma hierarquia de herana que contm tipos de empregados em um aplicativo de folha de pagamento. Na empresa, os empregados comissionados recebem apenas uma porcentagem (comisso) de suas vendas, enquanto que os empregados fixos comissionados recebem um salrio base mais a comisso.

Herana em Java
Vamos inicialmente criar a superclasse EmpComissionado em um arquivo de mesmo nome da classe, portanto, EmpComissionado.java. //Classe Empregado Comissionado public class EmpComissionado extends Object { protected String nome; protected String sobrenome; protected String cpf; protected double totalVendas; protected double taxaComissao; // Construtor com 5 argumentos public EmpComissionado (String n, String sn, String cic, double vendas,double comissao){ nome = n; sobrenome = sn; cpf = cic; setTotalVendas (vendas); setTaxaComissao (comissao); }

Herana em Java
public void setNome (String n){ nome = n; } public String getNome() { return nome; } public void setSobrenome (String sn){ sobrenome = sn; } public String getSobrenome() { return sobrenome; } public void setCpf (String cic){ cpf = cic; } public String getCpf() { return cpf; }

Herana em Java
public void setTotalVendas (double vendas){ totalVendas = (vendas < 0.0) ? 0.0 : vendas; } public double getTotalVendas () { return totalVendas; } public void setTaxaComissao (double tx){ taxaComissao = (tx < 0.0) ? 0.0 : tx; } public double getTaxaComissao () { return taxaComissao; } public double salario(){ // Calcula o salrio return taxaComissao * totalVendas; }

Herana em Java
public String toString () { return String.format ( "%s%s %s\n%s%s\n%s%.2f\n%s%.2f\n%s%.2f", "Identificacao do empregado: ", nome, sobrenome, "CPF: ", cpf, "Total de Vendas: ", totalVendas, "Taxa de Comisso: ", taxaComissao, "Salario Total: ", salario() ); } } // fim da classe Empregado Comissionado

Herana em Java
A seguir vamos, criar a subclasse EmpFixoComissionado , que herda todos os atributos e mtodos da superclasse EmpComissionado. Observe que a subclasse chama alguns mtodos da superclasse, a comear pelo prprio construtor desta (lembre-se de colocar o cdigo abaixo em um outro arquivo com o mesmo nome da classe). //Classe Empregado com salrio base mais Comisso public class EmpFixoComissionado extends EmpComissionado { private double salarioBase; // atributo exclusivo public EmpFixoComissionado ( //constructor da classe String n, String sn, String cic, double vendas, double comissao, double salBase){ // chama construtor da superclasse super (n, sn, cic, vendas, comissao); // chamada a mtodo da prpria classe setSalarioBase (salBase); }

Herana em Java
public void setSalarioBase (double salBase){ salarioBase = (salBase < 0.0) ? 0.0 : salBase; } public double getSalarioBase() { return salarioBase; } public double salario(){ // Calcula o salrio return salarioBase + super.salario(); } // Retorna as informaes public String toString () { return String.format ("%s \nSalario Base: %.2f", super.toString(), salarioBase); } } // fim da classe Empregado Fixo Comissionado

Herana em Java
Finalmente, vamos fazer uma aplicao que use as classes criadas (edite essa aplicao de teste em um terceiro arquivo, que deve se chamar Principal.java): // Testando a classe Empregado fixo com comisso public class Principal{ // Mtodo main public static void main ( String argv[]) { // Instancia objeto da classe EmpFixoComissionado EmpFixoComissionado empregado = new EmpFixoComissionado ("Roberto", "Silveira", "123456789-10", 20000, 0.02, 300); // obtm os dados do empregado System.out.println ("Dados do empregado: \n"); System.out.printf ("%s %s\n", "Nome: ", empregado.getNome() ); System.out.printf ("%s %s\n", "Sobrenome: ", empregado.getSobrenome() ); System.out.printf ("%s %s\n", "CPF: ", empregado.getCpf() ); System.out.printf ("%s %.2f\n", "Vendas: ", empregado.getVendas() ); System.out.printf ("%s %.2f\n", "Comissao: ", empregado.getTaxaComissao() ); System.out.printf ("%s %.2f\n", "Salario total: ", empregado.salario() ); System.out.printf ("%s %.2f\n", "Salario base: ", empregado.getSalarioBase() ); System.out.printf ("\n%s: \n\n%s\n", "As mesmas informacoes do empregado via toString", empregado.toString() ); } // fim do mtodo main

Desafios
1.

2. 3.

Altere o moderador de acesso do mtodo salario() da classe EmpComissionado de public para private e compile este arquivo. A seguir compile o arquivo com a classe EmpFixoComissionado . Explique o erro de compilao. Na classe de teste, crie um objeto da classe EmpComissionado e teste-o Crie um atributo bonus que represente um percentual a ser acrescido ao salrio. Este bonus se aplica a todos os empregados mas deve ser contado em dobro para os empregados comissionados. Faa as alteraes nos mtodos que julgar necessrias para realizar o novo clculo.

Aula 04: Objetivos


l l l l l

Compreender tipos estticos e dinmicos Definir o conceito de polimorfismo de mtodo Apresentar classes e mtodos abstratos Esclarecer o uso do operador this Apresentar classes e mtodos final

Recordando...
Na aula passada, empregando o conceito de herana, criamos uma subclasse EmpFixoComissionado que herda atributos e mtodos de uma superclasse EmpComissionado. Quando fizemos um mtodo para calcular o salrio em cada uma dessas classes, utilizamos a tcnica de escrever o mtodo salrio() na superclasse e sobrescreve-lo na subclasse. Assim, ao chamarmos salrio(), vimos que o mtodo efetivamente chamado era o primeiro encontrado de baixo para cima (da subclasse para a superclasse). Isto ocorreu porque a resoluo de qual mtodo chamar dinmica (depende do tipo do objeto efetivamente instanciado), independentemente do tipo esttico da varivel. Isto no ficou claro na aula passado porque os objetos tinham tipos estticos e tipos dinmicos iguais. Vejamos a seguir como poderia ser diferente.

Tipagem esttica x dinmica


De fato, de forma diferente do que vimos, poderamos ter uma varivel declarada como sendo de um determinado tipo esttico (classe), mas efetivamente sendo instanciada como um objeto de uma subclasse. Por exemplo, poderamos ter:
EmpComissionado empregado = new EmpFixoComissionado(Ana","Silva","123456789-10",20000,0.02,300);

Note que, neste caso, o tipo esttico da varivel empregado o da superclasse EmpComissionado, mas o objeto efetivamente instanciado de fato da subclasse EmpFixoComissionado. Aps esse comando, se o mtodo salrio() for chamado, o mtodo acionado ser o da subclasse. Essa caracterstica chamada Polimorfismo de Mtodo, mas s possvel determinar isso dinamicamente (em tempo de execuo), aps sabermos de qual classe o objeto foi efetivamente instanciado.

Classes e mtodos abstratos

Ainda no exemplo da aula passada, o que fizemos foi criar dua classes utilizando o conceito de herana e colocar na superclasse que era comum s duas classes. Entretanto, cabe observar que er previsto haver empregados (objetos, portanto) de ambas as classe (EmpComissionado e EmpFixoComissionado). Existem situaes em que classes possuem um conjunto d caractersticas comuns que, entretanto, no suficiente para qu com ele seja possvel definir objetos reais. Esse conjunto d caractersticas comuns ento separado em uma superclass destinada apenas a definir o que comum s subclasses del derivadas, sem que se tenha a inteno de efetivamente instancia objetos dessa classe. Tal classe conhecida como Class Abstrata.

Classes e mtodos abstratos


Para o projeto da aula anterior poderamos ter criado a estrutura ao lado, onde Empregado fosse uma classe reservada para conter as caractersticas comuns a todos os empregados. Essa classe, entretanto, no possuiria todos os dados necessrios para definir um empregado real, o que implica em que no haver nenhum objeto real dessa classe, caracterizando-a

Classes e mtodos abstratos


Essa classe deve conter apenas atributos que sejam comuns a todos os empregados, como nome, sobrenome e CPF. Nas classes derivadas que aparecero atributos relacionados forma de contratao e que influenciam a remunerao dos empregados, tais como total de vendas, bnus, horas trabalhadas , salrio base, etc. Nesse contexto, para que possamos utilizar corretamente o polimorfismo de mtodo no clculo do salrio, devemos definir um mtodo abstrato salrio() na superclasse Empregado. Tal mtodo no deve possuir efetivamente nenhuma implementao, pois no sequer possvel calcular o salrio nessa classe. O cdigo efetivo de implementao do mtodo salrio() deve ser deixado a cargo das subclasses, que possuem as informaes necessrias para realizar o clculo do salrio. Esse mtodo da superclasse Empregado chamado de Mtodo Abstrato e sua sobreposio nas subclasses permite o Polimorfismo de Mtodo.

Classes e mtodos abstratos


Na aula passada, quando implementamos diferentes verses para o mtodo construtor de uma classe, fizemos uma Sobrecarga de Mtodo. De fato podemos fazer isto com qualquer mtodo da classe. Como visto no caso do construtor, o que diferencia essas implementaes e permite linguagem determinar qual implementao efetivamente chamar a quantidade de argumentos definidos em cada uma e a quantidade de parmetros passados na chamada do referido mtodo. No exemplo de hoje, que ser uma adaptao do exemplo da aula passada, faremos uma sobrecarga do mtodo salario na classe EmpAssalariado, de forma a permitir dois clculos diferentes para o salrio, um com um abono (passado como parmetro) e outro sem abono.

Operador this
Novamente recordando a aula passada, quando criamos os mtodos parametrizados, declaramos os argumentos com nomes parecidos com os atributos da classe. Fazendo dessa forma, ficou claro que o argumento uma varivel e o atributo outra, como, por exemplo, em: public EmpComissionado (String n, String sn, String cic, double vendas,double comissao){ nome = n; sobrenome = sn; cpf = cic; setTotalVendas (vendas); setTaxaComissao (comissao); }

Operador this
No construtor acima estamos lidando com dez variveis (cinco argumentos do mtodo e cinco atributos da classe). Esta forma, entretanto, no favorece a compreenso, na medida que alguns nomes de argumentos so bastante esclarecedores do seu contedo e criar um sinnimo pode ser indesejvel. Porem, razes sintticas nos fizeram utilizar os sinnimos, pois se o argumento sn, por exemplo, fosse chamado sobrenome, teramos o comando de atribuio: sobrenome = sobrenome; que no seria corretamente compreendido pelo compilador. Neste caso estamos diante de uma sobrecarga de nome e o compilador resolve isso escolhendo a referncia mais prxima (a que foi definida por ltimo). Portanto, a varivel sobrenome referenciada nesse comando no seria o atributo da classe e sim o argumento do mtodo (o ltimo definido).

Operador this
Soluciona-se isso usando o operador this, que faz referncia ao objeto atual (objeto corrente ao tempo da execuo). Assim o trecho de programa anterior poderia ser mais elegantemente definido assim: public EmpComissionado (String nome, String sobrenome, String cpf, double totalVendas,double taxaComissao){ this.nome = nome; this.sobrenome = sobrenome; this.cpf = cpf; setTotalVendas (totalVendas); setTaxaComissao (taxaComissao); } O mesmo se aplica aos demais mtodos, como, por exemplo, aos mtodos set dos atributos das classes.

Classes e mtodos final


Podem ocorrer situaes em que no seja desejvel permitir que eventuais subclasses sobrescrevam mtodos de uma superclasse. Nestes casos devemos impedir a redefinio do mtodo atravs do uso de uma palavra reservada na declarao do mesmo. As declaraes de mtodos precedidas pela palavra reservada final no podem ser sobrescritas em subclasses. Os mtodos declarados como private so implicitamente final porque impossvel sobrescrev-los em uma subclasse. Como as implementaes dos mtodos final no podem mudar, todas as subclasses utilizam a mesma implementao do mtodo, e as chamadas a mtodos final so resolvidas em tempo de compilao, o que conhecido como vinculao esttica. Uma classe declarada como final no pode ser superclasse, ou seja, nenhuma classe pode herdar de uma classe declarada como final . Tornar uma classe final pode ser necessrio, por exemplo, para atender a requisitos de segurana, impedindo que programadores criem subclasses que poderiam driblar restries de segurana. J atributos declarados como final se comportam como constantes e devem ser iniciados na declarao ou no construtor da classe, no

Classes e mtodos final


Exemplos: private final int fator = 2; // atributo final protected final void abrir(); // metodo final public class conta { // classe final ... }

Revendo a aplicao
Para consolidar os conceitos de classe abstrata, mtodo abstrato, sobrecarga de mtodo, polimorfismo de mtodo, operador this e operador final, vamos alterar a aplicao que fizemos na aula passada para o cdigo que se segue. Primeiramente, vamos adicionar a classe abstrata Empregado, que possui apenas trs atributos (nome, sobrenome e cpf). Essa classe impede que classes derivadas alterem os mtodos set desses atributos (uso do final) e usa sobrecarga de nomes para receber argumentos no construtor com os mesmos nomes dos atributos (uso do this):

Revendo a aplicao
//Classe Empregado public abstract class Empregado extends Object { protected String nome; protected String sobrenome; protected String cpf; public Empregado (// Construtor com 3 argumentos String nome, String sobrenome, String cpf){ this.nome = nome; // uso do operador this this.sobrenome = sobrenome; this.cpf = cpf; } public final void setNome (String nome){//usa final this.nome = nome; } public String getNome() { return nome; }

Revendo a aplicao
public final void setSobrenome (String sobrenome){ this.sobrenome = sobrenome; } public String getSobrenome() { return sobrenome; } public final void setCpf (String cpf){ this.cpf = cpf; } public String getCpf() { return cpf; } public abstract double salario(); // Mtodo abstrato } // fim da classe Empregado

Revendo a aplicao
A seguir vamos reescrever a classe EmpComissionado para herdar da classe abstrata Empregado, fazendo as adaptaes necessrias no construtor. //Classe Empregado Comissionado public class EmpComissionado extends Empregado { protected double totalVendas; protected double taxaComissao; protected double bonus; public EmpComissionado (String nome, String sobrenome, String cpf, double totalVendas, double taxaComissao, double bonus){ // chama construtor da classe abstrata super (nome, sobrenome, cpf); setTotalVendas (totalVendas); setTaxaComissao (taxaComissao); setBonus(bonus); }

Revendo a aplicao
public void setTotalVendas (double totalVendas){ this.totalVendas = (totalVendas < 0.0) ? 0.0 : totalVendas; } public double getTotalVendas () { return totalVendas; } public void setTaxaComissao (double taxaComissao){ this.taxaComissao = (taxaComissao < 0.0) ? 0.0 : taxaComissao; } public double getTaxaComissao () { return taxaComissao; } public void setBonus (double bonus){ this.bonus = (bonus < 0.0) ? 0.0 : bonus; }

Revendo a aplicao
public double getBonus (){ return bonus; } public double salario(){ // Calcula o salrio return (taxaComissao * totalVendas + getBonus() * 2 * taxaComissao * totalVendas); } public String toString () { return String.format ( "%s%s %s\n%s%s\n%s%.2f\n%s%.2f\n%s%.2f", "Identificacao: ", nome, sobrenome, "CPF: ", cpf, "Total de vendas: ", totalVendas, "Taxa de comisso: ", taxaComissao, "Salario total: ", salario() ); } } // fim da classe Empregado Comissionado

Revendo a aplicao
A classe EmpFixoComissionado continua herdando da classe EmpComissionado. S sofreu alterao nos mtodos toString() e salario() que agora contemplam o proposto no desafio da aula passada: //Classe Empregado com salrio base mais Comisso public class EmpFixoComissionado extends EmpComissionado { private double salarioBase; // atributo exclusivo // Construtor com 7 argumentos public EmpFixoComissionado ( String nome, String sobrenome, String cpf, double totalVendas, double taxaComissao, double salarioBase, double bonus){ // chama construtor da superclasse EmpComissionado super (nome, sobrenome, cpf, totalVendas, taxaComissao,bonus); // inicia atributo prprio da classe setSalarioBase (salarioBase); }

Revendo a aplicao
public void setSalarioBase (double salarioBase){ this.salarioBase = (salarioBase < 0.0) ? 0.0 : salarioBase; } public double getSalarioBase() { return salarioBase; } public double salario(){ // Calcula o salrio return (salarioBase + taxaComissao * totalVendas + getBonus() * taxaComissao * totalVendas); } public String toString () { return String.format ("%s%s %s\n%s%s\n%s%.2f \n%s%.2f\n%s%.2f\n%s%.2f", "Identificacao: ", nome, sobrenome, "CPF: ", cpf, "Total de vendas: ", totalVendas, "Taxa de comisso: ", taxaComissao, "Salario base: ", salarioBase, "Salario total: ", salario() ); } } // fim da classe Empregado Fixo Comissionado

Revendo a aplicao
A nova classe EmpAssalariado herda diretamente da classe abstrata: //Classe Empregado Assalariado public class EmpAssalariado extends Empregado { private double salarioMensal; // atributo exclusivo // Construtor com 4 argumentos public EmpAssalariado (String nome, String sobrenome, String cpf, double salarioMensal){ // chama construtor da classe abstrata super (nome, sobrenome, cpf); setSalarioMensal(salarioMensal); } public void setSalarioMensal (double salarioMensal){ this.salarioMensal = salarioMensal; } public double getSalarioMensal(){ return salarioMensal;

Revendo a aplicao
public double salario(){ // Salrio sem abono return (getSalarioMensal()); } public double salario(double abono){ //sal. c/ abono return (getSalarioMensal()); } public String toString () { return String.format ( "%s%s %s\n%s%s\n%s%.2f\n%s%.2f\n", "Identificacao: ", nome, sobrenome, "CPF: ", cpf, "Salario total: ", salario(), "Salario total com abono: ", salario(100.0)); } } // fim da classe Empregado Assalariado

Revendo a aplicao
Finalmente, o cdigo de teste (classe Principal) fica como se segue (agora s est imprimindo chamando o mtodo toString das classes): public class Principal{ public static void main ( String argv[]) { EmpFixoComissionado empregadoFC = new EmpFixoComissionado ("Roberto", "Silveira", "123456789-10", 10000, 0.02, 300, 0.01); EmpComissionado empregadoC = new EmpComissionado ("Francisco", "Oliveira", "987654321-00", 20000, 0.02, 0.01); EmpAssalariado empregadoA = new EmpAssalariado ("Joaquim", "Alberto", "192837465-99", 1000); System.out.printf ("\n%s: \n\n%s\n\n", "Informacoes do empregado comissionado:", empregadoC.toString() );

Revendo a aplicao
System.out.printf ("\n%s: \n\n%s\n\n", "Informacoes do empregado fixo comissionado:", empregadoFC.toString() ); System.out.printf ("\n%s: \n\n%s\n\n", "Informacoes do empregado assalariado:", empregadoA.toString() ); } // fim do mtodo main } // fim da classe Principal

Compile e execute o cdigo acima.

Desafios
1.

2.

3.

Altere o cdigo da classe de teste (Principal ) para que o empregado assalariado (objeto empregadoA) seja declarado como da classe esttica Empregado mas continue sendo instanciado como da classe EmpAssalariado. Execute e veja que funciona perfeitamente o polimorfismo de mtodos. Agora tente alterar tambm a classe de instanciao do objeto empregadoA para Empregado. Compile e explique a ocorrncia de erro. Atendendo ao diagrama de classes da pgina dois desta aula, implemente tambm a classe EmpHorista. Crie os mtodos e atributos que julgar necessrios para que os objetos desta classe tenham um comportamento semelhante aos objetos das demais classes do projeto. Altere a classe Principal para que esta instancie e teste tambm um objeto empregadoHorista, imprimindo suas informaes, inclusive seu salrio, que deve ser calculado com base em um valor constante (use um atributo final ) representativo do valor da hora trabalhada, multiplicado pelo nmero de horas trabalhadas (um atributo exclusivo desta classe).

Aula 05 - Objetivos
l l l l

Reforar o conceito de polimorfismo de mtodo Criar arrays de objetos Trabalhar com vinculao dinmica Aprender a utilizar polimorfismo de interface

Recordando...
Na aula passada, empregando o conceito de herana, criamos uma superclasse abstrata Empregado, da qual derivavam trs subclasses EmpComissionado, EmpAssalariado e EmpHorista (esta ltima, no desafio). Vimos como declarar um objeto como sendo estaticamente de uma superclasse, mas instanci-lo dinamicamente de uma subclasse. Hoje vamos criar uma array de objetos distintos usando a tcnica de herana e tratar seus mtodos de forma polimrfica.

Declarando um array de empregados


Vejamos, primeiramente, a declarao para criar um array de quatro empregados (veja que foi usada a superclasse abstrata Empregado): Empregado empregados[] = new Empregado[4]; Entretanto, a superclasse abstrata e cada instanciao de objeto tem que ser de uma das subclasses no abstratas, como no exemplo abaixo: empregados[2] = new EmpAssalariado ("Joaquim", "Alberto","192837465-99", 1000); Para fazermos referncia ao mtodo salrio, que foi sobreposto em cada uma das subclasses, podemos usar o polimorfismo de mtodo: empregados[i].salario(); Entretanto, quando formos fazer referncia a um mtodo da classe derivada que alm de ter sido sobreposto (reescrito na subclasse) foi tambm sobrecarregado (foram criadas diferentes verses na subclasse passando diferentes quantidades de parmetros), ser necessria uma referncia explicita subclasse, para que o compilador possa fazer a resoluo da referncia esttica. Faremos isso atravs de um mecanismo chamado coero explcita (casting). Com este mecanismo, possvel criar um objeto da subclasse e atribuir a ele a referncia a um objeto da superclasse que tenha sido anteriormente criado. Desta forma, o compilador consegue compreender uma referncia a um mtodo que tenha sido sobrecarregado na subclasse.

Fazendo uma coero explcita

O Java permite a atribuio de uma referncia d superclasse a uma varivel de subclasse por meio d uma coero (cast) explcita, tcnica conhecida com downcasting. Vejamos como realizar o downcasting: EmpAssalariado empAssalariado = (EmpAssalariado)empregados[j]; Isto foi necessrio, pois desejamos poder chama tanto o mtodo salrio(), sem parmetros e que no exig casting, quanto o mtodo salrio(double abono), que fo sobrecarregado (e, portanto, no existe na superclasse).

A implementao do array e do casting


Para realizar as implementaes desejadas, s necessitamos mudar a classe EmpAssalariado (para que o mtodo toString no mais chame o mtodo salario com parmetro de abono) e a classe de teste Principal. public class Principal{ public static void main ( String argv[]) { Empregado empregados[] = new Empregado[4];// array empregados[0] = new EmpFixoComissionado ("Carlos", "Silva","123456789-10", 10000, 0.02, 300, 0.01); empregados[1] = new EmpComissionado ("Francisco", "Matos","987654321-00", 20000, 0.02, 0.01); empregados[2] = new EmpAssalariado ("Joaquim", "Alberto", "192837465-99", 1000); empregados[3] = new EmpHorista ("Felipe", "Martins", "999888765-43", 100);

A implementao do array e do casting


for ( int j = 0; j < empregados.length; j++ ){ System.out.printf( "Empregado da classe %s \n", empregados[j].getClass().getName()); System.out.println (empregados[j]); // toString if ( empregados[j] instanceof EmpAssalariado ) { EmpAssalariado empregadoA = (EmpAssalariado) empregados[j]; System.out.printf( "Salario (com abono): R$ %.2f\n\n", empregadoA.salario(200)); } // fim do if } // fim do for } // fim do mtodo main } // fim da classe Principal

A implementao do array e do casting


Na classe EmpAssalariado, s muda o mtodo toString: public String toString () { return String.format ( "%s%s %s\n%s%s\n%s%.2f", "Identificacao: ", nome, sobrenome, "CPF: ", cpf, "Salario Total: ", salario()); } A classe EmpHorista j foi acrescentada no desafio da aula passada: //Classe Empregado Horista public class EmpHorista extends Empregado { private final double valorHora = 7.50; protected double horasTrabalhadas; // Construtor com 4 argumentos public EmpHorista (String nome, String sobrenome, String cpf, double horasTrabalhadas){ super (nome, sobrenome, cpf); setHorasTrabalhadas(horasTrabalhadas);

A implementao do array e do casting


public void setHorasTrabalhadas (double horasTrabalhadas){ this.horasTrabalhadas = horasTrabalhadas; } public double getHorasTrabalhadas(){ return horasTrabalhadas; } public double salario(){ // Calcula salrio simples return (getHorasTrabalhadas()*valorHora); } public String toString () { return String.format ("%s%s %s\n%s%s\n%s%.2f\n", "Identificacao: ", nome, sobrenome, "CPF: ", cpf, "Salario total: ", salario()); } } // fim da classe Empregado Horista As demais classes so iguais s da aula passada. Compile e teste.

Alterando o for

Alm da implementao utilizando o comando for clssico como visto acim podemos alternativamente empregar o comando for estendido, disponvel a partir d Java 5. Com ele, a implementao da classe Principal fica mais elegante dispensando o uso de uma varivel de controle e aproveitando a dimenso d declarao do tipo array. Veja: for ( Empregado empregadoAtual : empregados ){ System.out.printf( "Empregado da classe %s \n", empregadoAtual.getClass().getName()); System.out.println (empregadoAtual); if (empregadoAtual instanceof EmpAssalariado ) { EmpAssalariado empregadoA = (EmpAssalariado) System.out.printf( "Salario (com abono): R$ %.2f\n\n", empregadoA.salario(200)); } // fim do if } // fim do for Faa a alterao, compile e teste desta outra forma.

Usando interfaces
Ainda no exemplo da aula passada, o que fizemos foi criar uma superclasse destinada apenas a definir o que comum s subclasses dela derivadas, sem que se tenha a inteno de efetivamente instanciar objetos dessa classe, que conhecida como classe abstrata. Outra forma de conseguir esse resultado criando uma Interface. Uma interface define um conjunto de mtodos que uma classe deve implementar, mas no define como esses mtodos devem ser implementados. utilizada quando classes no relacionadas necessitam compartilhar mtodos e constantes. Isto permite que instncias de classes no relacionadas sejam processadas de forma polimrfica respondam s mesmas chamadas de mtodos. O programador pode criar uma interface que descreve a funcionalidade desejada e ento implementar essa interface em quaisquer classes que requerem essa funcionalidade. Utiliza-se uma interface no lugar de uma classe abstrata quando no h nenhuma implementao padro a herdar nenhum atributo (varivel de classe) e nenhum mtodo com implementao. Uma interface , essencialmente, uma coleo de constantes e mtodos abstratos. Mtodos em uma interface so sempre pblicos e abstratos. Constantes em uma interface so sempre pblicas, estticas e final . A interface resolve o problema de Java no suportar herana mltipla como outras linguagens (C++, por exemplo), de forma mais elegante, pois apenas relaciona as funcionalidades necessrias s classes.

Usando interfaces
No nosso exemplo, se encararmos o salrio a ser pago a um empregado como uma despesa, podemos observar que outras classes no relacionadas a empregados podem tambm representar despesas. Por exemplo, uma fatura uma despesa e poderamos criar uma interface Pagamento , que fosse comum s faturas e aos empregados, na qual houvesse um mtodo para calcular o pagamento. Embora aplicado a coisas no relacionadas (faturas e empregados), o mtodo tem a ver com obter algum valor a ser pago. A modelagem do sistema teria agora o aspecto da figura ao lado. Como j vimos, em Java as classes s podem ter uma superclasse pois Java no suporta herana mltipla. Em contraposio, uma classe pode implementar vrias interfaces alm de herdar de uma classe. Exemplo: public class Testa implements Interface1, Interface2, interface3 extends SuperClasse

Revendo a aplicao
Para consolidar os conceitos de arrays de objetos, casting de classes e criao de interfaces, vamos alterar a aplicao que fizemos na aula passada para o cdigo que se segue. A interface Pagamento possui uma sintaxe que apenas declara os mtodos que sero implementados pelas classes que implementem esta interface. No nosso caso, como j dissemos, apenas um mtodo para calcular o pagamento a ser feito para os empregados e as faturas. O cdigo ser apenas: public interface Pagamento{ double calcularPagamento(); }

Revendo a aplicao
A classe Fatura possui atributos para guardar o nome da pea, o seu preo e a sua quantidade. Alm disso, implementa o mtodo para calcular o pagamento que foi previsto na interface. Seu cdigo est relacionado a seguir: public class Fatura implements Pagamento { private String nome; // nome da pea private int quantidade; // quantidade de peas private double preco; // preo unitrio da pea public Fatura (String nome, int quantidade, double preco){ this.nome = nome; this.setQuantidade (quantidade); this.setPreco (preco); } public void setNome(String nome){ this.nome = nome; }

Revendo a aplicao
public String getNome() { return nome; } public void setQuantidade(int quantidade){ this.quantidade = (quantidade<0)? 0 : quantidade; } public int getQuantidade() { return quantidade; } public void setPreco(double preco) { this.preco = ( preco < 0.0 ) ? 0.0 : preco; } public double getPreco() { return preco; }

Revendo a aplicao
public String toString() { return String.format( "%s: \n%s: %s \n%s: %d \n%s: R$ %.2f", "Fatura", "Nome da Pea", getNome(), "Quantidade", getQuantidade(), "Preo por item", getPreco() ); } public double calcularPagamento () { return getQuantidade() * getPreco(); } } // fim da classe Fatura

Revendo a aplicao
Na classe Empregado mudaremos apenas a declarao da classe para: public abstract class Empregado implements Pagamento { Nas demais classes de empregados, acrescentaremos um implementao do mtodo calcularPagamento() que apenas chama o mtodo salrio(). Coloque em cada um dos arquivos das classes: public double calcularPagamento () { return salario(); } A classe de teste Principal, agora instancia cinco elementos em um array de objetos com a mesma interface (Pagamento ). Quatro desses objetos so empregados e um uma fatura. Veja o cdigo usando o comando for estendido: public class Principal{ // Testando o projeto public static void main ( String argv[]) { Pagamento pagamentos[] = new Pagamento[5];// array pagamentos[0] = new EmpFixoComissionado ("Carlos", "Silva","123456789-10", 10000, 0.02, 300, 0.01);

Revendo a aplicao
pagamentos[1] = new EmpComissionado ("Francisco", "Matos","987654321-00", 20000, 0.02, 0.01); pagamentos[2] = new EmpAssalariado ("Joaquim", "Alberto", "192837465-99", 1000); pagamentos[3] = new EmpHorista ("Felipe", "Martins", "999888765-43", 100); pagamentos[4] = new Fatura ("Guardanapo",10,1.20); for (Pagamento pagamentoCorrente : pagamentos){ if (pagamentoCorrente instanceof Empregado) { System.out.printf ("%s\n","Empregado:"); } System.out.println(pagamentoCorrente);//toString System.out.printf("Pagamento: R$ %.2f\n\n", pagamentoCorrente.calcularPagamento()); } // fim do for } // fim do mtodo main } // fim da classe Principal

Desafios
1.

2.

Coloque na interface um atributo imposto , no valor de 10%, que deve ser aplicado no clculo do pagamento de todas as classes. Ou seja, o mtodo calcularPagamento deve acrescer o percentual de imposto ao valor a ser pago. Observe o modelo abaixo:

Desafios
Implemente as classes obedecendo hierarquia do diagrama. A interface define o mtodo para calcular pontos, que especificamente implementado em cada classe, obedecendo s seguintes regras de negcio: Pontos de um carto de prova so: o nmero de acertos multiplicado por dois, menos o nmero de erros; Pontos de um clube de futebol so o nmero de vitrias multiplicado por trs, mais o nmero de empates; Pontos de um clube de investimentos so o nmero de scios multiplicado pelo investimento mdio. A classe de teste deve criar um array de trs objetos, instanciando um objeto de cada classe passando os parmetros adequados ao construtor. A seguir, deve enviar uma mensagem ao objeto pedindo para que este calcule a quantidade de pontos e deve imprimir esse valor recebido.

Aula 06 - Objetivos
l l l l

Diferenciar tipos primitivos de dados e tipos de referncia a objetos Entender o uso dos operadores aritmticos, lgicos e relacionais Aprender a sintaxe e semntica das estruturas de controle de fluxo Tratar entradas de dados

Recordando...
Nas aulas passadas, criamos algumas aplicaes Java para ilustrar os conceitos de POO apresentados. Nestas aplicaes usamos variveis de diversos tipos, operadores e alguns comandos de deciso e repetio. Hoje veremos esses tipos e comandos detalhadamente. Tambm veremos como ler dados do teclado, pois at agora s imprimimos dados.

Tipos primitivos e tipos de referncia


Em Java, trabalhamos com dois tipos de dados: primitivos e de referncia, estes tambm denominados como no primitivos. Primitivos:

Tipo boolean byte char short int long float double

Quant. Bits 1 8 16 16 32 64 32 64

Valores armazenveis na varivel True ou False 128 at 127 ( -27 a 27-1 ) \u0000 a \uFFFF (0 a 65535) 32768 at 32767 ( -215 a 215-1 ) 2.147.483.648 at 2.147.483.647 (-263 a 263-1 ) 1,40 X 10-45 a 3,40 X 1038 4,94 X 10-324 a 1,70 X 10308 (-231 a 231-1 )

Tipos primitivos e tipos de referncia


Uma varivel de tipo primitivo pode armazenar exatamente um valor do seu tipo declarado. Variveis de tipo de referncia so utilizadas para armazenar as localizaes de objetos na memria do computador. Diz-se que estas variveis referenciam objetos. Os atributos de tipo primitivo so iniciados por ocasio da instanciao do objeto. Os atributos de tipos byte , char, short, int, long, float e double so iniciadas com zero, as variveis do tipo boolean com false. Podem ser especificados valores iniciais para variveis destes tipos quando de sua declarao. Variveis locais de mtodos no so iniciadas automaticamente. As variveis de instncia de tipo de referncia so iniciadas por padro com o valor null palavra reservada que representa uma referncia a nada. Somente depois que o objeto instanciado que a varivel contm uma referncia para o objeto. Por exemplo, o comando Curso meuCurso = new Curso(); cria uma instncia (objeto) da classe Curso, e a varivel meuCurso contm uma referncia a esse objeto. A partir de ento, a varivel pode ser usada para chamar mtodos do objeto ou referenciar seus atributos.

Usando Operadores
O Java oferece um conjunto amplo de operadores aritmticos, relacionais e lgicos. Veja a tabela abaixo: Tipo Op. + Aritmticos * / == Relacionais != > Lgicos && || Significado Adio Subtrao Multiplicao Diviso Igual Diferente Maior que E lgico OU lgico Ex. a+b a-b a*b a/b a==b a!=b a>b a&&b a||b Op. % ++ ->= < <= ! Significado Resto da diviso Menos unrio Incremento unrio Decremento unrio Maior ou igual Menor que Menor ou igual Negao Ex. a%b -a ++a ou a++ --a ou a-a>=b a<b a<=b !a

Estruturas de Controle do fluxo


Java contm trs tipos de estruturas de controle (instrues): seqncia, seleo e repetio. Um programa formado pela combinao destas estruturas, de forma a implementar o que o algoritmo determina. A estrutura de seqncia permite aglutinar vrios comandos em um bloco de comandos delimitado por chaves ({...}). Isto deve ser feito sempre que queiramos delimitar os comandos que faam parte de uma outra estrutura de controle de deciso ou repetio (if/else, switch, for, while, etc.).

Instrues de seleo
Comando if O if uma instruo que permite a seleo entre dois caminhos distintos, conforme a avaliao de uma condio lgica como falsa ou verdadeira. If (expresso lgica)comando1; else comando2; Exemplo: If ( nota >= 6 ) System.out. println (Aprovado); else System.out. println (Reprovado); A parte do else opcional. Comando1 e Comando2 podem ser blocos de comandos. O compilador Java sempre associa um else instruo if imediatamente anterior, a menos que instrudo de outro modo pela colocao das chaves Operador condicional ternrio Como j vimos em aulas anteriores, em algumas situaes podemos usar o operador ?, que realiza a mesma operao do comando if. Ex: System.out.println(nota > 6 ? Aprovado:Reprovado);

Instrues de seleo
Comando switch Este comando equivale a um conjunto de if encadeados: switch (expresso ordinal) { case ordinal1: comando1; break; case ordinal2: comando2; break; case ordinalN: comandoN; break; default: comandoDefault; } Exemplo: switch (opcao) { case a: case A: System.out.println(letra A); break; case b: case B: System.out.println(letra B); break; default: System.out.println(letra invalida);

Estruturas de repetio
Comando for O comando for indicado para repetirmos um trecho de cdigo uma quantidade fixa de vezes. Sua sintaxe possui trs sees opcionais: for (seo1; seo2; seo3) comando; a seo1 executada apenas uma vez e geralmente usada para iniciar uma varivel de controle do for. A seo2 executada antes de cada iterao do for e habilita a execuo de mais uma iterao, caso verdadeira (true). Geralmente usada para testar a varivel de controle do for. A seo3 executada ao final de cada iterao do for e geralmente usada para incrementar a varivel de controle. Exemplo: for (int i = 0; i < 4;i++) System.out.printf(%d ,i); //imprime de 0 a 3 Comandos while / do O comando while indicado quando desejamos repetir um trecho de cdigo uma quantidade indefinida de vezes, enquanto uma determinada condio for verdadeira. Sintaxe: while (expresso lgica) comando1;

Estruturas de repetio
Exemplo: while ( produto <= 100 ) produto = 3 * produto; Caso a condio seja inicialmente falsa, nenhuma iterao ser executada. Nos casos em que desejamos executar pelo menos uma vez os comando da repetio, devemos usar o comando do / while, Cuja sintaxe a que se segue: do comando1; while (expresso lgica); Veja o exemplo: do produto = 3 * produto; while ( produto <= 100 );// testa aps ter executado // pelo menos uma vez

Lendo valores do teclado


At agora, nossas aplicaes apenas escreviam valores na tela de console. Fizemos isso usando (embora sem ter sido ainda explicado) um Stream de dados. Um Stream um canal que conduz os dados de um lugar (um arquivo ou um dispositivo) para outro. A stream de sada padro (out) est na classe Java.lang.System e aberta automaticamente pela mquina virtual Java, j associada ao dispositivo de sada padro (display). J a stream de entrada padro (in), disponvel estaticamente atravs da mesma classe Java.lang.System, de utilizao bastante precria, na medida em que disponibiliza mtodos apenas de acesso a bytes, de forma que, para que se leia valores inteiros, reais ou strings, necessrio ir concatenando bytes para formar a entrada desejada. Assim, no utilizaremos essa forma de entrada e sim uma classe mais elaborada, disponvel na biblioteca java.util.Scanner, que permite a chamada de mtodos para ler diretamente strings, nmeros inteiros e nmeros reais.

Lendo valores do teclado


Para utiliz-la, necessrio instanciar um objeto da classe Scanner e chamar um mtodo apropriado para ler cada um dos tipos bsicos ou String de um dispositivo qualquer. Por exemplo, para ler do dispositivo padro de entrada, podemos ter o seguinte cdigo: // cria Scanner para ler entrada na janela de comando Scanner entrada = new Scanner( System.in ); // faz Scanner ler variveis de diferentes tipos palavra = entrada.next() // l String at <branco> nome = entrada.nextLine() // l String at <ENTER> valorI = entrada.nextInt() // l valor inteiro valorF = entrada.nextFloat() // l valor float valorD = entrada.nextDouble() // l valor double valorB = entrada.nextBoolean() // l valor boolean Alm de ler os valores, podemos tambm testar se o valor do tipo esperado, atravs de mtodos que retornam valores lgicos. Por exemplo: if (entrada.hasInt()) { // true, se entrada inteira if (entrada.hasFloat()) { // true, se entrada float if (entrada.hasDouble()) { // true, se entrada double

Aplicando os conceitos aprendidos


Para consolidar os conceitos de operadores, estruturas de controle e criao de interfaces, vamos criar uma aplicao diferente da que vnhamos fazendo nas aulas passadas. Nossa aplicao possuir apenas uma classe (Curso), que guardar seu prprio nome, o nome de um aluno e as notas das trs avaliaes desse aluno no curso. A classe oferece mtodos de get e set para seus atributos e um mtodo que avalia se o aluno foi aprovado ou reprovado, de acordo com as notas das avaliaes, retornando um String com essa avaliao final. Para julgar se o aluno foi aprovado, feita a mdia das duas maiores notas e o aluno estar aprovado se esta for maior ou igual a 6,0. public class Curso { private String nomeCurso; private String nomeAluno; private float notas[]; public Curso(String nomeCurso,String nomeAluno) { this.nomeCurso = nomeCurso; this.nomeAluno = nomeAluno; notas = new float[3]; }

Aplicando os conceitos aprendidos


public void setNomeCurso( String nomeCurso ) { this.nomeCurso = nomeCurso; } public String getNomeCurso() { return nomeCurso; } public void setNomeAluno( String nomeAluno ) { this.nomeAluno = nomeAluno; } public String getNomeAluno() { return nomeAluno; } public void setNotas (float nota, int posicao){ notas[posicao] = nota; }

Aplicando os conceitos aprendidos


public float calcularMedia() { int indNota=0; // indice das notas float piorNota=11; // valor da nota a descartar int indPiorNota=0; // indice da nota a descartar while ( indNota < 3 ) { // descobre a pior nota if (notas[indNota] < piorNota){ piorNota = notas[indNota]; indPiorNota = indNota; } indNota++; } // fim do while switch (indPiorNota){//media das 2 melhores case 0: return ((notas[1]+notas[2])/2); case 1: return ((notas[0]+notas[2])/2); case 2: return ((notas[0]+notas[1])/2); } return 0;

Aplicando os conceitos aprendidos


public String determinarSituacao() { String situacao; if (calcularMedia() >= 6.0) situacao = "APROVADO(A)"; else situacao = "REPROVADO(A)"; return String.format( "\n%s %s %s %s %s %s %s %.2f\n\n", "O(a) aluno(a)",getNomeAluno(),"foi", situacao,"no curso",getNomeCurso(), "com media",calcularMedia()); } // fim do mtodo determinarSituacao } // fim da classe LivroNotas

Aplicando os conceitos aprendidos


A classe da aplicao de teste possui o seguinte cdigo: import java.util.Scanner; // Classe Scanner public class AppCurso{ public static void main( String args[] ) { float nota; String curso="",aluno=""; //inicia Strings Scanner entrada = new Scanner( System.in ); // cria Scanner p/ ler do console System.out.printf("\nEntre com nome do curso: ");curso = entrada.nextLine(); System.out.printf("\nEntre com nome do aluno: "); aluno = entrada.nextLine(); Curso meuCurso = new Curso(curso,aluno); for (int cont=0; cont<3; cont++){ System.out.printf("\nDigite a nota %d: ",cont+1); nota = entrada.nextFloat(); meuCurso.setNotas(nota,cont); } System.out.printf("%s", meuCurso.determinarSituacao()); } // fim de main } // fim da classe AppCurso Compile e execute os cdigos das classes acima.

Desafios
1.

2.

Coloque na classe Curso um atributo frequencia , que represente o percentual de aulas assistidas pelo aluno. Modifique o mtodo determinarSituacao para que considere um percentual mnimo de 75% para considerar o aluno aprovado. Substitua o comando for da classe de teste pelo comando do/while

Aula 07 - Objetivos
l l l l l

Apresentar os operadores compostos de atribuio Usar os operadores unrios de incremento e decremento Compreender o conceito e o uso de atributos e mtodos Static Aprender a declarar e utilizar vetores e matrizes Reforar a utilizao da classe String

Recordando...
Nas aulas passadas, criamos algumas aplicaes Java em que instanciamos objetos a partir de classes que havamos previamente declarado. Essas classes possuam atributos que, aps a instanciao dos objetos, eram tratados como variveis de instncia do objeto. Ou seja, cada atributo ou mtodo era, at agora, visto como um atributo ou mtodo do objeto instanciado. Hoje veremos que os atributos e mtodos podem pertencer somente classe do objeto, sendo comuns aos diferentes objetos que tenham sido instanciados de uma mesma classe. Antes, entretanto, vamos reforar o conceito de operadores unrios de incremento e decremento e de operadores compostos de atribuio.

Operadores compostos de atribuio


A linguagem Java possui vrios operadores compostos de atribuio para abreviar expresses de atribuio. Qualquer instruo na forma varivel = varivel operador expresso; onde o operador seja +, -, *, / ou %, pode ser escrita na forma: varivel operador= expresso; Por exemplo, a instruo: c = c + 3; pode ser abreviada com o operador composto de atribuio de adio: c += 3; Suponha: int c = 3, d = 5, e = 4, f = 6, g = 12; += c += 7 ou c = c + 7 resulta c = 10 -= d -= 4 ou d = d 4 resulta d = 1 *= e *= 5 ou e = e * 5 resulta e = 20 /= f /= 3 ou f = f / 3 resulta f = 2 %= g %= 9 ou g = g % 9 resulta g = 3

Operadores de Incremento e Decremento


Java tem dois operadores unrios para adicionar 1 ou subtrair 1 de uma varivel numrica so o operador de incremento unrio ++ e o operador de decremento unrio --". Um programa pode incrementar de 1 o valor de uma varivel utilizando o operador de incremento, em vez das expresses c = c+1 ou c += 1. Quando o operador de incremento ou decremento colocado antes de uma varivel chamado operador de princremento ou de prdecremento, respectivamente. Quando posto depois, chamado operador de psincremento ou ps-decremento .

Pr-incremento

++a

Incrementa a de 1 e depois utiliza o novo valor na expresso.

Ps-incremento

a++

Utiliza o valor atual na expresso e depois incrementa a de 1. Decrementa a de 1 e depois utiliza o novo valor na expresso. Utiliza o valor atual na expresso e depois decrementa a de 1.

Pr-decremento

--a

Ps-decremento

a--

Operadores de Incremento e Decremento


A classe Incremento, a seguir, mostra as variaes acima:
public class Incremento{ public static void main( String args[] ) { int c = 5 , d = 5; // inicia variveis com 5 System.out.printf( "%d, %d, %d\n", c, c++, c ); System.out.printf( "%d, %d, %d\n", d, ++d, d ); } }

Atributos static
At o momento s havamos aprendido como definir atributos de instncia. Cada objeto tinha seus prprios atributos e uma modificao nos atributos de um objeto no afetava os atributos de outros objetos. Neste tpico iremos apreender como definir atributos de classe. Esses atributos so os mesmos para todos os objetos de uma classe. Eles so, portanto, compartilhados pelos objetos. Uma mudana em um destes atributos visvel por todos os objetos instanciados dessa classe. Atributos de classe tambm so chamados de atributos static . Para exemplificar, definiremos uma classe Robot que usa um atributo static como se fosse um contador, para saber quantos objetos robots foram criados (instanciados).

Atributos static
//Classe Robot class Robot { public int x, y; // posio do robot public static int contador; //contador de instancias public Robot(int x,int y){ this.x = x; this.y = y; contador++; } } A seguir a classe de teste Principal: class Principal { public static void main(String args[]) { Robot.contador=0; //inicializando variavel static Robot r1,r2; System.out.println(Robot.contador); r1 = new Robot(10,12); System.out.println(Robot.contador); r2 = new Robot(11,13); System.out.println(Robot.contador); } //main method } //class Principal Apesar de termos exemplificado com um inteiro, voc poderia ter usado uma classe no lugar desse atributo, naturalmente tomando o cuidado de chamar new antes de us-lo.

Mtodos static
Mtodos static tambm so chamados de mtodos de classes. Estes mtodos s podem operar sobre atributos que tambm sejam static. Assim: public static void metodoA() {... Exemplificando, vamos criar um mtodo static para incrementar o contador: public static void incrementa(){ contador++; } No esquea de alterar o construtor para, agora, chamar o novo mtodo: incrementa(); //substituindo o comando: contador++ Aps fazer as alteraes, compile e teste.

Vetores e matrizes
Em exemplos passados, j usamos vetores (arrays). Java d suporte a vetores e matrizes de diversas formas. Por exemplo, podemos formar um vetor com as notas de cinco alunos de uma sala de aula: float nota[] = { 6.5, 9.1, 4.2, 1.8, 6.4 }; Neste caso nota[0] a nota do primeiro aluno, isto , 6.5, nota[1] a nota do segundo, ou seja, 9.1, e assim por diante. Para usarmos de vetores e matrizes precisamos cumprir trs etapas: Declarar o vetor ou a matriz. Para isto, declaramos o nome da varivel e acrescentamos um par de colchetes antes ou depois. Por exemplo: int compra[]; double mat[][],elemento[][][]; int []nota;

1.

Vetores e matrizes
2.

3.

Reservar espao de memria e definir o tamanho. preciso definir o tamanho do vetor, isto , a quantidade total de elementos que ter de armazenar. Em seguida necessrio reservar espao de memria para armazenar os elementos. Isto feito de maneira simples pelo operador new: compra = new int[9]; // vetor de int nota = new double[35]; // vetor de double mat = new float[20][30]; // matriz de float meusObjetos = new Object[10] // vetor de referncias Armazenar elementos no vetor ou matriz. Para armazenar uma informao em um dos elementos de um vetor ou matriz, necessrio fornecer um ndice que indique a posio desse elemento. Por exemplo, para armazenar um valor na quarta posio do vetor nota, fazemos o seguinte: nota[3] = 7.5;

Vetores e matrizes
Os ndices comeam em zero e vo at o nmero de posies reservadas, menos um. No vetor nota , por exemplo, os ndices vlidos vo de 0 at 34. Ao tentar atribuir um valor a um elemento cujo ndice esteja fora desse intervalo, ocorrer um erro, impedindo a execuo. Quando desejamos criar um vetor com valores atribudos de modo esttico podemos fazer como no primeiro exemplo acima, onde foi declarado um vetor nota e o mesmo j foi iniciado com as notas de cinco alunos. Veja mais exemplos: // 12 primeiros termos da seqncia de Fibonacci: long fibonacci[] = {1,1,2,3,5,8,13,21,34,55,89,144}; // Tabela de sen(n*pi/6), n=0,1,2,...5 float seno[] = {0.000,0.500,0.866,1.000,0.866,0.500}; // Tabela de log(1+n), n=0,2...99: double tlog[] = new double[100]; for(int n=0; n<100; n++) tlog[i] = Math.log(1+n); // Matriz dos coeficientes double a[][] = { {1,2,3}, {0,1,3}, {0,0,-1} };

Vetores e matrizes
Para exemplificar o uso de mtodos/atributos estticos e vetores, vamos alterar a classe Robot, criando um mtodo static (guarda ()) para guardar, em um atributo static (o array robots[]), uma referncia para cada robot instanciado. Teremos agora o seguinte cdigo para a classe Robot: class Robot { public int x, y; // posio do robot public static int contador; //contador de instancias public static Robot robots[] = new Robot[10]; public Robot(int posicao, int x,int y){ this.x = x; this.y = y; incrementa(); guarda(posicao,this); } public int getX(){ return x; } public int getY(){ return y;

Vetores e matrizes
public void setX(int x){ this.x = x; } public void setY(int y){ this.y = y; } public static void incrementa(){ contador++; } public static void guarda (int posicao, Robot este){ robots[posicao] = este; } }

Vetores e matrizes
Agora, na classe Principal, aps criar cada objeto robot, chamamos o mtodo de cada objeto para pegar a sua respectiva posio, a partir das referncias dos objetos que esto guardadas no array de objetos da classe Robot. Veja o cdigo: //Classe principal class Principal { public static void main(String args[]) { Robot.contador=0; //inicializando variavel static Robot r; int i; for (i=0;i<10;i++) { // cria robots r = new Robot(i,i*2,i*2); } for (i=0;i<10;i++) { // imprime posicoes System.out.printf( "Posicao do robot %d: x=%d y=%d\n",i, Robot.robots[i].getX(),Robot.robots[i].getY()); } } //main method } //class Principal

A classe String
A classe String fornece construtores para iniciar objetos String de vrias maneiras. Quatro delas so mostradas no mdulo main da classe abaixo. public class StringConstructors{ public static void main( String args[] ) { char cArray[]={'b','i','r','t','h',' ','d','a','y'}; String s = new String( "hello" ); String s1 = new String(); String s2 = new String(s); String s3 = new String(cArray ); String s4 = new String(cArray, 6, 3 ); System.out.printf( "s1 = %s\ns2 = %s\ns3 = %s\ns4 = %s\n", s1, s2, s3, s4 ); // exibe strings } // fim de main }

A classe String
Alguns mtodos da classe String: length() retorna o comprimento de uma string public int length() charAt(ndice) retorna o caractere de uma localizao especfica do string public char charAt(int index) getChars retorna o conjunto de caracteres de um string como array char. public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

A classe String
O funcionamento desses mtodos visto na classe Miscelanea a seguir: public class Miscelanea{ public static void main( String args[] ) { String s1 = "OTO AMA ANA"; char charArray[] = new char[3]; System.out.printf("O String s1: %s", s1 ); System.out.printf("\nTamanho: %d",s1.length()); // percorre s1 com charAt e exibe em ordem inversa System.out.print( "\nO String invertido: " ); for ( int count=s1.length()-1; count>=0; count--) System.out.printf( "%s", s1.charAt( count )); // copia caracteres do String para o charArray s1.getChars( 4, 7, charArray, 0 ); System.out.print("\Caracteres de 4 ate 6: " ); for (char caracter : charArray ) System.out.print( caracter ); System.out.println(); } // fim de main }

Desafio
Crie uma classe Disciplina que possua nomes da matria e do professor. Deve haver um array (static ) com todas as referncias para os alunos da disciplina. A aplicao deve ler os nomes do professor e da matria e instanciar um objeto da classe Disciplina com os valores lidos para os atributos. Em seguida, deve ler o nome de 10 diferentes alunos e, para cada aluno, instanciar um objeto de uma classe Aluno, que deve possuir, alm do nome, uma nota (inicialmente 0). Ao instanciar o aluno, a aplicao deve guardar sua referncia no vetor da classe Disciplina . Depois disso, a aplicao deve pedir um nome de aluno, procurar o objeto aluno que possui esse nome e alterar sua nota para um valor fornecido pelo usurio.

Aula 08 - Objetivos
l l l l l l

Reforar conceitos sobre arrays unidimensionais e multidimensionais Passar arrays como argumentos de mtodos Entender o conceito de colees e aprender a usar a classe Arrays Aprender a criar pacotes de classes Introduzir o conceito de interfaces grficas (GUI) Apresentar componentes Swing

Recordando...
Em aulas passadas, vimos como declarar, instanciar e iniciar arrays de uma ou mais dimenses, de diferentes formas. Recorde algumas delas: Formas alternativas de fazer int c[ ]=new int [10]; float [ ] a, b; int k[ ] = {2, 4, 6, 8, 10}; int m [ ] [ ] = {{1,3,5}{7,9,0}}; int c[ ]; c = new int[10]; float a [ ]; float b [ ]; k[0]=2; k[1]=4; k[2]=6; k[3]=8; k[4]=10; int m [ ] [ ]; m=new int [2][3]; m[0]={1,3,5}; m[1]={7,9,0}; O que est sendo feito Instanciar um array Instanciar dois arrays Instanciar e iniciar um array com valores Instanciar e iniciar com valores um array bidimensional (matriz) Instanciar um array bidimensional c/ linhas de tamanhos diferentes

int n [ ] [ ]; n = new int [2] [ ]; n[0]=new int[3];n[1]=new int[5];

Passando arrays como argumentos de mtodos


Para passar um array como argumento para um mtodo, especifique o nome do array sem colchetes. Por ex., para uma array declarado como: int valor[] = int[10] A chamada de um mtodo trataValor que recebesse esse array, seria: trataValores(valor); J a declarao do mtodo com o argumento formal, teria a forma: void trataValores(int a[]); Caso desejssemos passar apenas um elemento do array, faramos: trataValor(valor[4]); //passa o quinto elemento Neste caso, o mtodo deveria ser declarado como: void trataValor(int b);

Passando arrays como argumentos de mtodos


Em muitas linguagens de programao, existem duas maneiras de passar argumentos em chamadas de mtodos: passagem por valor e passagem por referncia. Ao contrrio dessas linguagens, O Java no permite escolher passar por valor ou por referncia todos os argumentos so passados por valor. Uma chamada de mtodo pode passar dois tipos de valores para um mtodo: as cpias de valores primitivos, int por exemplo, e as cpias de referncias para objetos , inclusive referncias a arrays. Objetos no podem ser passados para os mtodos. Quando um mtodo modifica um parmetro do tipo primitivo, as alteraes no parmetro no tm nenhum efeito no valor original do argumento no mtodo chamador. Isto tambm verdadeiro para os parmetros de tipo por referncia. Se o mtodo chamado modificar um parmetro de tipo por referncia atribuindo a ele a referncia a outro objeto, o parmetro referenciar o novo objeto, mas a referncia armazenada na varivel do chamador ainda referencia o objeto original.

Colees
Podemos armazenar vrios objetos ou valores de tipos primitivos em um array e manipular este array como sendo uma nica entidade. Um array pode ser encapsulado em uma classe, possibilitando a criao de mtodos especficos de manipulao do array encapsulado. Apesar da flexibilidade que pode ser obtida com o encapsulamento de um array em uma classe, algumas necessidades teis no podem ser implementadas de forma trivial ou eficiente. Como, por exemplo: o tamanho do array no pode ser modificado depois do array criado; um array somente pode conter elementos de um nico tipo, exceto se considerarmos os mecanismos de herana e polimorfismo; algumas operaes no podem ser realizadas de maneira simples em array como inserir e excluir um determinado elemento. A linguagem Java possui classes e interfaces que poupam trabalho e oferecem mecanismos para agrupar e processar objetos em conjuntos, denominados genericamente como colees. Muitas dessas classes implementam estruturas de dados complexas, mas cujo uso transparente para o programador. Todas essas classes fazem parte do pacote java.util. Resumindo, uma coleo uma estrutura de dados, na realidade um objeto, que pode armazenar referncias a outros objetos. Normalmente as colees contm referncias a objetos que so todos do mesmo tipo. As interfaces de estrutura das colees declaram as operaes a serem realizadas nessas colees: Collection, Set, List, Map, Queue, ....

Classe Arrays
A classe Arrays fornece mtodos static de alto nvel para manipular arrays, como sort para ordenar o array, binarySearch para pesquisar o array ordenado, equals para comparar arrays e fill para colocar valores no array. O aplicativo a seguir mostra a utilizao de alguns desses mtodos: import java.util.Arrays; // Classe Arrays import java.util.Scanner; // Classe Scanner public class UsandoArrays { private int intArray[] = { 1, 2, 3, 4, 5, 6 }; private double doubleArray[] = {8.4,9.3,0.2,7.9,3.4}; private int intArrayCheio[], intArrayCopia[]; public UsandoArrays(){ //construtor intArrayCheio = new int[10]; intArrayCopia = new int[intArray.length]; Arrays.fill (intArrayCheio, 7);// preenche com 7s Arrays.sort (doubleArray); // ordena doubleArray System.arraycopy (intArray, 0, intArrayCopia, 0, intArray.length ); }

Classe Arrays
public void mostraArrays() { System.out.print( "doubleArray ordenado: " ); for (double doubleValue : doubleArray) System.out.printf ("%.1f; ", doubleValue); System.out.print( "\nintArray: " ); for ( int intValue : intArray ) System.out.printf( "%d ", intValue ); System.out.print( "\nintArrayCheio: "); for ( int intValue : intArrayCheio ) System.out.printf( "%d ", intValue ); System.out.print( "\nintArrayCopia: " ); for ( int intValue : intArrayCopia ) System.out.printf( "%d ", intValue ); System.out.println( "\n" ); } public int pesquisaInt( int value ){ return Arrays.binarySearch(intArray, value );

Classe Arrays
public void mostraIgualdade(){ boolean b = Arrays.equals(intArray, intArrayCopia); System.out.printf("intArray %s intArrayCopia\n", ( b ? "==" : "!=" )); b = Arrays.equals( intArray, intArrayCheio ); System.out.printf( "intArray %s intArrayCheio\n", ( b ? "==" : "!=" ) ); } public static void main( String args[] ) { UsandoArrays meuArray = new UsandoArrays(); meuArray.mostraArrays(); meuArray.mostraIgualdade(); Scanner entrada = new Scanner( System.in ); System.out.printf("\nEntre com valor a procurar: "); int val = entrada.nextInt();

Classe Arrays
int location = meuArray.pesquisaInt(val); String lixo = entrada.nextLine() ; if ( location >= 0 ) System.out.printf( "Valor %d encontrado na posicao %d do intArray\n", val, location ); else System.out.printf( "Valor %d nao foi encontrado em intArray\n",val); } }

Criando Pacotes
Aplicaes e projetos complexos necessitam de organizao das classes que utilizam, de forma que fique claro a qual aplicao ou projeto as classes pertencem. Esta necessidade de organizao mais aparente quando se deseja compartilhar classes ou instal-las em outro computador. Java prov um mecanismo de agrupamento de classes em pacotes packages com o qual podemos criar grupos de classes relacionadas. Para a criao desses pacotes, basta uma declarao de pertinncia ao pacote em cada classe e a organizao das classes em um diretrio. Para criar uma pacote basta, portanto, criar um diretrio e colocar l os cdigos-fonte das classes que desejamos que faam parte desse pacote. Como exemplo, vamos considerar as classes Data , Hora e, ainda, a classe DataHora que encapsula uma data e uma hora. Para aglutinar essas classes em um pacote, primeiramente devemos criar um diretrio DataHora e, a seguir, armazenar as classes dentro desse diretrio. Cada classe do pacote deve ter, no seu incio, a palavra-chave package seguida do nome do diretrio (pacote) ao qual a classe pertence. Veja para a classe Data :

Criando Pacotes
package DataHora; // indica o pacote da classe public class Data { byte dia; // acessibilidade default package byte mes; // acessibilidade default package short ano; // acessibilidade default package public Data(byte d, byte m, short a){ dia = d; mes = m; ano = a; } public String toString(){ return dia + "/" + mes + "/" + ano; } }

Criando Pacotes
A seguir listamos a classe Hora que encapsula os dados de uma hora: package DataHora; // indica o pacote da classe public class Hora { byte hora; // acessibilidade default package byte minuto; // acessibilidade default package byte segundo; // acessibilidade default package public Hora(byte h, byte m, byte s){ hora = h; minuto = m; segundo = s; } public String toString(){ return hora + ":" + minuto + ":" + segundo; } }

Criando Pacotes
A terceira classe do pacote DataHora a classe de nome DataHora: package DataHora; public class DataHora { private Data novaData; private Hora novaHora; public DataHora(byte d, byte mes, short a, byte h, byte min, byte s){ novaData = new Data(d, mes, a); novaHora = new Hora(h, min, s); }

Criando Pacotes
public String toString(){ String resulta = novaHora.hora + ":" + novaHora.minuto + ":" + novaHora.segundo; resulta += " de " + novaData.dia + " de "; switch (novaData.mes){ case 1: resulta += "Janeiro"; break; case 2: resulta += "Fevereiro"; break; case 3: resulta += "Maro"; break; case 4: resulta += "Abril"; break; case 5: resulta += "Maio"; break; case 6: resulta += "Junho"; break; case 7: resulta += "Julho"; break; case 8: resulta += "Agosto"; break; case 9: resulta += "Setembro"; break; case 10: resulta += "Outubro"; break; case 11: resulta += "Novembro"; break; case 12: resulta += "Dezembro"; break;

Criando Pacotes
resulta += " de " + novaData.ano; return resulta; } } Note que a classe DataHora acima, faz referncia a atributos das classes Data e Hora (hora, dia,etc.), que possuem acessibilidade default (package ). As classes Data , Hora e DataHora pertencem ao pacote DataHora . A classe de teste DemoDataHora utiliza as classes Data , Hora e DataHora , mas no faz parte do pacote DataHora (coloque-a em outro diretrio). Veja: import DataHora.Hora; import DataHora.Data; import DataHora.DataHora; public class DemoDataHora { public static void main (String args[]){ Hora meiodia=new Hora ((byte)12,(byte)00,(byte)00); Data hoje=new Data ((byte)24,(byte)10,(short)2006); DataHora agora=new DataHora ((byte)24,(byte)10, (short)2006,(byte)19,(byte)50,(byte)00); System.out.println (meiodia); System.out.println (hoje); System.out.println (agora); }

Usando interfaces grficas


At agora nossas aplicaes utilizaram uma janela de texto (console) para entrada e sada de dados. A maioria dos aplicativos que utilizamos no dia-a-dia, entretanto, utiliza janelas com diversos recursos grficos para interagir com o usurio, como campos de edio, botes e outros objetos grficos que compem o que se chama uma Interface Grfica (GUI). Uma GUI construda a partir de componentes, tambm chamados de controles ou widgets (window gadgets) em outras linguagens. Um componente GUI um objeto com o qual o usurio interage via mouse, teclado ou outro formulrio de entrada. Exemplos de GUI so as janelas de aplicativos como o Internet Explorer, Word, etc,...

Entrada e sada com JOptionPane


A classe JOptionPane do Java (pacote javax.swing) fornece caixas de dilogos pr-empacotadas tanto para entrada como para sada. Esses dilogos so exibidos invocando mtodos JOptionPane static. A classe a seguir um aplicativo de adio que utiliza dois dilogos de entrada para obter inteiros do usurio e um dilogo de mensagem para exibir a soma desses inteiros. import javax.swing.JOptionPane; public class Adicao{ // Adio de inteiros public static void main( String args[] ){ String strNumero1 = JOptionPane.showInputDialog("Entre com um nmero" ); String strNumero2 = JOptionPane.showInputDialog("Entre outro nmero"); int numero1 = Integer.parseInt(strNumero1); int numero2 = Integer.parseInt(strNumero2); int soma = numero1 + numero2; //soma os nmeros JOptionPane.showMessageDialog(null, "A soma : " + soma, "Soma de dois inteiros", JOptionPane.PLAIN_MESSAGE ); } // fim do main

Entrada e sada com JOptionPane


O mtodo showInputDialog da classe JOptionPane exibe um dilogo de entrada apresentando o argumento String para o usurio. Esse mtodo devolve o String digitado na caixa de texto para o programa. Ao contrrio da classe Scanner que pode captar valores de vrios tipos atravs de seus mtodos, o mtodo showInputDialog s permite captar informaes do tipo String. Se usurio clicar no boto Cancel, o mtodo retorna null. Se o usurio digitar uma informao no convertvel para o tipo int , ou mesmo no digitar caracter algum, e clicar no boto OK, ocorrer um erro em tempo de execuo que, futuramente, veremos como tratar. O aplicativo tambm utilizou o mtodo showMessageDialog da classe JOptionPane para exibir uma mensagem que contm a soma dos dois nmeros. O primeiro argumento informa a posio da caixa de dilogo na tela, no caso null indica que a caixa deve ficar no centro da tela. O segundo argumento a mensagem a exibir, neste caso o resultado de uma concatenao. O terceiro argumento um String que deve aparecer na barra de ttulo da caixa de dilogo.

Entrada e sada com JOptionPane


O quarto argumento o tipo de dilogo: ERROR_MESSAGE Apresenta um cone vermelho com X.

INFORMATION_MESSAGE

Apresenta um cone azul com i.

WARNING_MESSAGE

Apresenta um cone amarelo com !.

QUESTION_MESSAGE

Apresenta um cone verde com ?.

PLAIN_MESSAGE

S a mensagem, sem cone.

Componentes Swing
A maioria dos aplicativos GUI exige interfaces mais elaboradas e personalizadas. Os componentes Swing so escritos, manipulados e exibidos em Java e fazem parte das Java Foundation Classes (JFC), que so bibliotecas para desenvolvimento de GUI para mltiplas plataformas. Abaixo, uma lista de componentes Swing GUI do pacote Javax.swing: JLabel JTextField JButton JCheckBox JList JComboBox JPanel Exibe texto no editvel. Permite a digitao de um texto de entrada. Gera um evento ao clicar nele com o mouse. Especifica opes que podem ser selecionadas. Lista de itens que permite seleo simples ou Mltipla. Lista de opes com possibilidade de digitao na caixa. rea para organizar componentes ou desenho de imagens.

Componentes Swing
Antes do conjunto Swing, introduzido no J2SE 1.2, as GUI eram construdas com componentes AWT ( Abstract Window Toolkit) do pacote java.awt. Estes componentes so exibidos de forma diferente em cada plataforma: Windows, Macintosh, ... A maneira como o usurio interage com um componente AWT particular tambm difere entre as plataformas. Juntas, a aparncia e a maneira como o usurio interage com o aplicativo so conhecidas como a aparncia e comportamento do aplicativo. Componentes Swing permitem especificar uniformemente a aparncia e o comportamento para um aplicativo em todas as plataformas ou utilizar a aparncia e o comportamento personalizados de cada plataforma. Entretanto, alguns componentes Swing requerem interao direta com o sistema local de janelas, o que pode restringir sua aparncia e funcionalidade, sendo chamados de componentes Swing pesados. A maioria dos componentes Swing, entretanto, no so afetados pelos sistemas de janelas das plataformas e so componentes Swing leves.

Componentes Swing
ObjectComponentContainerJComponent O diagrama UML ao lado, mostra a hierarquia da herana de classes a partir das quais os componentes Swing leves herdam seus atributos e comportamento comuns. A classe Object a superclasse de toda a hierarquia de classes do Java. A classe Component (pacote java.awt) declara muitos dos atributos e comportamentos comuns aos componentes GUI em pacotes java.awt e javax.swing. A classe Container organiza e exibe outros objetos Container , assim como objetos Component, em tela. Qualquer objeto que um Container pode ser utilizado para organizar outros objetos Component em uma GUI. Como um Container um Component , possvel anexar Containers a outros Containers para ajudar na organizao de uma GUI. A classe JComponent (pacote javax.swing) a superclasse de todos os componentes leves Swing e declara seus atributos e comportamentos comuns. Como JComponent uma subclasse de Container , todos os componentes Swing leves tambm so Containers.

Object Component Container

JCompone

Criando aplicaes GUI


O aplicativo a seguir introduz um framework, como chamada, normalmente, a estrutura bsica de uma interface. A maioria das janelas que so criadas so instncias da classe JFrame ou um subclasse dela. JFrame fornece os atributos e comportamentos bsicos de uma janela barra de ttulo e botes de minimizar, maximizar e fechar a janela. Em geral, uma aplicao GUI consiste de, pelo menos, duas classes: uma subclasse de JFrame e uma classe de aplicativo em que o mtodo main cria e exibe a janela principal do aplicativo. Uma interface tpica com o usurio contm muitos componentes, o que poderia criar dificuldades para identificar o propsito de cada componente, a menos que sejam fornecidas informaes que declaram o propsito de cada um deles. Para isso usado um controle da classe JLabel, que uma subclasse de JComponent. Um JLabel exibe uma nica linha de texto de leitura, uma imagem, ou um texto com imagem.

Criando aplicaes GUI


A aplicao a seguir mostra vrios recursos do componente JLabel e apresenta um exemplo de framework dado pelo gerenciador de layout FlowLayout. O Java tem vrios gerenciadores de layout. Ser utilizada uma instncia da classe JFrame para exibir uma janela que contm 3 JLabel. Ao construir uma GUI, cada componente deve ser anexado a um container. No caso deste aplicativo, uma janela criada com um JFrame . Geralmente pode ser especificada a posio de cada componente, o que conhecido como especificar o layout dos componentes GUI. Nas prximas aulas estudaremos outros gerenciadores de layout do Java. No FlowLayout, os componentes GUI so colocados em um container da esquerda para a direita, na ordem em que so anexados ao container pelo programa. Quando no houver mais espao, eles continuam a aparecer da esquerda para a direita na prxima linha. Se o container for redimensionado, os componentes so reorganizados na nova largura do container, possivelmente com mais ou menos linhas de componentes. setLayout(new FlowLayout());

Criando aplicaes GUI


A instruo acima, o mtodo setLayout, herdado indiretamente da classe Container, especifica que o layout da janela ser um FlowLayout. No caso criado um objeto FlowLayout e passada sua referncia como argumento para setLayout. import java.awt.FlowLayout; // gerenciador de layout import javax.swing.JFrame; // janela bsica import javax.swing.JLabel; // exibe textos e imagens import javax.swing.Icon; // para manipular imagens import javax.swing.ImageIcon; // carrega imagens import javax.swing.SwingConstants; //constantes do Swing public class UsaLabel extends JFrame{ private JLabel label1; // JLabel apenas com texto private JLabel label2; // JLabel com texto e cone private JLabel label3; // texto e cone adicionados public UsaLabel(){ super("Testando Labels");// frame bsico c/ ttulo setLayout(new FlowLayout()); // layout do frame label1 = new JLabel("Label simples com texto" ); label1.setToolTipText("Este o label1");

Criando aplicaes GUI


add(label1); // adiciona label1 ao JFrame Icon bug = new ImageIcon(getClass().getResource( "bug1.gif")); // string, Icon e alinhamento label2 = new JLabel("Label com cone esquerda", bug,SwingConstants.LEFT); label2.setToolTipText("Este o label2"); add(label2); // adiciona label2 ao JFrame label3 = new JLabel(); // JLabel sem argumentos label3.setText("Label com cone acima" ); //texto label3.setIcon(bug); // adiciona o cone label3.setHorizontalTextPosition( SwingConstants.CENTER); label3.setVerticalTextPosition( SwingConstants.BOTTOM); label3.setToolTipText("Este o label3" ); add(label3); // adiciona label3 ao JFrame } // fim do construtor UsaLabel

Criando aplicaes GUI


A classe TestaLabel, cria um objeto da classe LabelFrame e especifica a operao de fechamento padro da janela (simplesmente a oculta). O mtodo setDefaultCloseOperation da classe UsandoLabel , herdado de JFrame, com a constante JFrame.EXIT_ON_CLOSE como argumento, indica que o aplicativo termina quando a janela for fechada pelo usurio. import javax.swing.JFrame; public class TestaLabel{ public static void main( String args[] ) { UsaLabel janela = new UsaLabel(); janela.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); janela.setSize(275,180);// larg.x alt. do frame janela.setVisible( true ); // exibe frame } // fim de main } // fim da classe

Desafio
1.

2.

3.

Aumente a largura do Frame para compreender o funcionamento do estilo FlowLayout. Procure informaes sobre classes e mtodos usados no docs do JDK. Tente adicionar objetos JTextField e JButton janela criada explorando suas particularidades

Aula 09 - Objetivos
l l l l

Reforar conceitos sobre interfaces grficas com componentes Swing Introduzir o conceito de evento Apresentar mais alguns componentes Swing Compreender o funcionamento do tratamento de eventos

Recordando...
Na aula passada, vimos como criar uma interface grfica usando componentes do pacote Swing. Entretanto a aplicao que desenvolvemos somente exibia informaes, no possuindo entrada de dados. Hoje vamos estender esse conceito, usando outros componentes tpicos de aplicaes grficas, como botes e caixas de edio. Antes, entretanto, vamos desenvolver o conceito de tratamento de eventos.

Tratamento de eventos
As tarefas que um aplicativo grfico deve realizar so comandadas pelo usurio atravs da interao deste com a GUI. comum clicar sobre um boto (OK, Enviar ou Gravar, por exemplo) para instruir o aplicativo a realizar uma tarefa. As aplicaes com GUIs so, portanto, baseadas em eventos, que geralmente so gerados pelo usurio. Quando um usurio interage com um componente GUI, ele gera um evento, que resulta numa tarefa a ser executada. Alguns eventos comuns so o clicar em um boto, o digitar numa caixa de texto ou o selecionar uma opo de uma lista. O cdigo que realiza uma tarefa em resposta ao evento chamado de handler de evento, e o processo total de responder ao evento conhecido como tratamento do evento.

Tratando eventos de componentes Swing


Vamos conhecer dois componentes do pacote javax.swing que possuem eventos associados: JTextField e JPasswordField. A classe JTextField estende a classe JTextComponent (javax.swing.text), e possui recursos comuns aos componentes baseados em texto do Swing. Este componente serve, normalmente, para a entrada de dados. A classe JPasswordField estende JTextField adicionando mtodos para o processamento de senhas. Este componente mostra caracteres eco medida que o usurio digita, escondendo os caracteres digitados. Quando o usurio, aps digitar um texto em um dos componentes acima, pressionar Enter, ser gerado um evento que poder acionar uma tarefa

Tratando eventos de componentes Swing


Antes que um aplicativo possa responder a um evento, necessrio: Criar uma classe que represente o handler do evento e instanciar um objeto dessa classe (o handler do evento). Implementar uma interface apropriada, conhecida como interface listener de evento na classe do handler do evento; Registrar o handler do evento, indicando que o objeto de handler do evento deve ser notificado quando o evento ocorrer. O componente GUI acionado pelo usurio gera um ActionEvent (pacote java.awt.event ), que processado pelo objeto handler do evento, que implementa uma interface ActionListener (pacote java.awt.event ). O aplicativo a seguir utiliza as classes apresentadas para criar e manipular quatro campos de texto. Quando o usurio digita em um dos campos e pressiona Enter, o aplicativo exibe um caixa de dilogo com o texto digitado. Observe que o texto s pode ser digitado no componente que estiver sob foco. Um componente recebe o foco quando o usurio clica sobre ele ou quando passeia pelos objetos utilizando a tecla tab.

Tratando eventos de componentes Swing


import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JTextField; import javax.swing.JPasswordField; import javax.swing.JOptionPane; public class JanelaTexto extends JFrame{ private JTextField campo1; private JTextField campo2; private JTextField campo3; private JPasswordField campo4; public JanelaTexto(){ super("Testa caixas de texto"); setLayout(new FlowLayout()); // layout do frame campo1 = new JTextField(10); //caixa com 10 colunas add( campo1 ); // adiciona campo1 janela

Tratando eventos de componentes Swing


campo2 = new JTextField("Campo editvel"); add(campo2); campo3 = new JTextField("No editvel", 10); campo3.setEditable(false); // desativa edio add(campo3); campo4 = new JPasswordField("Senha",10); add(campo4); //instancia o objeto handler do evento TrataEvento handler = new TrataEvento(); campo1.addActionListener(handler);//registra handler campo2.addActionListener(handler);//registra handler campo4.addActionListener(handler);//registra handler } // fim do construtor

Tratando eventos de componentes Swing


// classe que implementa o objeto handler do evento private class TrataEvento implements ActionListener{ public void actionPerformed(ActionEvent evento){ String s = ""; if (evento.getSource() == campo1) s=String.format("Texto 1: %s ",campo1.getText()); else if (evento.getSource() == campo2) s=String.format("Texto 2: %s ",campo2.getText()); else if (evento.getSource() == campo4) s = String.format("Texto: %s", new String(campo4.getPassword())); JOptionPane.showMessageDialog(null, s); } } // fim da classe TrataEvento } // fim da classe JanelaTexto

Tratando eventos de componentes Swing


A largura em pixels de uma coluna de texto depende o tamanho da fonte atual do campo de texto. Se o texto digitado for mais largo que o campo de 10 colunas do objeto, a parte do texto direita no ficar visvel. O tratamento de eventos nesse exemplo realizado por um objeto da classe TrataEvento . Quando o usurio pressionar Enter em um JTextField ou no JPasswordField, o componente gera um ActionEvent (pacote java.awt.event), que processado por um objeto que implemente a interface ActionListener (pacote java.awt.event). Para que o evento no objeto GUI seja atendido necessrio registrar previamente o objeto handler no objeto GUI. Na classe acima, foi utilizado o mtodo actionPerformed de um objeto de tratamento de evento. No caso, a origem dos eventos o Enter nos campos de texto da janela e, quando isto ocorrer, o sistema cria um objeto ActionEvent nico que contm informaes sobre o evento que acabou de ocorrer, tais como a origem do evento e o texto do campo de texto e passa este objeto em uma chamada para o mtodo actionPerformed do ouvinte de eventos, ou listener de eventos. O mtodo getSource() da classe ActionEvent retorna uma referncia origem do evento e o mtodo getActionCommand, da mesma classe, retorna o texto do campo de texto.

Tratando eventos de componentes Swing


A seguir temos a classe TestaJanelaTexto que utiliza a classe acima. import javax.swing.JFrame; public class TestaJanelaTexto { public static void main( String args[] ) { JanelaTexto jan = new JanelaTexto (); jan.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jan.setSize(250, 120); jan.setVisible(true); } }

Tipos comuns de eventos


Existem diferentes tipos de eventos em uma interface GUI. Ao ocorrer um evento, as informaes sobre o evento so armazenadas em um objeto de uma classe que estende a classe AWTEvent. A hierarquia abaixo contm vrias classes de eventos do pacote java.awt.event. Estes tipos de eventos so utilizados tantos em objetos AWT como Swing. Eventos especficos para objetos Swing so declarados no pacote javax.swing.event. Object EventObject AWTEvent ActionEvent AdjustmentEvent ItemEvent TextEvent ComponentEvent

ContainerEvent FocusEvent PaintEvent WindowEvent KeyEvent InputEvent MouseEvent

Tipos comuns de eventos


O modelo de tratamento que vimos aqui conhecido como modelo de delegao de eventos, pois o processamento de um evento passado a um objeto particular no aplicativo, o objeto listener ou o ouvinte de eventos. Para cada tipo de evento, existe uma interface ouvinte de eventos. Um ouvinte de evento um objeto que implementa uma ou mais interfaces do pacote java.awt.event ou javax.swing.event. Veja algumas interfaces na caixa ao lado Cada interface ouvinte de eventos especifica os mtodos de tratamento de evento que interessem. Quando ocorre um evento, o componente da interface com o qual o usurio interagiu informa seus ouvintes registrados, chamando o mtodo de tratamento de evento adequado de cada ouvinte.

WindowListener ActionListener AdjustmentListener ComponentListener ContainerListener FocusListener ItemListener KeyListener MouseListener MouseMotionListener TextListener

Entendendo o funcionamento de eventos


l

Registrando eventos: Cada objeto JComponent, por exemplo JTextField , tem uma varivel de instncia chamada listenerList que referencia um objeto da classe EventListenerList do pacote javax.swing.event. Podemos entender listenerList como um array . Quando a instruo campo1.addActionListener (handler) executada, uma nova entrada que contm uma referncia ao objeto TextFieldHandler colocada na listenerList do JTextField campo1 . Ou seja, cada componente GUI mantm sua prpria lista de ouvintes que foram registrados para tratar os eventos do componente. Chamando o handler de evento: Cada componente GUI suporta vrios tipos de eventos: de mouse, de teclado, etc. Quando um evento ocorre, somente os mtodos apropriados dos ouvintes de eventos so afetados. Cada tipo de evento tem uma ou mais interfaces ouvintes de eventos correspondentes. ActionEvents so tratados por ActionListeners, MouseEvents so tratados por MouseListeners e MouseMotionListeners , e KeyEvents so tratados por KeyListeners . Quando ocorre um evento, um componente GUI recebe da JVM um ID do evento que especifica o tipo de evento. O componente GUI utiliza o ID para decidir o tipo de ouvinte a ser acionado e o mtodo a ser chamado no objeto ouvinte. Para que isto acontea, necessrio registrar um handler de evento no componente GUI para o tipo particular de evento que seu aplicativo exige, e o componente GUI far com que o mtodo apropriado do handler seja chamado.

O componente JButton
Um boto um componente que o usurio clica com o mouse para disparar uma ao especfica. Um aplicativo pode utilizar vrios tipos de botes: botes de comando, caixas de seleo e botes de opo. A classe JanelaBotoes cria 2 JButtons com cones, e realiza o tratamento de eventos dos botes em uma nica instncia da classe TrataBotao. import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JOptionPane; public class JanelaBotoes extends JFrame { private JButton botao1; private JButton botao2; public JanelaBotoes() { super("Testando Botes");

O componente JButton
setLayout(new FlowLayout()); botao1 = new JButton("Boto simples"); add(botao1); Icon bug1 = new ImageIcon( getClass().getResource("bug1.gif")); Icon bug2 = new ImageIcon( getClass().getResource("bug2.gif")); botao2 = new JButton("Boto com cone", bug1); botao2.setRolloverIcon(bug2); //icone de rollover add(botao2); TrataBotao handler = new TrataBotao(); botao2.addActionListener(handler); // registra handler botao1.addActionListener(handler); // registra handler }

O componente JButton
private class TrataBotao implements ActionListener{ public void actionPerformed(ActionEvent evento){ JOptionPane.showMessageDialog (JanelaBotoes.this, String.format("Voc cliclou no : %s", evento.getActionCommand())); } } } Os components JButtons, assim como os JTextFields, geram ActionsEvents que podem ser processados por qualquer objeto ActionListener. A classe TrataBotao declara o mtodo actionPerformed que exibe numa caixa de mensagem o rtulo do boto clicado pelo usurio.

O componente JButton
A classe TestaJanelaBotoes a seguir completa a aplicao. import javax.swing.JFrame; public class TestaJanelaBotoes{ public static void main(String args[]) { JanelaBotoes Jan = new JanelaBotoes(); Jan.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Jan.setSize( 300, 200 ); Jan.setVisible(true); } } As caixas de mensagens aparecem centralizadas na janela do aplicativo devido chamada do mtodo showMessageDialog, utilizar como primeiro argumento JanelaBotoes.this em vez de null. Este primeiro argumento indica o componente que ir conter (container) a caixa de dilogo.

Desafio
1.

Usando a interface KeyListener e o evento KeyEvent, implemente um handler para detectar e emitir uma mensagem quando uma tecla for apertada enquanto o foco estiver no componente botao2.

Aula 10 - Objetivo
l l l l

Introduzir mais alguns componentes de interfaces grficas Compreender o conceito de exceo Aprender a tratar excees nos programas Apresentar a clusula Throws

Recordando...
Na aula passada, vimos como criar uma interface grfica usando componentes do pacote Swing para entrada de dados (JTextField e JPasswordField ) pelo teclado e mouse (JButton). Hoje veremos mais dois componentes (JCheckBox e JRadioButton ). A seguir veremos como tratar os possveis erros gerados por comandos dentro do prprio programa.

O boto de estado JCheckBox


Os botes de estado JCheckBox e JRadioButton, descendentes do componente JToggleButton, trabalham com as informaes de ativado (verdadeiro) ou desativado (falso). Um JRadioButton diferente de um JCheckBox dado que vrios JRadioButton quando agrupados so mutuamente exclusivos, ou seja, somente um dos JRadioButton pode estar selecionado por vez. A classe a seguir utiliza dois objetos JCheckBox para selecionar o estilo desejado de fonte do texto exibido em um JTextField, um para o estilo negrito, outro para o estilo itlico. Ao iniciar o aplicativo, nenhum dos JCheckBox estar ativado.

O boto de estado JCheckBox


import java.awt.FlowLayout; import java.awt.Font; import java.awt.event.ItemListener; import java.awt.event.ItemEvent; import javax.swing.JFrame; import javax.swing.JTextField; import javax.swing.JCheckBox; public class JanelaComCheckBox extends JFrame{ private JTextField texto; private JCheckBox cb1; private JCheckBox cb2; // construtor adiciona JCheckBoxes e JTextField public JanelaComCheckBox() { super( "Testa CheckBox" ); // cria JFrame com ttulo setLayout( new FlowLayout() ); // define o layout texto = new JTextField("Fonte com novo estilo", 20); texto.setFont(new Font("Serif", Font.PLAIN,14));

O boto de estado JCheckBox


cb1 = new JCheckBox( "Negrito" ); //CheckBox Negrito cb2 = new JCheckBox( "Italico" ); //CheckBox Itlico add(cb1); //adiciona CheckBox de negrito ao Frame add(cb2); //adiciona CheckBox de itlico ao Frame CheckBoxHandler h=new CheckBoxHandler();// cria handler cb1.addItemListener(h); //registra o mesmo handler p/.. cb2.addItemListener(h); //..os dois controles CheckBox } // fim do construtor // classe interna para tratar o evento ItemListener private class CheckBoxHandler implements ItemListener { // controla o estilo de fonte negrito private int valNegrito = Font.PLAIN; // controla o estilo de fonte itlico private int valItalic = Font.PLAIN; // responde aos eventos de caixa de seleo public void itemStateChanged(ItemEvent event) { // processa eventos da caixa de seleo de negrito

O boto de estado JCheckBox


if (event.getSource() == cb1) valNegrito = cb1.isSelected()?Font.BOLD:Font.PLAIN; // processa eventos da caixa de seleo de itlico if (event.getSource() == cb2) valItalic = cb2.isSelected()?Font.ITALIC:Font.PLAIN; // configura a fonte do campo de texto texto.setFont(new Font("Serif", valNegrito + valItalic, 14)); } // fim do mtodo itemStateChanged } // fim da classe CheckBoxHandler } // fim da classe JanelaComCheckBox

O boto de estado JCheckBox


A classe TestaJanelaComCheckBox a seguir utilizada para testar a classe anterior. import javax.swing.JFrame; public class TestaJanelaComCheckBox{ public static void main( String args[] ) { JanelaComCheckBox janela = new JanelaComCheckBox(); janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); janela.setSize(275, 100); //configura tamanho da janela janela.setVisible(true); // exibe a janela } // fim do main }

O boto de estado JRadioButton


O boto de opo, instncia da classe JRadioButton, parecido com a caixa de seleo apresentada, pois. tambm tem dois estados, selecionado (verdadeiro) e no selecionado (falso). A classe a seguir utiliza botes que permitem que apenas um nico estilo de fonte seja selecionado por vez. import java.awt.FlowLayout; import java.awt.Font; import java.awt.event.ItemListener; import java.awt.event.ItemEvent; import javax.swing.JFrame; import javax.swing.JTextField; import javax.swing.JRadioButton; import javax.swing.ButtonGroup; public class JanelaComRadioButton extends JFrame { private JTextField texto; private Font normalFont; private Font negritoFont; private Font italicoFont; private Font negrItalFont;

O boto de estado JRadioButton


private JRadioButton normalRB; private JRadioButton negritoRB; private JRadioButton italicoRB; private JRadioButton negrItalRB; // buttongroup para armazenar botes de opo private ButtonGroup grupoRB; // construtor adiciona JRadioButtons ao JFrame public JanelaComRadioButton() { super("Testa RadioButton" ); setLayout(new FlowLayout()); texto = new JTextField("Mudando o estilo", 25 ); add(texto); // adiciona textField ao JFrame // cria botes de opo normalRB = new JRadioButton("Normal",true); negritoRB = new JRadioButton("Negrito",false); italicoRB = new JRadioButton("Italico",false); negrItalRB = new JRadioButton("Negrito/Itlico",false);

O boto de estado JRadioButton


add(negritoRB); // adiciona o boto de negrito add(italicoRB); // adiciona o boto de itlico add(negrItalRB);// adiciona boto de negrito/itlico // cria relacionamento lgico entre JRadioButtons grupoRB = new ButtonGroup(); // cria ButtonGroup grupoRB.add(normalRB); // adiciona boto ao grupo grupoRB.add(negritoRB); // adiciona boto ao grupo grupoRB.add(italicoRB); // adiciona boto ao grupo grupoRB.add(negrItalRB); // adiciona boto ao grupo // cria objetos fonte normalFont = new Font( "Serif", Font.PLAIN, 14 ); negritoFont = new Font( "Serif", Font.BOLD, 14 ); italicoFont = new Font( "Serif", Font.ITALIC, 14 ); negrItalFont = new Font( "Serif", Font.BOLD + Font.ITALIC, 14 ); texto.setFont(normalFont); // configura fonte inicial

O boto de estado JRadioButton


// registra eventos para JradioButtons normalRB.addItemListener( new RadioButtonHandler(normalFont)); negritoRB.addItemListener( new RadioButtonHandler(negritoFont)); italicoRB.addItemListener( new RadioButtonHandler(italicoFont)); negrItalRB.addItemListener( new RadioButtonHandler(negrItalFont)); }// fim do construtor RadioButtonFrame // classe interna para tratar eventos de boto de opo private class RadioButtonHandler implements ItemListener{ private Font font; // fonte associada com o listener public RadioButtonHandler(Font f) { font = f; // configura a fonte desse listener } // fim do construtor RadioButtonHandler

O boto de estado JRadioButton


// mtodo de tratamento dos eventos de boto de opo public void itemStateChanged(ItemEvent event) { texto.setFont(font); // configura fonte de texto } // fim do mtodo itemStateChanged } // fim da classe RadioButtonHandler interna e private } A classe TestaJanelaComRadioButton, a seguir, testa a classe anterior. import javax.swing.JFrame; public class TestaJanelaComRadioButton{ public static void main( String args[] ){ JanelaComRadioButton jan = new JanelaComRadioButton(); jan.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jan.setSize(300, 100); // define tamanho da janela jan.setVisible(true); // exibe a janela } // fim de main }

Ocorrncia de excees
Uma exceo uma indicao de um problema que ocorre durante a execuo de um programa. O tratamento da exceo permite que programadores gerem aplicativos que possam resolver situaes em que excees acorram, objetivando a continuidade na execuo, garantindo aos aplicativos caractersticas de robustez e tolerncia a falhas. Vejamos o que ocorre em um aplicativo que no utiliza tratamento de erro. A classe a seguir solicita do usurio dois inteiros e calcula seu quociente. Neste caso, podemos verificar que as excees so lanadas (ocorrem) quando um problema detectado e no h como trat-lo. import java.util.Scanner; public class GeraErro{// demonstra exceo de div. por zero public static int dividir(int numerador,int denominador){ return numerador / denominador; // possivel erro }

Ocorrncia de excees
public static void main(String args[]){ Scanner scanner = new Scanner( System.in ); System.out.print( "Entre com numerador inteiro: " ); int numerador = scanner.nextInt(); System.out.print( "Entre com denominador inteiro: " ); int denominador = scanner.nextInt(); int resultado = dividir (numerador, denominador); System.out.printf("\n %d / %d = %d\n", numerador, denominador, resultado); } // fim do main } Se executarmos o aplicativo anterior e digitarmos dois nmeros inteiros, sendo o segundo diferente de zero, o aplicativo executar normalmente informando o inteiro resultando da diviso dos dois nmeros. Se em uma execuo digitarmos para denominador o valor zero, ocorre erro e vrias linhas, conhecidas como rastreamento de pilha, so apresentadas. Neste caso, como no possvel dividir por zero, a exceo ArithmeticException do pacote java.lang lanada e uma informao extra / by zero fornece detalhes sobre a exceo especfica. Se, em outra execuo, digitarmos um caractere no numrico, gerada uma ocorrncia de InputMismatchException do pacote java.util . Note que nas linhas rastreamento de pilha, h informao da linha de cdigo em que a

Tratamento das excees


Reescrevemos o aplicativo anterior utilizando tratamento de excees para processar as ArithmeticExceptions e InputMismatchExceptions. A classe agora trata as excees de forma que, se o usurio cometer um erro, o programa captura e trata as excees, permitindo a re-insero dos dados. import java.util.InputMismatchException; import java.util.Scanner; public class TrataErro{ // demonstra o lanamento de excees public static int dividir(int numerador, int denominador) throws ArithmeticException{ return numerador / denominador; //possivel erro } // fim de mtodo quotiente public static void main( String args[] ) { Scanner ent = new Scanner(System.in); // determina se mais entradas so necessarias boolean continueLoop = true;

Tratamento das excees


do { try { System.out.print("Entre c/ numerador: " ); int numerador = ent.nextInt(); System.out.print("Entre c/ denominador: "); int denominador = ent.nextInt(); int resultado = dividir(numerador, denominador); System.out.printf("\n%d / %d = %d\n", numerador, denominador, resultado ); continueLoop = false; // entrada ok; fim de loop } // fim de try catch(InputMismatchException inputMismatchException){ System.err.printf( "\nExceo : %s\n", inputMismatchException ); // descarta entrada para nova tentativa ent.nextLine(); System.out.println("Entre com inteiros.\n"); } // fim de catch

Tratamento das excees


catch (ArithmeticException arithmeticException){ System.err.printf("\nExceo: %s\n", arithmeticException); System.out.println("Diviso por zero. + "Tente novamente.\n" ); } // fim de catch } while (continueLoop); // fim de do/while } // fim do main }

Tratamento das excees


A classe acima contm um bloco try que inclui o cdigo que pode lanar uma exceo, deixando claro que ao ocorrer uma exceo, o restante do cdigo a partir na instruo que ocasionou a exceo no executado. A instruo try consiste na palavra chave try seguida por um bloco de cdigo entre chaves {}, e normalmente nos referirmos como bloco try ao(s) comando(s) dentro da chaves da instruo try. O bloco try seguido por dois blocos catch, um que trata uma InputMismatchException e outro que trata uma ArithmeticException. Um bloco catch, tambm chamado de clusula catch ou handler de exceo, captura e trata a exceo. Um bloco catch inicia-se com a palavra-chave catch e seguido por um parmetro entre parnteses (parmetro de exceo) e um bloco de cdigo entre chaves. Da mesma forma, comum utilizarmos o termo bloco catch para designar o cdigo entre as chaves. Pelo menos um bloco catch ou um bloco finally deve se seguir imediatamente ao bloco try. Todo bloco catch especifica um parmetro de exceo entre parnteses que identifica o tipo de exceo que o handler pode processar. Quando uma exceo ocorre em um bloco try, o bloco catch que executado aquele que corresponde exatamente ao tipo da exceo que ocorreu ou a uma superclasse dela. O nome do parmetro de exceo permite ao bloco catch utilizar o objeto de exceo, como por exemplo, chamar implicitamente o mtodo toString da exceo capturada para exibir informaes bsicas sobre a exceo. Os programadores Java costumam utilizar simplesmente a letra e como o nome de parmetros de exceo.

Utilizando a clusula throws


Na aplicao anterior, especificamente na declarao do mtodo dividir utiliza-se a clusula throws . Esta declarao especifica que o mtodo pode lanar uma exceo em caso de erro. A referida clusula, sintaticamente, pode aparecer aps a lista de parmetros do mtodo e conter uma lista de excees separadas por vrgulas que o mtodo lanar se ocorrer um problema. Essas excees podem ser lanadas por instrues no corpo de mtodo ou por mtodos chamados no corpo. Um mtodo pode lanar excees das classes listadas em sua clusula throws ou de suas subclasses. No caso da classe TrataErro, os clientes do mtodo dividir() so informados que o mtodo pode lanar uma ArithmeticException. Todas as classes de exceo do Java herdam, direta ou indiretamente, da classe Exception, formando uma hierarquia de herana que pode ser estendida pelos programadores para formar sua prpria classe de exceo.

Utilizando a clusula throws

Utilizando a clusula throws


Vrias classes de exceo podem ser derivadas de uma superclasse comum. Se um handler catch for escrito para capturar objetos de exceo de um tipo de superclasse, ele tambm pode capturar todos os objetos de subclasses dessa classe. Se houver mltiplos blocos catch que correspondem a um tipo particular de exceo, somente o primeiro bloco catch correspondente executar na ocorrncia da exceo desse tipo. Se seguirmos a um bloco try, com um bloco catch para o tipo AtithmeticException e outro catch para o tipo Exception, somente o primeiro bloco correspondente executaria.

O Bloco Finally
Os programas que obtm certos recursos do ambiente operacional devem retorna-los para evitar os supostos vazamentos de recursos. O tipo mais comum o vazamento de memria. O Java realiza a coleta automtica de lixo de memria no mais utilizada por programas, evitando assim a maioria dos vazamentos de memria. Entretanto outros tipos de vazamentos podem ocorrer, como por exemplo, arquivos, conexes com bancos de dados, com redes que no so fechadas adequadamente e que talvez no fiquem disponveis para uso em outros aplicativos. O bloco finally, que tambm composto de chaves, opcional. Se estiver presente, este bloco colocado depois do ltimo bloco catch como mostrado a seguir. O Java garante que o bloco finally caso esteja presente, executar se uma exceo for lanada no bloco try correspondente ou quaisquer de seus blocos catch. Tambm executar se um bloco try fechar utilizando a instruo return , break ou continue. Entretanto no executar se o aplicativo fechar antes de um bloco try chamando o mtodo System.exit que encerra imediatamente o aplicativo. try{ } catch (TipoExceo1 exceo1){ } catch (TipoExceo2 exceo2){ } finally{ << instrues de liberao de recursos >>

Tratamentos aninhados
Se uma exceo que ocorre em um bloco try no puder ser capturada por handlers catch desse bloco try, o aplicativo pula o restante do bloco try e prossegue para o bloco finally. Ento o programa passa a exceo para o prximo bloco try externo caso haja, normalmente no mtodo chamador, onde um bloco catch pode captur-la. A classe a seguir mostra que o bloco finally ainda executar mesmo que no seja lanada uma exceo no bloco try correspondente. public class UsandoExceptions { public static void main( String args[] ) { try { lancaExcecao(); // chama mtodo throwException } // exceo lanada por throwException catch ( Exception e ) { System.err.println( "Exceo tratada no main" ); System.out.printf( "Exceo : %s\n", e ); } naolancaExcecao(); } // fim de main

Tratamentos aninhados
// demonstra try...catch...finally public static void lancaExcecao() throws Exception{ try { // lana uma exceo System.out.println( "Mtodo lancaExcecao" ); throw new Exception(); // gera a exceo } // captura exceo lanada em try catch ( Exception e ) { System.err.println( "Exceo tratada no mtodo lancaExcecao" ); System.out.printf( "Exceo : %s\n", e ); throw e; // Ateno: Lana novamente para // processamento adicional no main // qualquer cdigo aqui no seria alcanado } // fim de catch

Tratamentos aninhados
finally { // executa independentemente do que // ocorre em try...catch System.err.println( "Finally executado em lancaExcecao" ); } // fim de finally // qualquer cdigo aqui no seria atingido, // exceo lanada de novo em catch } // demonstra finally quando nenhuma exceo ocorrer public static void naolancaExcecao() { try { // bloco try no lana uma exceo System.out.println( "Mtodo naolancaExcecao" ); } // fim de try catch ( Exception e ) { // no executa System.err.println( e ); } // fim de catch

Tratamentos aninhados
finally { // executa independentemente do que ocorre // em try...catch System.err.println( "Finally executado em naolancaExcecao" ); } // fim de finally System.out.println( "Fim de naolancaExcecao" ); } }

Tratamentos aninhados
A instruo no mtodo throwException() throw new Exception(); conhecida como instruo throw e executada para informar a ocorrncia de uma exceo dizemos que o mtodo relana a exceo. Os programadores podem relanar excees utilizando essa instruo indicando a um mtodo cliente que ocorreu um erro. A instruo no mtodo lancaExcecao() throw e; relana a exceo. Excees so relanadas quando um bloco catch no pode processar uma exceo, ou s pode parcialmente. Relanar uma exceo adia o tratamento de exceo para outro bloco catch associado com uma instruo try externa. Uma exceo relanada utilizando a palavra-chave throw, seguida por uma referncia ao objeto de exceo que acabou de ser capturado. Um exceo no pode ser relanada de um bloco finally . No mtodo notthrowException() nenhuma exceo lanada no bloco try, ento o programa pula o bloco catch. Apesar disto, o bloco finally executado.

Desafio
1. Analise o cdigo a seguir: import javax.swing.*; import java.awt.*; public class TelaMensagem extends JFrame { private JButton btnExibir; private JTextField txtExibir; public TelaMensagem() { txtExibir = new JTextField(); btnExibir = new JButton(); getContentPane().setLayout( new FlowLayout()); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setResizable(false); txtExibir.setColumns(40); getContentPane().add(txtExibir); btnExibir.setText("Exibir"); getContentPane().add(btnExibir); pack(); } public static void main( String[] args ){ new TelaMensagem().setVisible(true); } Utilizando a linguagem Java escreva o cdigo que adicione um evento para o boto responsvel por exibir na tela o valor digitado na caixa de texto. Este valor deve ser um nmero positivo. Se esta condio no for atendida, o sistema deve capturar e tratar a exceo.

Aula 11 - Objetivos
l l l l

Introduzir mais alguns gerenciadores de layout Compreender o FlowLayout, BorderLayout, GridLayout Apresentar layouts mais complexos Revisar os conceitos aprendidos em um estudo de caso

Recordando...
Na aula passada, vimos como tratar os possveis erros gerados por comandos dentro do prprio programa. Continuamos, entretanto, a trabalhar com aplicaes grficas que usavam o mesmo tipo de layout (FlowLayout). Hoje veremos outros tipos de layout e treinaremos com o estudo de caso de uma aplicao completa para consolidar o aprendido.

Gerenciadores de layout
Para que possamos organizar a arrumao dos componentes GUI em um container, existem os de gerenciadores de layout. Em um layout bsico, como o que vimos at agora, em vez de determinar a posio e o tamanho exatos de cada componente GUI na janela, o programador apenas define a aparncia e o comportamento bsicos, deixando o gerenciador de layout encarregado dos detalhes de arrumao. Todos os gerenciadores implementam a interface LayoutManager do pacote java.awt. O mtodo setLayout da classe Container recebe como argumento um objeto que implementa a interface LayoutManager.

Gerenciadores de layout
H trs maneiras de organizar componentes em uma GUI:
1.

2.

3.

Posicionamento absoluto configurando o layout do container como null, possvel especificar o tamanho de cada componente e sua posio absoluta em relao ao canto superior esquerdo do container. Gerenciadores de layout Com eles mais simples e mais rpido criar uma GUI, mas normalmente se perde algum controle sobre o tamanho e posicionamento de controles GUI; Programao visual em um IDE Estes ambientes facilitam a criao de GUIs. Em geral, todo IDE visual fornece uma ferramenta de desenho GUI que permite arrastar e soltar componentes GUI de uma caixa de ferramentas em uma rea de desenho (janela). O IDE gera o cdigo que cria a GUI e, alm disso, possvel adicionar os cdigos de tratamento de eventos para os componentes.

BorderLayout
Este gerenciador, que o padro no JFrame, organiza componentes em cinco regies: NORTH, SOUTH, EAST, WEST e CENTER. A classe BorderLayout estende a classe Object e implementa a interface LayoutManager2, subinterface de LayoutManager que adiciona vrios mtodos para obter um processamento de layout mais aprimorado. Este gerenciador limita um Container a conter no mximo cinco componentes, um em cada regio, porm o componente da regio pode ser um outro container, no qual outros componentes podem ser anexados.

BorderLayout
A classe a seguir usa o BorderLayout. Os argumentos do construtor especificam o nmero de pixels dos espaos horizontal e vertical entre os componentes. Nela utilizada uma outra verso do construtor add da classe Container que aceita dois argumentos: o componente a adicionar e a regio em que o componente deve aparecer. import java.awt.BorderLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JButton; public class JanelaComBorderLayout extends JFrame implements ActionListener { private JButton botoes[];// array de botes private final String nomes[] = {"Esconde Norte", "Esconde Sul", "Esconde Leste", "Esconde Oeste", "Esconde Centro"}; private BorderLayout meuLayout; // objeto borderlayout public JanelaComBorderLayout() { // configura a GUI

BorderLayout
super( "Demonstrao do BorderLayout" ); // espaos de 5 pixels na vertical e na horizontal meuLayout = new BorderLayout( 5, 5); setLayout(meuLayout); // configura o layout do frame botoes = new JButton[nomes.length];// instancia array // cria botoes e registra ouvintes para eles for ( int cont = 0; cont < nomes.length; cont++ ){ botoes[cont] = new JButton(nomes[cont]);// cria boto botoes[cont].addActionListener(this);// registra } // final do for add(botoes[0], BorderLayout.NORTH); add(botoes[1], BorderLayout.SOUTH); add(botoes[2], BorderLayout.EAST); add(botoes[3], BorderLayout.WEST); add(botoes[4], BorderLayout.CENTER); } // fim do construtor BorderLayoutFrame

BorderLayout
// trata os eventos de boto public void actionPerformed(ActionEvent esteEvento){ // verifica a origem de evento e o painel de layout for (JButton botao : botoes) { if (esteEvento.getSource() == botao) botao.setVisible(false); //oculta boto clicado else botao.setVisible(true); // e mostra os demais } meuLayout.layoutContainer(getContentPane());//re-layout } // fim do mtodo actionPerformed }

BorderLayout
A classe a seguir utilizada para testar a classe JanelaComBorderLayout. import javax.swing.JFrame; public class TestaJanelaComBorderLayout{ public static void main( String args[] ) { JanelaComBorderLayout jan = new JanelaComBorderLayout(); jan.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jan.setSize( 400, 200 ); // tamanho da janela jan.setVisible(true); // exibe janela } }

BorderLayout
A classe acima implementa a interface ActionListener diretamente, da JanelaComBorderLayout tratar os eventos de JButtons. A linha buttons[cont].addActionListener(this); passa a referncia this para o mtodo addActionListener de cada JButton. Quando o usurio clica em um JButton particular no layout, o mtodo ActionPerformed executado. A instruo for utiliza um desvio condicional composto para ocultar o JButton particular que gerou o evento. A linha layout.layoutContainer( getContentPane() ); utiliza o mtodo layoutContainer para recalcular o layout do painel de contedo. As regies no BorderLayour alteram a forma quando JButtons so ocultados e exibidos em outras regies da seguinte forma: se todas as regies so ocupadas, o espao do container inteiro coberto por componentes GUI; se a regio NORTH ou SOUTH no for ocupada, os componentes das regies WEST, CENTER e EAST expandem-se verticalmente para ocupar o espao livre; se a regio CENTER no for ocupada, a rea deixada vazia os outros componentes no se expandem para o espao deixado por esta regio.

GridLayout
O GridLayout divide o container em uma grade de modo que os componentes podem ser colocados nas linhas e colunas. A classe GridLayout herda diretamente da classe Object, alm de implementar LayoutManager. Cada componente em um GridLayout tem a mesma largura e altura. Componentes GUIs so adicionados a partir da clula na parte superior esquerda da grade e continuando da esquerda para a direita at a linha estar cheia. O processo continua na linha abaixo.

GridLayout
A classe JanelaComGridLayout a seguir utiliza seis JButtons. import java.awt.GridLayout; import java.awt.Container; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JButton; public class JanelaComGridLayout extends JFrame implements ActionListener { private JButton botoes[]; private final String nomes[] = { "Um", "Dois", "Trs", "Quatro", "Cinco", "Seis" }; private boolean muda = true; // alterna entre layouts private Container container; // painel de contedo private GridLayout grid1; // primeiro gridlayout private GridLayout grid2; // segundo gridlayout public JanelaComGridLayout(){// construtor sem argumento

GridLayout
super( "Demostrao do GridLayout" ); grid1 = new GridLayout(2, 3, 5, 5); //grid 2x3 espao 5 grid2 = new GridLayout(3, 2);//grid 3x2 sem espao container = getContentPane(); //painel de contedo setLayout( grid1 ); // configura o layout botoes = new JButton[nomes.length]; // cria array for (int cont = 0; cont < nomes.length; cont++){ botoes[cont] = new JButton(nomes[cont]); botoes[cont].addActionListener(this); // adiciona o boto ao JFrame add(botoes[cont] ); } // for final } // fim do construtor // trata eventos de boto alternando entre layouts

GridLayout
public void actionPerformed( ActionEvent evento ){ if (muda) // configura layout como Segundo container.setLayout(grid2); else // configura layout como primeiro container.setLayout(grid1); muda = !muda; // alterna para valor oposto container.validate(); // refaz o layout do container } // fim do mtodo actionPerformed }

GridLayout
A classe TestaJanelaComGridLayout, a seguir, testa a classe acima. import javax.swing.JFrame; public class TestaJanelaComGridLayout { public static void main( String args[] ) { JanelaComGridLayout janela = new JanelaComGridLayout(); janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); janela.setSize( 400, 200 ); // configura a janela janela.setVisible(true); // exibe a janela } // fim de main } As linhas grid1 = new GridLayout( 2, 3, 5, 5 ); grid2 = new GridLayout( 3, 2 ); criam duas instncias de GridLayout. O primeiro construtor especifica um GridLayout com 2 linhas, 3 colunas e 5 pixels tanto para espaamento vertical com para o horizontal. O segundo objeto GridLayout especifica um gerenciador com 3 linhas, 2 colunas e espaamentos-padro de 1 pixel. A linha container.validate(); reformata, de outra maneira, um container cujo layout foi alterado. O mtodo validate () recalcula o layout do container com base no gerenciador atual para o container e o conjunto

Layouts mais complexos


Interfaces mais complexas exigem que cada componente seja colocado na posio exata. Normalmente se constituem de mltiplos painis, com componentes de cada painel organizados em um layout especfico. A classe JPanel estende JComponent , que por sua vez estende a classe JContainer, de modo que JPanel um container. Portanto, cada JPanel pode ter componentes, inclusive outros painis, anexados a ele com o mtodo add().

Layouts mais complexos


O aplicativo a seguir mostra um layout mais complexo com vrios JButtons colocados na regio South de um BorderLayout. import java.awt.GridLayout; import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JButton; public class JanelaComPainel extends JFrame { private JPanel painelBotoes; //painel p/ armazenar botes private JButton botoes[]; // array de botes public JanelaComPainel(){// construtor sem argumento super( "Demonstrao de Panel" ); botoes = new JButton[5]; // cria array de botes painelBotoes = new JPanel(); // configura painel painelBotoes.setLayout( new GridLayout( 1, botoes.length ) );

Layouts mais complexos


// cria e adiciona botes ao painel for ( int cont = 0; cont < botoes.length; cont++ ) { botoes[cont] = new JButton("Boto " + (cont + 1)); painelBotoes.add(botoes[cont]); //adiciona boto } // final do for add(painelBotoes, BorderLayout.SOUTH);//adiciona painel } // fim do construtor } A classe a seguir testa a classe JanelaComPainel apresentada. import javax.swing.JFrame; public class TestaJanelaComPainel extends JFrame { public static void main(String args[]){ JanelaComPainel janela = new JanelaComPainel(); janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); janela.setSize(450, 200); janela.setVisible(true); }

Layouts mais complexos


Depois do objeto painelBotoes ser declarado e instanciado, a instruo painelBotoes.setLayout(new GridLayout(1,botoes.length)); configura o layout como um GridLayout de 1 linha e 5 colunas. J a linha: painelBotoes.add(botoes[cont]); adiciona os botes diretamente ao JPanel, dado que JPanel no tem painel de contedo conforme um JFrame . Logo aps, utilizado o padro default BorderLayout para adicionar buttonJPanel regio South . A regio South ficar to grande quanto os botes no buttonJPanel. Um JPanel dimensionado aos componentes que ele contm. medida que mais componentes so adicionados, o JPanel cresce.

Desafio
1.

Uma empresa solicita o desenvolvimento de um software que jogue xadrez sozinho contra humanos. Para isso preciso ter a informao de como se move cada pea dentro do jogo, e seu respectivo grau de importncia. O rei, por exemplo, s se move uma casa em qualquer direo e a pea mais importante, ao passo que a rainha se move o quanto quiser em qualquer direo e a segunda pea mais importante. A princpio, dada uma posio X, Y toda pea pode se mover para l. Se necessrio, cada pea especfica define sua maneira de se mover e sua hierarquia no jogo. Ateno deve ser dada aos conceitos de orientao a objeto como herana e encapsulamento. Informe a nova posio de uma pea, aps cada movimento dela. l Com base no diagrama UML a seguir, utilizando a linguagem Java, implemente todas as classes dos diagramas abaixo, encapsulando obrigatoriamente todos os atributos. l Implemente o mtodo mover() para movimentar o Rei, gerando uma exceo quando houver tentativa de movimentar o Rei com distncia maior que uma casa.

Desafio

Desafio
Utilizando a linguagem Java escreva o cdigo que adicionaria um evento para o boto responsvel por exibir na tela o valor digitado na caixa de texto. Este valor deve ser um nmero positivo. Se esta condio no for atendida, o sistema deve levantar uma exceo. import javax.swing.*; import java.awt.*; import java.awt.event.*; public class TelaMensagem extends JFrame { private JButton btnExibir; private JTextField txtExibir; public TelaMensagem() { txtExibir = new JTextField(); btnExibir = new JButton(); getContentPane().setLayout(new FlowLayout()); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setResizable(false); txtExibir.setColumns(40); getContentPane().add(txtExibir); btnExibir.setText("Exibir"); getContentPane().add(btnExibir); pack(); } public static void main( String [] args ){ new TelaMensagem().setVisible(true); }
2.

Desafio
3.

Crie um programa em Java para manipular a classe Rainha criada na questo nmero 1. Este programa recebe como parmetro de linha de comando a posio inicial da pea.e deve mov-la para a posio 2, 4. Antes e depois de mover a pea, escreva na tela para onde ela est. Orientaes: Pode-se partir do princpio que o usurio sempre informar os dados necessrios na linha de comando; Utilize os mtodos de manipulao do objeto para escrever e ler suas propriedades, inclusive na hora de escrev-las na tela.

Aula 12 - Objetivos
l

Revisar os conceitos aprendidos em um estudo de caso

Recordando...
Na aula passada, vimos outros tipos de layout e treinamos com o estudo de caso de uma aplicao completa para consolidar o aprendido. Hoje veremos outro estudo de caso. importante que voc faa o estudo de hoje, procurando consultar as aulas passadas para identificar onde se encontra a teoria associada e qual a sintaxe dos comandos. Mos obra!

Estudo de caso
1.

Uma academia de ginstica possui um programa para calcular a quantidade mxima de batimentos cardacos a que cada atleta deve ser submetido durante os exerccios. Cada pessoa possui uma matrcula e so mantidas informaes sobre o peso, a idade de cada atleta, fatores que so levados em considerao para o clculo dos batimentos cardacos mximos. O diagrama abaixo mostra uma parte das classes existentes. O batimento cardaco mximo dos homens deve ser equivalente a um valor base (peso + idade). O batimento cardaco mximo das mulheres deve ser equivalente ao valor base (peso + idade), caso tenham at 60 anos. Para mulheres a partir de 61 anos os anos excedentes a 60 devem ser descontados em dobro do valor base. Os homens, quando estiverem se preparando para alguma competio, podem ter seu batimento bsico acrescido de um valor que varia de indivduo para indivduo.

Estudo de caso

Estudo de caso
o valor do possvel incremento a ser somado ao batimento mximo (no caso de homem em preparao para competio) e escrever no console de sada a matrcula da pessoa armazenada e a batimento cardaco mximo calculado. Nesta questo obrigatria a chamada dos mtodos polimrficos de clculo do batimento mximo, bem como dos mtodos de manipulao dos atributos.

Estudo de caso
Analise o cdigo Java abaixo: import javax.swing.*; import java.awt.*; public class TelaTeste extends JFrame { private JLabel rotulo; private JButton botao; private JTextField texto; public TelaTeste () { super("Tela de teste"); setLayout(new FlowLayout()); rotulo = new JLabel("Digite a idade do atleta:" ); texto = new JTextField(10); botao = new JButton("Conferir"); add(rotulo); add(texto); add(botao); pack();
2.

Estudo de caso
public static void main( String[] args ){ TelaTeste tela = new TelaTeste(); t.setVisible(true); t.setDefaultCloseOperation(EXIT_ON_CLOSE); } } Escreva em Java o cdigo para registrar e tratar o evento de click no boto. A rotina de tratamento deve ler um valor inteiro de uma caixa de texto e exibir uma janela com a mensagem Criana, caso a idade seja at 11 anos, Adolescente, caso a idade seja entre 12 e 17 anos e Adulto caso a idade seja maior ou igual a 18 anos. Caso o valor digitado seja negativo deve ser exibida uma janela com a mensagem Idade deve ser positiva.. Caso, ainda, o texto no seja um inteiro vlido, o sistema deve tratar a exceo e exibir uma janela com a mensagem Valor digitado no um nmero inteiro.