You are on page 1of 44

Programação Orientada a Objetos

UNESA - Universidade Estácio de Sá


Análise de Sistemas de Computação
Professor: Ângelo Stroligo Pecly
Programação Orientada a Objetos

1- Introdução à programação Java

Em torno de 1990, uma equipe da SUN Microsystems, liderada por James Gosling foi
incumbida de desenvolver programas para controlar aparelhos eletrônicos. A linguagem
inicialmente utilizada foi C++, mas, com o decorrer do tempo, essa equipe se deparou com
várias dificuldades inerentes ao C++ (tais como herança múltipla e ponteiros). Para contornar
essas dificuldades foi desenvolvida a linguagem Oak, que tinha a mesma estrutura do C++, só
que sem os detalhes que o tornava complicado para controlar aparelhos eletrônicos.
A linguagem Oak foi utilizada na construção do sistema Star Seven (que possibilita o
controle de vários aparelhos eletrônicos de uma casa através do toque em uma tela) e de um
sistema de televisão interativa. Apesar de nenhum dos dois projetos terem se tornado
produtos, a linguagem Oak, com o decorrer do tempo, pôde amadurecer. Tendo em vista que
o nome Oak já havia sido reivindicado, a SUN passou a chamar a linguagem Oak de Java.
Em 1993, a Internet passou a suportar WWW, deixando de ser composta somente de
texto e adotando um ambiente gráfico. Com isso, a SUN adaptou a já poderosa (independente
de plataforma, segura e simples) linguagem Java para esse novo mundo, criando o recurso de
Applet. Para mostrar que Java era uma linguagem robusta, a SUN implementou um browser, o
HotJava.
Em meados de 1995 a linguagem Java foi lançada oficialmente, e passou a ser
incorporada aos browsers da Netscape e da Microsoft.

1.1- As suas Características

✗ Simples: Java eliminou as dificuldades herdadas do C++ e adicionou


facilidades, tal como Garbage Collector;
✗ Orientada a Objetos: Java é pura (totalmente OO) e agrega um grande
conjunto de classes em suas bibliotecas;
✗ Distribuída: Suporta aplicações em rede e objetos distribuídos (RMI);
✗ Segura: Verifica o byte-code antes da execução;
✗ Robusta: O interpretador permite tratamento de exceções e não permite que
uma aplicação paralise o sistema (projetada para software confiável);
✗ Plataforma Independente: Java, por ser interpretada, pode rodar em
qualquer plataforma (desde que esta tenha o interpretador);
✗ Alta Performance: Mais rápida que linguagens script (em browsers) e passível
de compilação just-in-time (JIT);
✗ Multi-tarefa: Pode-se executar threads simultaneamente;

1.2- Os 3 Alicerces

Tradicionalmente, as linguagens de programação são avaliadas por três parâmetros:


velocidade, segurança e portabilidade. O ideal é uma linguagem que tenha um equilíbrio entre
estes três alicerces, pois a deficiência em algum desses itens pode comprometer o sucesso do
software que está sendo desenvolvido. Abaixo, é apresentado graficamente a relevância de
cada um destes alicerces nas linguagens C++, Java, Smalltalk e Tcl.
Programação Orientada a Objetos

1.3- Principais diferenças

Por questões de segurança, simplificação, e por ser uma linguagem OO pura, Java não
utiliza:
✗ Structures e unions;
✗ #define;
✗ Ponteiros;
✗ Herança múltipla;
✗ Funções;
✗ Goto;

Em compensação Java adicionou:


✗ Garbage collector automático;
✗ Acoplamento dinâmico;

1.4- JVM (Java Virtual Machine)

Para que Java conseguisse atingir independência de plataforma, a SUN optou por uma
arquitetura independente (máquina virtual), para a qual um código fonte Java é compilado. O
código fonte (programa.java), após compilado, se transforma em byte-code (programa.class).
Esse byte-code atualmente não pode ser executado em nenhuma arquitetura, mas pode ser
interpretado em várias arquiteturas, desde que estas tenham um interpretador Java instalado.
Veja abaixo como ocorrem as mudanças <código fonte>  <byte-code (plataforma
independente)>  <binário (plataforma dependente)>:

Interpretador 1001110111
Programa Java Meu
Programa

MeuPrograma.java MeuPrograma.class

Compilador

O interpretador Java é uma implementação da máquina virtual Java, voltada para uma
determinada plataforma. Um código fonte Java é compilado somente uma vez, mas será
interpretado quantas vezes forem necessárias a sua execução.

MeuPrograma.java
Programa Java Compilador

Interpretador Interpretador

Meu
Meu Programa
Programa

Palm PC
Programação Orientada a Objetos

1.5- Ambientes de Desenvolvimento

Já existem no mercado vários ambientes para desenvolvimento em Java. O ambiente


que define os padrões é o JDK, desenvolvido pela SUN. A grande vantagem do JDK é ser
freeware, mas ele não possui interface gráfica e nem apresenta suporte adequado à sua
construção.
Outro ambiente bastante conhecido é o Jbuilder, fabricado pela Inprise. As suas
grandes vantagens são a interface gráfica padrão Delphi/CBuilder, suporte à construção de
interface gráfica e o seu depurador gráfico. Abaixo, segue uma tabela com os ambientes mais
utilizados, fabricante, e onde encontrar informações úteis:

Ambiente Fabricante Referência


JDK SUN http://www.javasoft.com/products/jdk/1.1/index.html
Jbuilder Inprise http://www.inprise.com/jbuilder
JCreator Xinox Software Http://www.jcreator.com
Visual J++ Microsoft http://msdn.microsoft.com/visualj

1.5.1- Introdução ao JDK (Java Development Kit)

Nesta seção, apresentamos as ferramentas mais utilizadas no JDK1.3:

✗ javac

Descrição Compilador Java


Função Transformar código fonte em byte-code
Sintaxe javac [opções] codigofonte.java
opções mais utilizadas:
-classpath diretório Diretório de classes utilizadas pelo programa.
-d diretório Diretório destino para os byte-codes.
-g Cria tabelas de debug.
-deprecation Exibe a localização de métodos obsoletos.
-nowarn Não exibe advertências.
-o Tenta otimizar o byte-code a ser gerado.
-verbose Exibe informações de status
-depend Causa a recompilação das classes dependentes de
códigofonte.java
Exemplo javac Button.java

✗ Java

Descrição Interpretador Java


Função Executar programas (byte-codes) escritos em Java
Sintaxe java [opções] nomedaclasse <args>
opções mais utilizadas:
-debug Executa o debug.
-classpath diretório Diretório de classes utilizadas pelo programa.
-mxx Quantidade máxima de memória para a seção.
-msx Quantidade de memória para a inicialização.
-noasyncgc Não utiliza coleta de lixo assíncrona.
-noclassgc Desliga a coleta de lixo automática para classes.
-nojit Desabilita a compilação just-in-time.
-version Exibe informações sobre versão.
-help Exibe informações sobre utilização.
-ssx Tamanho da pilha para código C.
-ossx Tamanho da pilha para código Java.
-v, -verbose Exibe informações de status.
-verify Verifica o código Java.
-verifyremote Verifica o código Java carregado de um classloader.
-noverify Não verifica o código Java.
Programação Orientada a Objetos

-verbosegc Exibe informações de status do coletor de lixo.


-DpropertyName=newValue Configura valores de propriedades.
Exemplo java Button

1.6- Declaração de variáveis

Uma variável é um nome definido pelo programador ao qual pode ser associado um
valor pertencente a um certo tipo de dados. Em outras palavras, uma variável é uma porção
de memória, identificada por um nome, que é capaz de armazenar um valor de um certo tipo.
Desta forma toda variável possui um nome, um tipo, um conteúdo e um endereço de memória.
O nome de uma variável em Java pode ser uma seqüência de um ou mais caracteres
alfabéticos e numéricos, iniciados por uma letra ou ainda pelos caracteres ‘_’ (underscore) ou
‘$’ (cifrão). Os nomes não podem conter outros símbolos gráficos, operadores ou espaços em
branco, podendo ser arbitrariamente longos embora apenas os primeiros 32 caracteres serão
utilizados para distinguir nomes de diferentes variáveis. É importante ressaltar que as letras
minúsculas são consideradas diferentes das letras maiúsculas, ou seja, a linguagem Java é
sensível à caixa, assim temos como exemplos válidos:

a total x2 $min
_especial VALOR Maximo ExpData

Seguindo as mesmas regras temos abaixo exemplos inválidos de nomes de


variáveis:

1x Total geral numero-minimo void

A razão deste nomes serem inválidos é simples: o primeiro começa com um


algarismo, o segundo possui um espaço em branco, o terceiro contém o operador de
subtração, mas por que o quarto é inválido?
Porque além das regras de formação de nome em si (identificadores), uma variável
não pode utilizar como nome uma palavra reservada da linguagem. As palavras reservadas são
os comandos e nomes dos tipos primitivos.
As palavras reservadas da linguagem Java, que portanto não podem ser utilizadas
como nome de variáveis ou outros elementos, são:

abstract do implements private throw


boolean double import protected throws
break else instanceof public transient
byte extends int return true
case false interface short try
catch final long static void
char finally native super volatile
class float new switch while
continue for null if default
synchronized package this

Além destas, existem outras que embora reservadas não são usadas pela linguagem:

const future generic goto inner


operator outer rest var volatile

Algumas destas, tal como o goto, faziam parte da especificação preliminar do Oak,
antes de sua formalização como Java. Recomenda-se não utilizá-las qualquer que seja o
propósito.
Programação Orientada a Objetos

Desta forma para declararmos uma variável devemos seguir a seguinte sintaxe:

tipo nome1 [, nome2 [, nome3 [ …, nomeN]]];

Ou seja, primeiro indicamos um tipo, depois declaramos uma lista contendo um ou


mais nomes (identificadores) de variáveis desejadas deste tipo, onde nesta lista os nome são
separados por vírgulas e a declaração terminada por ‘;’ (ponto-e-vírgula). Veja alguns
exemplos:

int i;
float total, preco;
byte mascara;
double valorMedio;

Também é possível definirmos um valor inicial para uma variável diretamente em sua
declaração:

int quantidade = 0;
float angulo = 1.57;
boolean ok = false;
char letra = ‘c’;

Variáveis podem ser declaradas em qualquer ponto de um programa Java, sendo


válidas em todo o escopo onde foram declaradas e nos escopos internos à estes. Por escopo
entende-se o bloco (conjunto de comandos da linguagem) onde ocorreu a declaração da
variável.

1.7- Programa “Hello World”

// HelloWorld.java
public class HelloWorld {
public static void main (String args[]) {
System.out.println("Hello World!");
}
}

Compilando um primeiro programa

✗ Certifique-se de ter adicionado a sua lista de path’s o path do compilador e


interpretador Java. (javac e java respectivamente)
✗ Crie o arquivo acima em um diretório e salve-o com o nome: HelloWorld.Java
✗ Chame o compilador Java para este arquivo: javac HelloWorld.Java
✗ Seu diretório deve ter recebido um novo arquivo após essa compilação:
HelloWorld.class
✗ Chame o interpretador Java para este arquivo (omita a extensão .class de arquivo):
java HelloWorld

Resolvendo os eventuais problemas

Se você se tiver digitado tudo ao envés de usar “copy and paste”, é bem provável que
ele não compile, se isto ocorrer, leia atentamente o programa. Você não esqueceu nenhum
ponto e vírgula? E as chaves? HelloWorld começa com letra maiúscula, e isso faz diferença,
você foi coerente com a convenção adotada de letras maiúsculas e minúsculas para seus
identificadores?
Você estava no mesmo diretório de HelloWorld.java quando chamou o compilador? E
quando chamou o interpretador, também?
Se ainda não der certo, não se desespere, leia as explicações passo a passo do
programa e depois recorra a um usuário mais experiente. Normalmente a Java é muito fácil de
Programação Orientada a Objetos

se programar, e você precisará de pouca ajuda, o seu interesse o fará cada vez mais familiar
com esta linguagem.

Explicação passo a passo do programa exemplo:

// HelloWorld.java
Comentários em Java seguem a mesma sintaxe de C++, “//” inicia uma linha de
comentário, todo o restante da linha é ignorado. Existe também um outro tipo de comentário
formado por /* Insira aqui o texto a ser ignorado */ , este tipo de comentário pode ser
intercalado em uma linha de código. Comentários são tratados como espaços em branco.

public class HelloWorld {


Na declaração acima class é a palavra reservada que marca o início da declaração de
uma classe. O termo “public” é um qualificador, por enquanto guarde public class como o início
da declaração de uma classe.
“HelloWorld” é o nome dado a esta classe. O “abre chaves” marca o início das
declarações da classe que são os atributos e métodos. Esta classe só possui uma declaração, a
do método main, note que um método, ao contrário de C++, só pode ser declarado
{internamente} a classe a qual pertence, evitando as confusões sobre “escopo”. Desta forma,
todo pedaço de código em Java deve pertencer ao “abre chaves”, “fecha chaves” da definição
de uma classe.

public static void main (String args[]) {


public
É um qualificador do método que indica que este é acessível externamente a esta
classe (para outras classes que eventualmente seriam criadas).
static
É um outro qualificador que indica que o método deve ser compartilhado por todos os
objetos que são criados a partir desta classe. Os métodos static podem ser invocados, mesmo
quando não for criado nenhum objeto para a classe, para tal deve-se seguir a sintaxe:
<NomeClasse>.<NomemetodoStatic>(argumentos);
Retornaremos a esta explicação mais tarde, por hora você precisa saber que
particularmente o método main precisa ter essa qualificação porque ele é chamado sem que se
crie nenhum objeto de sua classe.
void
Semelhante ao void do C++ ou C, é o valor de retorno da função, quando a função
não retorna nenhum valor ela retorna void, uma espécie de valor vazio que tem que ser
especificado.
main
Este é um nome particular de método que indica para o compilador o início do
programa, é dentro deste método e através das iterações entre os atributos, variáveis e
argumentos visíveis nele que o programa se desenvolve.
String args[]
É o argumento de main e por conseqüência do programa todo, ele é um vetor de
Strings que é formado quando são passados ou não argumentos através da invocação do
nome do programa na linha de comando do sistema operacional, exemplo:

java HelloWorld argumentotexto1 argumentotexto2

{ }
“Abre chaves” e “fecha chaves”. Para quem não conhece C ou C++, eles podem ser
entendidos como algo semelhante ao BEGIN-END de Pascal ou Modula-3, ou seja: delimitam
um bloco de código. Os programadores Pascal notarão que variáveis locais dos métodos
podem ser declaradas em qualquer local entre as chaves. Mas por motivos de clareza do
código declararemos todas no início do bloco.

System.out.println("Hello World!");
Chamada do método println para o atributo out da classe ou objeto System, o
Programação Orientada a Objetos

argumento é uma constante do tipo String. println assim como writeln de Pascal, imprime a
String e posiciona o cursor na linha abaixo , analogamente print não avança linha. Por hora
você pode guardar esta linha de código como o comando para imprimir mensagens na tela,
onde o argumento que vem entre aspas é a String a ser impressa. O ; “ponto e vírgula” separa
operações.

}
Finalmente o fecha chaves termina com a declaração da classe HelloWorld.

Conclusão
Normalmente o volume de conceitos presentes num primeiro programa de uma
linguagem orientada a objetos como Java é grande se comparado com o de um primeiro
programa em C ou Pascal. Esses conceitos ainda serão aprofundados e são citados aqui apenas
por curiosidade, é normal que você não tenha entendido tudo.

Exercícios:
1- Experimente fazer modificações no programa HelloWorld. Imprima outras
mensagens na tela, adicione comentários.

2- A Linguagem Java

2.1- Comentários
Comentários são trechos de texto, usualmente explicativos, inseridos no programa de
forma que não sejam considerados como parte do código, ou seja, são informações deixadas
juntamente com o código como informação para quem programa.
O Java aceita três tipos de comentários:

➢ de uma linha
➢ de múltiplas linhas
➢ de documentação

O primeiro, de uma linha, utiliza duas barras (//) para marcar seu início:

// comentário de uma linha


// tudo após as duas barras é considerado comentário

O segundo usa a combinação /* e */ para delimitar uma ou mais linhas de


comentários:

/* comentário
de múltiplas linhas */

O último tipo é semelhante ao comentário de múltiplas linhas, mas tem o propósito de


documentar o programa:

/* comentário de documentação que também


podem ter múltiplas linhas
*/

Geralmente o comentário de documentação é posicionado imediatamente antes do


elemento a ser documentado e tem seu conteúdo extraído automaticamente pelo utilitário
javadoc fornecido juntamente com o JDK. Esta ferramenta gera páginas em formato html
contendo os comentários organizados da mesma forma que a documentação fornecida
juntamente com o JDK.
Aproveitando tal característica do javadoc, usualmente se adiciona tags html aos
comentários de documentação para melhorar a forma final da documentação produzida, com a
inclusão de imagens, tabelas, textos explicativos, links e outros recursos. Além das tags html
Programação Orientada a Objetos

vários tipos de informações administrativas podem ser adicionadas a estes comentários


especiais através de marcadores pré-definidos iniciados com “@” que permitem a criação
automática de ligações hipertexto entre a documentação e a formatação padronizada de outros
elementos, tais como nome do autor, parâmetros, tipo de retorno, etc.

/* Classe destinada ao armazenamento de dados


relacionados a arquivos ou diretórios.
<p> Pode ser usada para armazenar árvores de diretórios.
@autor Peter Jandl Jr.
@see java.io.File
*/
public class FileData extends File {
/* Construtor
@param filename nome do arquivo
*/
public FileData(String filename) {
}
}

2.2- Constantes
Quando uma variável (atributo) é declarada como final, seu conteúdo não poderá ser
modificado (é uma constante). Veja o exemplo:

final float aceleracaoDaGravidade = 9.8

Todas as regras para a declaração de variáveis são também válidas para a declaração
de constantes.

2.3- Tipos Primitivos


Os tipos primitivos em Java, diferentemente de objetos (que necessitam de
construção e são tratados por referência), não necessitam de construção (instanciação através
da palavra reservada new) e são tratados por valor. Esses tipos são:

Tipo Tamanho/Formato Descrição


(números inteiros)
Byte 8-bit complemento a dois Inteiro de tamanho de um byte
Short 16-bit complemento a dois Inteiro curto
Int 32-bit complemento a dois Inteiro
Long 64-bit complemento a dois Inteiro longo
(números reais)
Float 32-bit IEEE 754 Ponto flutuante
Double 64-bit IEEE 754 Ponto flutuante de precisão dupla
(outros tipos)
Char 16-bit caracter Unicode Um único caracter
Boolean true ou false Um valor booleano

Abaixo seguem trechos de código para auxiliar a compreensão da sintaxe de


declaração de tipos primitivos:

byte tamanhoDoPe = 38;


int numeroDaPorta = 4096;
numeroDaPorta += 40; //passa a conter 4136
float nota = 7.25F; //F indica que o numero é um float
final boolean VERDADE = true; //Constante VERDADE com valor true

Apesar de String não ser um tipo primitivo, ele pode ser visto como um, pois pode ser
construído diretamente, sem o uso de new, como está descrito no exemplo a seguir:
Programação Orientada a Objetos

//cria uma String com o valor “Exemplo!!!”


String texto = “Exemplo!!!”;
System.out.println(texto); // mostra a String

2.4- Operadores

2.4.1- Operadores aritméticos

Operador Uso Descrição


+ op1 + op2 Soma op1 com op2
- op1 - op2 Subtrai op2 de op1
* op1 * op2 Multiplica op1 por op2
/ op1 / op2 Divide op1 por op2
% op1 % op2 Calcula o resto da divisão (módulo) de op1 por op2
++ op++ Incrementa op de 1; utiliza o valor antes de incrementar
++ ++op Incrementa op de 1; utiliza o valor depois de incrementar
-- op-- Decrementa op de 1; utiliza o valor antes de incrementar
-- --op Decrementa op de 1; utiliza o valor depois de incrementar

2.4.2- Operadores relacionais

Operador Uso Retorna verdadeiro se


> op1 > op2 op1 é maior que op2
>= op1 >= op2 op1 é maior ou igual que op2
< op1 < op2 op1 é menor que op2
<= op1 <= op2 op1 é menor ou igual que op2
== op1 == op2 op1 e op2 são iguais
!= op1 != op2 op1 e op2 são diferentes

2.4.3- Operadores condicionais

Operador Uso Retorna verdadeiro se


Ambos op1 e op2 são verdadeiros. Avalia a expressão op1 e
&& op1 && op2
condicionalmente avalia a expressão op2
Ou op1 ou op2 é verdadeiro. Avalia a expressão op1 e
|| op1 || op2
condicionalmente avalia a expressão op2
! ! op op é falso
& op1 & op2 Ambos op1 e op2 são verdadeiros. Sempre avalia op1 e op2
| op1 | op2 Ou op1 ou op2 é verdadeiro. Sempre avalia op1 e op2

2.4.4- Operadores de atribuição

Operador Uso Equivalente a


+= op1 += op2 op1 = op1 + op2
-= op1 -= op2 op1 = op1 – op2
*= op1 *= op2 op1 = op1 * op2
/= op1 /= op2 op1 = op1 / op2
%= op1 %= op2 op1 = op1 % op2
&= op1 &= op2 op1 = op1 & op2
|= op1 |= op2 op1 = op1 | op2
^= op1 ^= op2 op1 = op1 ^ op2
<<= op1<<=op2 op1 = op1 << op2
>>= op1>>=op2 op1 = op1 >> op2
>>>= op1>>>=op2 op1 = op1 >>> op2

2.4.5- Operadores de bit

Operador Uso Operação


>> op1 >> op2 desloca os bits de op1 para a direita de uma distância op2
Programação Orientada a Objetos

<< op1 << op2 desloca os bits de op1 para a esquerda de uma distância op2
>>> op1>>>op2 desloca os bits de op1 para a direita de uma distância op2 (sem
sinal)
& op1 & op2 e de bits
| op1 | op2 ou de bits
^ op1 ^ op2 ou exclusivo de bits
~ ~op2 complemento de bits

2.5- Modificadores
Os modificadores (ou qualificadores) de visibilidade indicam o nível de acesso ao
método ou atributo. Na tabela a seguir, temos todos os níveis possíveis e suas visibilidades:

Modificador Visibilidade
Private Somente dentro da classe
Sem modificador Em todas as classes do mesmo pacote
Protected Em todas as classes do mesmo pacote e em subclasses
Public Todas as classes

2.6- Comandos de entrada e saída de dados

➢ Saída
Normalmente, em programação, quando nos referimos à saída de dados estamos
particularmente interessados em exibir mensagens no monitor do computador. Java possui
alguns comandos para saída de dados, dentre eles, destacamos apenas três:

System.out.println(“Olá Mundo!!!”);
Este comando mostra a mensagem delimitada entre as aspas no monitor e salta para
a próxima linha para que uma nova saída não apareça na mesma linha.

System.out.print(“UNESA”);
Este comando exerce, essencialmente, a mesma função do anterior, porém, ele não
salta para a próxima linha, ou seja, um novo comando exibirá um novo texto na mesma linha.

System.out.printf(“AV1=%d”,nota);
Este comando permite um maior poder de formatação da saída. Aqui pode-se utilizar
todos os recursos de formatação existente na linguagem C.

➢ Entrada
Java se popularizou essencialmente pela programação voltada à Internet e ao
ambiente gráfico. Esta característica fez com que suas primeiras versões fossem deficientes
nas operações de entrada de dados em modo texto. Nos primórdios desta linguagem, se
utilizava a entrada de dados por parâmetros (String args[]), porém as versões mais
recentes contornaram o problema e já é possível efetuar a entrada de dados de forma
razoavelmente simples. Veja um exemplo de programa que obtém dois números inteiros do
teclado e exibe a soma deles.

import java.util.Scanner;
public class Adicao {
public static void main(String args[]) {

Scanner input = new Scanner(System.in);

int n1,n2,soma;

System.out.print(“Entre com o primeiro número: ”);


n1 = input.nextInt();
Programação Orientada a Objetos

System.out.print(“Entre com o segundo número: ”);


n2 = input.nextInt();

soma=n1+n2;
System.out.println(“A soma é ”+soma);
}
}

O exemplo acima mostra como pode ser efetuada a entrada de números inteiros, para
outros tipos de dados, basta alterar/adaptar o método input.next???(), para cada tipo de
dado.

Tipo Método
int input.nextInt()
String input.next()
float input.nextFloat()
double input.nextDouble()
char Input.nextChar()

2.7- Controle de Fluxo


Um programa de computador é uma seqüência de instruções organizadas de forma tal
a produzir a solução de um determinado problema. Naturalmente tais instruções são
executadas em seqüência, o que se denomina fluxo seqüencial de execução. Um inúmeras
circunstâncias é necessário executar as instruções de um programa em uma ordem diferente
da estritamente seqüencial. Tais situações são caracterizadas pela necessidade da repetição de
instruções individuais ou grupos de instruções e também pelo desvio do fluxo de execução.
As linguagens de programação tipicamente possuem diversas estruturas de
programação destinadas ao controle do fluxo de execução, isto é, estruturas que permitem a
repetição e o desvio do fluxo de execução. Geralmente as estruturas de controle de execução
são divididas em:

Tipo Palavra chave


Decisão if-else, switch-case
Repetição for, while, do-while
Exceção try-catch-finally, throw
Outros break, continue, label, return

Antes de tratarmos especificamente das estruturas de controle da linguagem é


necessário colocarmos algumas definições. Formalmente as instruções de um programa são
chamadas diretivas (statements).
Em Java, tal como na linguagem C/C++, as diretivas são separadas umas das outras
através do símbolo de pontuação ‘;’ (ponto e vírgula), sendo possível existir várias diretivas
numa mesma linha desde que separadas por um ponto e vírgula.
Como nas outras linguagens de programação, as estruturas de controle podem operar
sobre diretivas isoladas (individuais) ou sobre várias diretivas tratadas como um conjunto, que
é denominado bloco. Um bloco em Java é um grupo de diretivas delimitadas por chaves
“{ ... }”. Por sua vez um bloco de diretivas recebe um tratamento equivalente ao de uma única
diretiva.

{
diretiva1;
diretiva2;
.
.
.
diretivaN;
}
Programação Orientada a Objetos

2.7.1- Estruturas de desvio de fluxo


Existem várias estruturas de desvio de fluxo que podem provocar a modificação da
maneira com que as instruções de um programa são executadas conforme avaliação de uma
codificação. O Java dispões de duas destas estruturas: if e switch.
O if é uma estrutura simples de desvio de fluxo de execução, isto é, é um comando
que permite a seleção entre dois caminhos distintos para execução dependendo do resultado
falso ou verdadeiro resultante de um expressão lógica.

if (expressão_lógica)
{ comando1;
} else {
comando2;
}

O comando if permite duas construções possíveis: a primeira, utilizando a parte


obrigatória, condiciona a execução do comando1 a um resultado verdadeiro resultante da
avaliação da expressão lógica associada; a segunda, usando opcionalmente o else, permite
que seja executado o comando1 caso o resultado da expressão lógica seja verdadeiro ou que
seja executado o comando2 caso tal resultado seja falso.
A seguir um exemplo de uso da diretiva if:

//exemploIf.java
import java.io.*;

public class exemploIf {


public static void main (String args[]) {
if (args.length > 0) {
System.out.println(args[0]);
} else {
System.out.println(“Argumentos insuficientes!”);
}
}
}

Ao executar-se este programa podem ocorrer duas situações distintas como resultado:
se for fornecido algum argumento na linha de comando (args.length > 0), o programa exibirá
tal argumento. Caso não seja passado nenhum argumento, o programa exibirá a mensagem
alertando o usuário.
Programação Orientada a Objetos

Já o switch, é um comando de desvio múltiplo de fluxo, isto é, baseado na avaliação


de uma expressão ordinal é escolhido um caminho de execução dentre vários possíveis. Um
resultado ordinal é aquele pertencente a um conjunto onde se conhecem precisamente o
elemento anterior e posterior, por exemplo, o conjunto dos caracteres, ou seja, um valor
dentro de um conjunto cujos valores podem ser claramente ordenados (‘A’,’B’,’C’, . . . ).
O switch equivale logicamente a um conjunto de comandos if encadeados, embora
seja usualmente mais eficiente durante a execução.
A sintaxe é a seguinte:

switch(expressão_ordinal)
case ordinal1: comando1;
break;
case ordinal2: comando2;
break;
default: comando_default;
}

A expressão utilizada pelo switch deve, necessariamente, retornar um resultado


ordinal. Conforme o resultado é selecionado em cada um dos casos indicados pela construção
case. Os comandos encontrados a partir do caso escolhido são executadas até o final da
diretiva switch ou até encontrar um comando break. Se o valor resultante não possuir um
caso específico, serão executados os comandos colocados na cláusula default, que é opcional
neste comando.

Note que o ponto de início de execução é um caso (case) cujo valor ordinal é aquele
resultante da expressão avaliada. Após iniciada a execução do conjunto de comandos
identificados por um certo caso, tais ações só são interrompidas com a execução de um
comando break ou com o final do comando switch.
A seguir temos uma aplicação simples que exemplifica a utilização dos comandos
switch e break.

//exemploSwitch.java
import java.io.*;
public class exemploSwitch {
public static void main (String args []) {
if (args.length > 0) {
switch(args[0].charAt(0)) {
case ‘a’:
case ‘A’: System.out.println(“Vogal A”);
Programação Orientada a Objetos

break;
case ‘e’:
case ‘E’: System.out.println(“Vogal E”);
break;
case ‘i’:
case ’I’: System.out.println(“Vogal I”);
break;
case ‘o’:
case ‘O’: System.out.println(“Vogal O”);
break;
case ‘u’:
case ’U’: System.out.println(“Vogal U”);
break;
default: System.out.println(“Arg Inválido”);
}
} else {
System.out.println(“Não foi fornecido argumento!”);
}
}
}

No exemplo, quando fornecido algum argumento, a aplicação identifica se o primeiro


caracter deste é uma vogal. Se o argumento não for iniciado por uma vogal ocorre a execução
da seleção default do comando switch. Caso não existam argumentos fornecidos o programa
imprime uma mensagem correspondente.

Exercícios:

1- Escreva um programa que lei um número inteiro positivo e exiba o dobro do


mesmo.
2- Escreva um programa para calcular a área de um triângulo, sendo dados a sua
base e a sua altura.

 BASE x ALTURA
AREA=
2

3- Escreva um programa para calcular e exibir o comprimento de uma circunferência,


sendo dado o valor de seu raio.
C=2πR
Defina π, como sendo uma constante de valor igual a 3.1415.

4- Escreva um programa que leia duas variáveis inteiras e troque o conteúdo entre
elas.

5- Escreva um programa para ler uma temperatura dada na escala Fahrenheit e exibir
o equivalente em Celsius.

5
C= x  F −32
9

6- Escreva um programa para calcular e exibir o valor de xy, sendo dados a base(x) e
o expoente (y).

7- Escreva um programa que leia dois números e exiba o maior deles.

8- Escreva um programa que leia dois números e exiba-os em ordem crescente.


Programação Orientada a Objetos

Exercícios Teóricos

1- Construa um programa em Java que obtenha três números inteiros do teclado e os


mostre em ordem crescente.

2- Construa um programa em Java que obtenha dois números inteiros do teclado e


informe se o primeiro é divisível pelo segundo.

2.7.2- Estruturas de repetição


Como repetição consideramos um trecho de código que deve se repetido por algumas
vezes. A repetição é uma das tarefas mais comuns da programação utilizada para efetuarmos
contagens, para obtenção de dados, para impressão, etc. Em Java dispomos do comando for
cuja sintaxe é dada a seguir:

for(inicialização; condição de execução; incr/decremento)


{ Lista de comandos
}

O for possui três campos ou seções, todas opcionais, delimitamos por um par de
parênteses que efetuam o controle de repetição de um comando individual ou de um bloco de
comandos. Cada campo é separado um do outro por um ponto e vírgula. O primeiro campo é
usado para dar valor inicial a uma variável de controle (um contador). O segundo campo é um
expressão lógica que determina a execução ou não do(s) comando(s) associado(s) ao for. O
terceiro campo realiza uma operação sobre a variável de controle, geralmente incrementando
ou decrementando a variável.

Após a execução da seção de inicialização ocorre a avaliação da expressão lógica. Se a


expressão é avaliada como verdadeira, o comando (ou bloco) associado é executado, caso
contrário o comando for é encerrado e a execução do programa prossegue normalmente. O
terceiro campo determina como a variável de controle será modificada a cada iteração do for.
Considera-se como iteração a execução completa do comando associado, fazendo que ocorra o
incremento ou decremento da variável de controle. É importante ressaltar que o primeiro
campo (inicialização) só é executado quando se entra no comando for, nas demais “voltas” do
comando este trecho é completamente ignorado. A seguir um exemplo de utilização do
comando for:

// exemploFor.java
import java.io.*;
public class exemploFor {
public static void main (String args[]) {
int j;
Programação Orientada a Objetos

for (j=0; j<10; j++) {


System.out.println(“ “+j);
}
}
}

O while é o que chamamos de laço condicional, isto é, um conjunto de instruções que


é repetido enquanto o resultado de uma expressão lógica (uma condição) é avaliada como
verdadeira. Abaixo a sintaxe do comando while.

while (expressão_lógica)
{ comando ou lista de comandos
}

Note que o comando while avalia o resultado da expressão antes de executar o


comando associado, assim é possível que o(s) comando(s) associado(s) nunca seja(m)
executado(s) caso a condição seja inicialmente falsa. Um problema típico relacionado a
avaliação do comando while é o seguinte: se a condição nunca se tornar falsa o laço será
repetido ininterruptamente.

O do-while também é um laço condicional, isto é, tal como o while é um conjunto de


instruções repetido enquanto o resultado da condição é avaliada como verdadeira mas,
diferentemente do while, o comando associado é executado antes da expressão lógica,
fazendo com que tal comando seja executado pelo menos uma vez, independente da
expressão lógica.
Segue a sintaxe do comando do-while e uma ilustração de seu comportamento:

do
comando ou lista de comandos
while (expressão_lógica);
Programação Orientada a Objetos

A seguir temos exemplos da aplicação destes dois comandos de repetição:

//exemploWhile.java
import java.io.*;
public class exemploWhile {
public static void main (String args[]) {
int j = 0;
while (j > Integer.parseInt(args[0])) {
System.out.println(“ “+ j);
j--;
}
}
}

//exemploDoWhile.java
import java.io.*;
public class exemploDoWhile {
public static void main (String args []) {
int min = Integer.parseInt(args[0]);
int max = Integer.parseInt(args[1]);
do {
System.out.println(“ “ + min + “ < “ + max);
min++; max—;
} while (min < max);
System.out.println(“ “ + min + “ > “ + max);
}
}

2.7.3- Interrupções com: break, continue e return


A qualquer momento, dentro de um loop (for, while e do-while) pode ser feita uma
reconsideração da condição de execução do loop. Para que isso ocorra é utilizado o comando
continue. Ao encontrar um continue, o programa é desviado para o início do loop, no caso de
for ou while, ou para o final do loop, no caso de do-while, para a reavaliação. Para a
interrupção da execução de um loop, é utilizado o comando break.
O comando return é utilizado, na construção métodos, para retornar valor ao
acionador do método. Não há uma regra quanto a localização do return, o que é certo é que
quando este comando é encontrado a execução é imediatamente interrompida e o retorno ao
acionador é efetuado.

Exercícios
1- Faça um programa em Java mostre todos os números inteiros pares de 2 a 100.

2- Faça um programa em Java para exibir os números inteiros de 20 a 10,


decrescendo de 1 em 1.

3- Faça um programa em Java que leia um número N, some todos os números inteiros
de 1 a N, e mostre o resultado obtido.

4- Faça um programa em Java que leia N e uma lista de N números e mostre a soma
de todos os números lidos.

5- Escreva um programa em Java que leia um conjunto de 100 números inteiros


positivos e determine o maior deles.

6- Construa um programa em Java que leia um número inteiro N e uma lista de N


números inteiros positivos e determine o maior número da lista.
Programação Orientada a Objetos

Exercícios Teóricos
1- Escreva um programa em Java que leia um conjunto de números inteiros positivos
e determine o maior deles. A leitura do valor 0 (zero) indica o fim da entrada dos dados.

2- Escreva um programa em Java que leia um conjunto de números inteiros positivos


terminada pelo número 0 (zero). Ao final, o programa deverá mostrar a média aritmética de
todos os números lidos.

3- Escreva um programa em Java que calcule o fatorial de um número inteiro lido,


sabendo-se que: N! = 1 x 2 x 3 x . . . x N-1 x N; 0! = 1.

2.7.4- Estruturas de controle de erros


O Java oferece duas importantes estruturas para o controle de erros muito
semelhantes as estruturas existentes na linguagem C++: try-catch e try-finally. Ambas
tem o propósito de evitar que o programador tenha que realizar testes de verificação e
avaliação antes da realização de certas operações, desviando automaticamente o fluxo de
execução para rotinas de tratamento de erro. Através destes comandos, delimita-se um trecho
de código que será monitorado automaticamente pelo sistema. A ocorrência de erros no Java é
sinalizada através de exceções, isto é, objetos especiais que carregam a informação sobre o
tipo de erro detectado.
Existem várias classes de exceções adequadas para o tratamento dos problemas mais
comuns em Java, usualmente inclusas nos respectivos pacotes. Exceções especiais podem ser
criadas em adição às existentes ampliando as possibilidades de tratamento de erro. Com o
try-catch a ocorrência de erros de um ou mais tipos dentro do trecho de código delimitado
desvia a execução automaticamente para uma rotina designada para o tratamento específico
deste erro.
A sintaxe do try-catch é a seguinte:

try {
comando_normal;
} catch (exception1) {
rotina_de_tratamento_de_erro1;
} catch (exception2) {
rotina_de_tratamento_de_erro2;
}

No programa exemploIf2.java, listado a seguir, um argumento é requerido pelo


programa e um loop será executado partindo de 0 até o numero (inteiro) passado como
argumento. Caso seja fornecido um argumento diferente de inteiro ocorre uma exceção da
classe java.lang.NumberFormatException devido a tentativa de se converter o argumento
passado para um número inteiro.

//exemploIf2.java
import java.io.*;
public class exemploIf2 {
public static void main (String args[]) {
if (args.length > 0) {
try {
for(int j=0;j<Integer.parseInt(args[0]);j++){
System.out.println(“ “+ j +” “);
}
System.out.println(“\nFim da contagem”);
} catch (java.lang.NumberFormatException e) {
System.out.println(“Argumento inválido!”);
}
}
}
}
Programação Orientada a Objetos

Com o try-finally temos um comportamento bastante diferente. Uma rotina de


finalização é garantidamente executada, isto é, o trecho particular de código contido na
cláusula finally é sempre executado ocorrendo ou não erros dentro do trecho delimitado pela
cláusula try.
A sintaxe do try-finally é colocada a seguir:

try {
comando_normal;
} finally {
rotina_de_tratamento_de_erro;
}

Isto é particularmente interessante quando certos recursos do sistema ou estruturas


de dados devem ser liberadas, independentemente de sua utilização.

Exercícios
1- Construa um programa em Java que leia 3 (três) números inteiros (N,X,Y) e mostre
todos os números de N entre X e Y.

2- Um número é, por definição, primo se ele não tem divisores, exceto 1 e ele próprio.
Escreva um programa em Java que leia um número inteiro e determine se ele é ou não primo.

3- Construa um programa em Java que leia dois números inteiros (X e Y) e mostre


todos os primos entre X e Y.

4- Construa um programa em Java que leia um número N, calcule e mostre os N


primeiros termos da sequência de Fibonacci. A sequência de Fibonacci é formada inicialmente
pelos valores 0 e 1 e, a partir de então, cada novo elemento desta sequência é obtido pela
soma dos dois elementos imediatamente anteriores. Exemplo: (0,1,1,2,3,5,8,13,...)

3- Classes e Objetos

Até este momento vimos exemplos de programas Java onde as tarefas se


concentravam no método main(), porém, a partir do conceito de classes e objetos,
começaremos a construir programas divididos em partes bem distintas: A primeira deverá
definir o problema do mundo real através da especificação de suas características (classe); A
segunda parte deverá criar instâncias (objetos) das classes definidas para que se possa dar
vida às definições contidas nas classes, ou seja, para que se possa dar um comportamento
dinâmico aos objetos modelados na primeira etapa.
Normalmente, um aluno de programação deseja digitar um código fonte e pôr este
código para executar o mais rápido possível, porém, no paradigma OO, o aluno deve ser mais
contido e organizado, pois como foi dito no parágrafo anterior, a especificação do problema
e a execução do programa devem ser tratados em momentos distintos.
Inicialmente deve-se criar a classe. Mas o que vem a ser uma classe? Uma classe é
um molde para que se possa construir objetos reais dos quais desejamos modelar. E o que
vem a ser um molde? Um molde pode ser entendido como um conjunto de características de
um terminado objeto. Por características, deve-se englobar o conceito de atributos (adjetivos)
e comportamentos.
Programação Orientada a Objetos

3.1- Especificando uma classe


O essencial da abordagem orientada a objetos é que podemos (e devemos) criar
novos modelos de dados, as classes, para melhor representar os dados que serão utilizados
pela aplicação, isto é, para melhor representarmos os objetos reais a serem tratados pela
aplicação. Note que um mesmo objeto pode ser descrito de diferentes maneiras, sendo cada
uma destas maneiras mais ou menos adequada para representar tal objeto dentro de um
determinado contexto, ou seja, dentro de um certo problema.
A definição de uma nova classe em Java é um processo muito simples, desde que
saibamos como descrever o referido objeto.
Uma classe em Java pode ser definida através da seguinte estrutura de código:

qualificador_de_acesso class Nome_Da_Classe {


// atributos da classe
. . .
// métodos da classe
. . .
}

Os qualificadores de acesso indicam como a classe pode ser utilizada por outras
classes e, consequentemente, outras aplicações. Existem dois especificadores de acesso
básicos:

Qualificador Significado
Indica que o conteúdo público da classe pode ser utilizado livremente por outras
Public
classes.
Indica que o conteúdo público da classe pode ser utilizado livremente por outras
Package
classes do mesmo pacote.

3.1.1- Atributos
O atributo é um elemento da classe que pode representar uma característica dos
objetos instanciados ou valores de controle da classe. A representação básica de um atributo
consiste em seu identificador e seu tipo.
A sintaxe para se criar atributos é idêntica à criação das variáveis, com a exceção de
se ter que definir o qualificador de acesso do atributo. Veja alguns exemplos:

private int dia,mes,ano;


public String Nome;
protected float nota1,nota2;

3.1.2- Métodos
Um método se refere a um comportamento ou uma ação que pode ser executada
sobre o objeto. Os métodos alteram o estado do objeto, ou seja, alteram os conteúdos das
variáveis de instância. Os métodos também são bastante utilizados para que se possa
consultar os conteúdos das variáveis de instância, uma vez que, devido ao encapsulamento,
tais variáveis ficam inacessíveis fora da classe.
Uma outra característica interessante dos métodos é o fato de, naturalmente, se
implementar uma maior modularização do programa, uma vez que o desenvolvedor observa os
comportamentos dos objetos de forma separada e sequencial (um de cada vez), programando
cada comportamento num método individual.
A criação de um método deve seguir a seguinte sintaxe:

Qualificador_De_Acesso Tipo_De_Retorno Nome_Do_Método(Lista_De_Argumentos) {


// Atributos
. . .
// Código (programação)
. . .
// Retorno de valores (se houver)
}
Programação Orientada a Objetos

Qualificador Global Classe Pacote Subclasse


Public Sim Sim Sim Sim
Private Não Sim Não Não
Protected Não Sim Sim Sim
Package (qualificador omitido) Não Sim Sim Não

3.1.3- Encapsulamento
O Encapsulamento é uma característica muito interessante da POO, ela se resume ao
fato de se restringir o acesso a determinados elementos de uma determinada classe.
Normalmente os atributos de uma classe são definidos como private, ou seja, só
podem ser acessados diretamente dentro da própria classe. Isto é justificável, pois
normalmente os atributos são para controle interno do objeto ou cercados de controles
imperceptíveis aos usuários, mas importantíssimos para o correto funcionamento do objeto.
Imagine que o usuário pudesse especificar um mês como 13. (Ex.: dd/mm/aaaa –
24/13/2009)
Os métodos, pelo contrario, na maioria das vezes, são declarados como public, isso
se justifica pelo fato de que eles modelam os comportamentos dos objetos e é presumível que
o usuário deveria ter acesso as esses comportamentos. Vejamos o exemplo de um carro: Este
provavelmente terá os métodos Acelerar() e Frear() como públicos, porém, algum método
referente a uma ação interna do motor, por exemplo, GerarCentelha() poderá e deverá ser
definido como privado, uma vez que o usuário não tem a necessidade de acessar diretamente
este método.

Exercícios
1- Suponha uma classe em Java que implemente uma data. Pense em seus atributos e
métodos.
2- Implemente a classe Data, idealizada acima, em Java. Implemente apenas os
métodos setDia(int), setMes(int), setAno(int), int getDia(), int getMes() e
int::getAno().
3- Construa um programa em Java para testar a classe Data.
4- Construa os seguintes métodos: String NomeMes(), int Bissexto(), int
DiasMes() e String getData().
5- Construa o método para incrementar ou decrementar algum dos atributos da data.
O método Incr(int,int,int) deverá funcionar de acordo com os exemplos:
Parâmetros (1,0,0): incrementa o dia em 1;
Parâmetros (0,2,0): incrementa o mês em 2;
Parâmetros (0,0,-1): decrementa o ano em 1;
Obs.: O método fará apenas uma ação por vez.
6- Pelo conceito de encapsulamento, devemos proteger os atributos de modo que eles
não assumam valores incoerentes. No exercício número 2, as atribuições aos atributos da data
são implementadas de forma independente. Isto pode gerar inconsistências. Uma maneira de
corrigir este problema é excluir as implementações dos métodos setDia(int), setMes(int)e
setAno(int) e implementar o método setData(int,int,int). Este método receberá os três
atributos ao mesmo tempo e validará ou não a data.

3.1.4- Construtores e Destrutores

3.1.4.1- Construtores

Construtores são métodos especiais chamados pelo sistema no momento da criação de


um objeto. Eles não possuem valor de retorno, porque você não pode chamar um construtor
para um objeto, você só usa o construtor no momento da inicialização do objeto. Construtores
representam uma oportunidade de inicializar os atributos de forma organizada, imagine se
você esquecesse de inicializar corretamente.
Um construtor tem sempre o mesmo nome da classe a qual pertence. Para a classe
Programação Orientada a Objetos

String, pré-definida na linguagem, o construtor tem a forma String(“Constante do tipo


String”) com o argumento entre aspas que é especificado pelo programador. Ele seria
chamado automaticamente no momento da criação do objeto.

String a = new String("Texto"); //alocação e inicialização através do construtor

Nos exemplos anteriores, também usávamos construtores no momento de inicializar


nossos objetos, só que eles não possuíam argumentos.
Existem variações sobre o tema que veremos mais tarde: sobrecarga de construtor,
"copy constructor", construtor de corpo vazio. O exemplo a seguir é simples, semelhante aos
anteriores, preste atenção no método com o mesmo nome que a classe, este é o construtor:

//Classe Ponto, arquivo Ponto.java


public class Ponto {
private float x,y;
public Ponto(float ax,float ay) // sempre omita o valor de retorno!
{
x=ax; y=ay;
}

public void move(float dx,float dy)


{
x+=dx; y+=dy;
}

public void mostra()


{
System.out.println("("+x+","+y+")");
}
}

//Programa principal, arquivo PrincPonto.java


public class PrincPonto {
public static void main(String args[]) {
Ponto ap = new Ponto((float)0.0,(float)0.0);
ap.mostra();
ap.move(1,1);
ap.mostra();
}
}

Note que com a definição do construtor, você é obrigado a passar os argumentos no


momento da alocação do objeto. Se você precisa ter a opção de não passar ou passar outros
valores, as possíveis soluções serão dadas em polimorfismo.
A expressão (float)0.0 indica que é para ser feita a conversão de 1.0 para ponto
flutuante. 1.0 sozinho é considerado double. (int)1.0 é igual a 1. (int) 2.3 é igual a 2. Esta
operação indicada por (nometipo)tipo_a_ser_convertido é também chamada de "type cast".
A ocorrência de rotinas de criação de objetos em diversos locais de um programa é
muito comum. Objetos podem ser criados dentro de estruturas condicionais, armazenados em
arquivos, passados como parâmetros, inseridos em estruturas dinâmicas dentro de outros
objetos, etc.

Exercícios
1- Construa a classe Contador. Esta classe deverá manter um valor inteiro. Este valor
poderá ser incrementado pelo acionamento do método incr(), e poderá ser decrementado
pelo acionamento do método decr(). Para simplificar o execício estes métodos somente
alterarão o estado do contador em uma unidade. Implemente também o método getCont(),
para obter o valor atual do contador e o método Mostrar(), que exibirá o valor atual do
contador.
Programação Orientada a Objetos

2- Crie um construtor para a classe Contador.


3- Construa um programa para testar a classe contador.

3.1.4.2- Destrutores ou "finalizers"

A presença de coleta automática de lixo torna o conceito de destrutores um pouco


diferente de seus equivalentes em outras linguagens orientadas a objetos. Em Java
destrutores são métodos chamados pelo sistema quando a memória de um objeto está para
ser liberada pelo coletor automático de lixo.
A sintaxe dos destrutores é a seguinte:

protected void finalize() {


//codigo para arrumar a casa, antes que o objeto seja apagado
}

Note que o que caracteriza o construtor é ter o mesmo nome da classe, já o destrutor
é caracterizado por possuir o nome finalize. Você pode chamar o destrutor, mas isso não
implica que o objeto será deletado. Ao contrário dos construtores, os destrutores não tem
argumentos, mas possuem valor de retorno que é igual a void.
Os destrutores são muito úteis para "limpar a casa" quando um objeto deixa de ser
usado. Um exemplo bastante comum do uso de destrutores é o de um objeto que lida com
arquivos que devem ser fechados quando o objeto for destruído. Existem outros casos onde
um objeto deve comunicar aos outros objetos que será inutilizado, destruído, ou seja, sairá do
programa.
Em Java, que possui coleta automática de lixo, um objeto passa a não existir mais
no programa quando nenhuma variável faz referência a ele. Nesse ponto, ele é armazenado no
coletor automático de lixo, onde receberá o tratamento adequado. Um nó de uma lista ligada
pode ser apagado simplesmente fazendo o nó anterior apontar para o posterior a ele. Os
programadores não acostumados com esse conceito precisam ouvir a seguinte frase: "Você
não é obrigado a liberar explicitamente a memória de um objeto como é feito em C++ e
outras linguagens".
Se estivéssemos por exemplo em C++, que não possui coleta automática de lixo, o
destrutor seria chamado sempre que a memória de um objeto fosse desalocada, o que é feito
pelo programador através de uma chamada a delete.nomedoobjeto();.
Em Java a liberação de memória que é feita pelo coletor automático de lixo que é
executado de modo assíncrono com o restante do programa, ou seja, você não pode contar
com o fato de que o destrutor será chamado imediatamente após o momento em que seu
objeto sai de escopo, a não ser que o programa seja executado com o modo assíncrono do
coletor automático de lixo desligado (java -noasyncgc NomePrograma).

3.2- Sobrecarga, Herança e Polimorfismo


A construção de classes, embora de fundamental importância, não representa o
mecanismo mais importante da orientação à objetos. A grande contribuição da orientação à
objetos para o projeto de desenvolvimento de sistemas é o polimorfismo. A palavra
polimorfismo vem do grego poli morfos e significa muitas formas. Na OO representa uma
característica onde se admite tratamento idêntico para formas diferentes baseado em relações
de semelhança, isto é, entidades diferentes podem ser tratadas de forma semelhante
conferindo grande versatilidade aos programas e classes que se beneficiam destas
características.

3.2.1- Sobrecarga de Métodos


A forma mais simples de polimorfismo oferecido pela linguagem Java é a sobrecarga
de métodos (method overload), ou seja, é a possibilidade de existirem numa mesma classe
vários métodos com o mesmo nome. Para que estes métodos de mesmo nome possam ser
distinguidos eles devem possuir uma assinatura diferente. A assinatura (signature) de um
método é uma lista que indica os tipos de todos os seus argumentos, sendo assim, métodos
com mesmo nome são considerados diferentes se recebem um diferente número ou tipo de
Programação Orientada a Objetos

argumentos e tem, portanto, uma assinatura diferente. Um método que não recebe
argumentos tem como assinatura o tipo void enquanto um outro método que recebe dois
inteiros como argumentos tem como assinatura os tipos int, int como no exemplo abaixo:

// Calculo.java
public class Calculo {
public long dobro (int x) {
return 2*(long)x;
}

public long dobro (long x) {


return 2*x;
}

public long dobro (String x) {


return 2*(long)Integer.parseInt(x);
}
}

No exemplo temos na classe Calculo a implementação de três métodos denominados


dobro() que tomam um único argumento retornando um valor que é o dobro do valor do
argumento recebido. Através da sobrecarga foram implementadas três versões do método
dobro(), cada uma capaz de receber um argumento de tipo diferente. Na prática, é como se o
método dobro() fosse capaz de processar argumentos de tipos diferentes.
Outra situação possível é a implementação de métodos com o mesmo nome e
diferentes listas de argumentos, possibilitando uma utilização mais flexível das idéias centrais
contidas neste método como a seguir:

// Sobrecarga.java
public class Sobrecarga {
public long Somatorio (int max) {
int total = 0;
for (int i = 1; i < max; i++)
{ total += i; }
return total;
}
public long Somatorio (int max, int incr) {
int total = 0;
for (int i = 1; i < max; i += incr)
{ total += i; }
return total;
}
}

No exemplo acima temos o método Somatorio() que efetua a soma dos primeiros max
números naturais ou efetua a soma dos primeiros max números naturais espaçados de incr e
que a seleção de um método ou outro se dá pela diferença de argumentos utilizados pelo
método Somatorio().
A API do Java utiliza intensivamente o mecanismo de sobrecarga, por exemplo, a
classe java.lang.String onde o método indexOf possui várias implementações. O método
indexOf se destina a localizar algo dentro de uma string, isto é, determinar a posição (índice)
de um caracter ou substring, o que caracteriza diferentes possibilidades para seu uso,
conforme a tabela a seguir:
Programação Orientada a Objetos

Método Descrição
Retorna a posição, dentro da string, da primeira ocorrência do caracter
IndexOf(int)
especificado.
Retorna a posição, dentro da string, da primeira ocorrência do caracter
IndexOf(int, int)
especificado a partir da posição dada.
Retorna a posição, dentro da string, da primeira ocorrência da substring
IndexOf(String)
especificada.
Retorna a posição, dentro da string, da primeira ocorrência da substring
IndexOf(String,int)
especificada a partir da posição dada.

Desta forma, fica transparente para o usuário da classe a existência destes quatro
métodos, ao mesmo tempo ficam disponíveis tais alternativas para localização de caracteres
simples ou substrings dentro de strings.
Numa classe onde são implementados vários métodos com o mesmo nome fica a
cargo do compilador determinar qual o método apropriado em função da lista de argumentos
indicada pelo método efetivamente utilizado (dynamic binding).
Um outro ponto importante é que Java não fornece recursos para sobrecarga de
operadores tal como existe na linguagem C++. Apesar disto ser um aspecto restritivo da
linguagem, é perfeitamente condizente com a filosofia que orientou o desenvolvimento desta
linguagem que foi criada para ser pequena, simples, segura de se programar e de se usar. A
ausência de mecanismos para definir a sobrecarga de operadores pode ser contornada através
da definição e implementação apropriada de classes e métodos.

3.2.2- Sobrecarga de Construtores


Da mesma forma que podemos sobrecarregar métodos de uma classe, podemos
sobrecarregar seus construtores, ou seja, uma classe pode possuir mais de um construtor
onde cada um deles é diferenciado por sua assinatura. O compilador determina qual dos
construtores utilizar através dos agrupamentos utilizados na chamada do construtor.
Obviamente deve existir um construtor cuja lista de argumentos seja utilizada na criação de
um novo objeto, caso contrário será indicado o erro:

javac SobrecargaTest.java
SobrecargaTest.java:4: Wrong number of arguments in constructor.
Sobrecarga s = new Sobrecarga(false);

Java oferece um construtor default para cada classe o qual não precisa ser declarado e
implementado. Este construtor, que não recebe parâmetros, mesmo quando implementado, é
denominado construtor default. Quando sobrecarregamos o construtor de uma classe, tal como
faríamos com qualquer outro método, criamos construtores denominados construtores cópia
(copy constructor). A seguir um exemplo de uma classe contendo três diferentes construtores
(construtor default e dois construtores cópia):

// Sobracarga2.java
public class Sobracarga2 {
public int prim,sec;

//Construtores
public Sobracarga2() {
prim = sec = 0;
}
public Sobracarga2(int p) {
prim = p;
sec = 0;
}
public Sobracarga2(int p, int s) {
prim = p;
sec = s;
}
}
Programação Orientada a Objetos

A classe Sobracarga2 possui dois atributos inteiros prim e sec que são inicializados
com valor zero através do construtor default. Para que o atributo prim seja inicializado com
outro valor podemos utilizar o construtor cópia que recebe um parâmetro inteiro. Para que
tanto a atributo prim como sec sejam inicializados diferentemente dispõe-se ainda de um
segundo construtor cópia.
O uso de construtores sobrecarregados é bastante conveniente pois possibilita reduzir
o código que deve ser escrito para utilização de um objeto como nos trechos de código abaixo:

Sobracarga2 s = new Sobracarga2();


s.prim = 10;

Pode ser substituído por apenas:

Sobracarga2 s = new Sobracarga2(10);

Outro caso possível:

Sobracarga2 s = new Sobracarga2();


s.prim = 5;
s.sec = -2;

Pode ser substituído por:

Sobracarga3 s = new Sobracarga3(5, -2);

A API do Java utiliza extensivamente o mecanismo de sobrecarga de construtores para


oferecer aos programadores a maior flexibilidade possível. Um exemplo disto é a classe
java.lang.String que possui 11 diferentes construtores dos quais destacamos alguns:

Construtor Descrição
String() Cria uma nova string se conteúdo
Cria uma nova string convertendo o conteúdo do vetor de bytes
String(byte[])
especificado
Cria uma nova string convertendo o conteúdo do vetor de char
String(char[])
especificado
Cria uma nova string contendo a mesma seqüência de caracteres
String(String)
da string especificada
Cria uma nova string contendo a mesma seqüência de caracteres
String(StringBuffer)
do objeto StringBuffer especificado

Ao mesmo tempo que a disponibilidade de vários construtores cópia é bastante


conveniente, sua implementação em uma certa classe deve ser objeto de análise cuidadosa
para determinar-se se certa adição será realmente útil aos usuários da classe evitando-se
assim onerar demasiadamente o código produzido.

Exercícios Teóricos
1- Faça uma classe Conta (Conta Corrente) que contenha o nome e o salário do
cliente, o número da conta, o saldo e o limite. O saldo inicial deve ser zero e o limite de crédito
(cheque especial) não poderá ser maior que o valor do salário mensal do cliente. Faça um
método deposito() e um método saque(). O método saque() irá devolver true ou false,
dependendo se o cliente pode ou não realizar a retirada. Faça um método GetSaldo() que
retorne o saldo do cliente.
2- Repita o exercício anterior utilizando a sobrecarga de construtores.
Programação Orientada a Objetos

3.2.3- Herança
A herança (inheritance) é o segundo e mais importante mecanismo do polimorfismo e
pode ser entendido de diversas formas das quais, a mais simples é: uma técnica onde uma
classe passa utilizar atributos e operações definidas em uma classe especificada como seu
ancestral. Rigorosamente falando, a herança é o compartilhamento de atributos e operações
entre classes baseado num relacionamento hierárquico do tipo pai e filho, ou seja, a classe pai
contém definições que podem ser utilizadas nas classes definidas como filho. A classe pai é o
que se denomina classe base (base class) ou superclasse (superclass) e as classes filho são
chamadas de classes derivadas (derived class) ou subclasses (subclass). Este mecanismo
sugere que uma classe poderia ser definida em termos mais genéricos ou amplos e depois
refinada sucessivamente em uma ou mais subclasses específicas. Daí a origem do termo
técnico que descreve a herança: especialização (specialization).
Em Java indicamos que uma classe é derivada de uma outra classe utilizando a
palavra reservada extends conforme o trecho simplificado de código dado a seguir: A
superclasse não recebe qualquer indicação especial.

// SuperClass.java
public class SuperClass {
.
.
.
}

// SubClass.java
public class SubClass extends SuperClass {
.
.
.
}

Num diagrama UML teríamos a seguinte representação para classes hierarquicamente


relacionadas:

Em princípio, todos atributos e operações definidos para certa classe base são
aplicáveis para seus descendentes que, por sua vez, não podem omitir ou suprimir tais
características, pois não seriam verdadeiros descendentes se fizessem isto. Por outro lado,
uma subclasse pode modificar a implementação de alguma operação (reimplementar) por
questões de eficiência sem modificar a interface externa da classe. Além disso as subclasses
podem adicionar novos métodos e atributos não existentes na classe base, criando uma versão
mais específica da classe base, isto é, especializando-a. Na figura abaixo temos um exemplo
de hierarquia de classes onde são indicados os atributos e operações adicionados em cada
classe. Note que os atributos e operações adicionados não são indicados explicitamente na
classe derivada, mas implicitamente pela relação de herança.
Programação Orientada a Objetos

A herança é portanto um mecanismo de especialização pois uma dada subclasse


possui tudo que foi definido pela sua superclasse além de atributos e métodos localmente
adicionados. Por outro lado, a herança oferece um mecanismo para generalização pois uma
instância de uma classe é uma instância de todos os ancestrais desta classe, isto é, um objeto
de uma classe derivada pode ser tratado polimorficamente como um objeto da superclasse.
No mundo real, alguns objetos podem ser descritos como casos especiais,
especializações ou generalizações de outros objetos e classes. Por exemplo, a bola de futebol
de salão é uma especialização da classe bola de futebol que por sua vez é uma especialização
da classe bola. Aquilo que foi descrito para uma certa classe não precisa ser repetido para uma
classe mais especializada originada na primeira.
Atributos e métodos definidos na classe base não precisam ser repetidos numa classe
derivada, desta forma a orientação à objetos auxilia a reduzir a redundância de código dentro
de um programa ao mesmo tempo que possibilita que classes mais genéricas sejam
reaproveitadas em outros projetos (reusabilidade de código). Outro aspecto bastante
importante é que se o projeto de uma hierarquia de classe é suficientemente genérico e
amplo, temos o desenvolvimento de uma solução generalizada e com isso torna-se possível
mais do que a reutilização de código, mas passa a ser possível o que denomina reutilização do
projeto. Uma classe ou hierarquia de classes que pode ser genericamente utilizada em outros
projetos é que se chama de padrão de projeto ou design pattern.

Exercícios
1- Construa uma classe Ponto. Esta classe deve especificar as coordenadas de um
ponto e as operações que podem ser realizadas sobre ponto. Implemente o construtor da
classe.
2- Construa uma classe Pixel. Esta classe deve herdar tudo que a classe Ponto possui
e acrescentar o atributo cor. Implemente o construtor desta classe.
3- Construa a classe ContaE. Esta classe deverá ser herdeira da classe Conta. A
diferença entre as classes é que na ContaE o limite de saque será de 3 vezes o valor do
salário.
Programação Orientada a Objetos

4- Applet
Applets são pequenos programas escritos em Java que podem ser embutidos em
documentos hipertextos. Este programa será executado (interpretado) por um browser (um
navegador Web) quando for carregada a página que contém tal applet. Desta forma uma
applet é um programa Java destinado a ser utilizado pelos browser´s significando que será
transportada pela Internet tal como documentos HTML, imagens GIF e JPEG e outros
conteúdos típicos da rede.
Em função deste uso, as applet´s usualmente são construídas para serem pequenos
programas e, por questões de segurança, obedecem critérios rígidos para que sua execução
seja possível pelos browser´s.
Outro aspecto é que as applet´s são programas executados nos ambientes gráficos
das diversas plataformas que utilizam a Web, assim sua construção é bastante semelhante a
criação de programas que utilizem componentes ou recursos gráficos disponíveis na AWT.
Abaixo, um pequeno exemplo de applet e seu resultado quando executado num browser.

import java.awt.*;
import java.applet.*;

public class PMPWelcome extends Applet {


public void paint(Graphics g) {
g.drawString(“Java is Hot!”,25,25);
}
}

O código HTML necessário para se produzir a página exibida na figura acima é


mostrado a seguir:

<html>
<head>
<title>Testando Applets</title>
</head>
<body>
<applet
code="PMPWelcome.class"
width=200
height=150>
</applet>
</body>
</html>
Programação Orientada a Objetos

Notamos tratar-se de um arquivo HTML normal, onde a inclusão da applet é realizada


através da tag <applet>.
Como é possível, a tag <applet> possui vários campos, os quais indicam:

Campo Descrição
ARCHIVE Nome do arquivo compactado da applet (Java Archive – arquivo .jar)
ALT Nome alternativo.
ALIGN Alinhamento da applet (valores possíveis são: top, midle, bottom, left e right
CODE Nome do arquivo de classe Java incluindo a extensão .class.
CODEBASE URI base para os arquivos de classe Java.
HEIGHT Altura da applet (em pixels).
HSPACE Margem horizontal (em pixels).
NAME Nome da applet para comunicação inter-applet.
VSPACE Margem vertical (em pixels).
WIDTH Largura da applet (em pixels).

É necessário utilizar o campo CODE para especificar a applet (programa Java) que deve
ser executada. O campo ARCHIVE é usado caso a applet esteja inserida num arquivo
compactado tipo JAR. O campo CODEBASE indica o local onde os arquivos “.class” ou “.jar”
estão localizados. Os demais campos referem-se a disposição da applet na página HTML. A
forma mais freqüente de uso desta tag é como exemplificado, ou seja, especificando-se a
applet através do campo CODE e seu tamanho através dos campos HEIGHT e WIDTH.
A tag <applet> é uma tag dupla, portanto finalizada por </applet>. Em seu corpo,
isto é, no interior da construção <applet></applet> podemos inserir outra tag, <param>,
destinada a parametrização da applet, o que será visto mais adiante.
A programação e compilação de applet´s é uma tarefa idêntica a criação de
programas em Java: utiliza-se um editor de textos comum e depois o compilador javac para
realizar a compilação do programa nos byte-codes correspondentes, (.class). Novamente o
nome do arquivo deve ser idêntico ao da classe pública nele contido.
No entanto o teste das applet´s produzidas não pode ser feito através do
interpretador java e sim, através de um browser compatível com Java ou através do aplicativo
appletviewer fornecido juntamente com as demais ferramentas do JDK. O appletviewer
executa applet´s que estejam inseridas em arquivos HTML, por exemplo:

appletviewer Applet1.html

Isto produziria o seguinte resultado para a applet PMPWelcome:


Programação Orientada a Objetos

Não existe a necessidade do arquivo HTML possuir o mesmo nome que a applet ou sua
classe. Outra facilidade é que o arquivo HTML pode conter apenas a tag <applet>, embora
consiga tratar arquivos HTML complexos. Assim o uso do appletviewer é mais conveniente
durante a fase de desenvolvimento e teste das applets.

4.1- Funcionamento das Applet´s


Embora a construção de applet´s seja semelhante a criação de programas gráficos em
Java, a compreensão de seu ciclo de vida auxilia bastante no entendimento de sua estrutura.
As applet´s são aplicações especiais que possuem um modo particular de funcionamento.

➢ instanciação (create)
➢ inicialização (init)
➢ início (start)
➢ execução e renderização (paint e outros métodos)
➢ parada (stop)
➢ finalização ou destruição (destroy)

Este modo de funcionamento define o ciclo de vida das applet´s, que é esquematizado
na figura abaixo. Implementações mínimas de applet´s utilizam geralmente o método init()
ou o método paint().

4.1.1- O método init()


Tal como programas, as applet´s são objetos definidos em classes. Enquanto os
programas necessitam de um método main(), implementado em uma de suas classes, para
definir o início do programa (que provocará a instanciação e exibição de um Frame ou a
execução de uma aplicação de console), as applet´s são instanciadas pelos próprios
navegadores, ou melhor, pelas JVM encarregadas da execução das applet´s. Como qualquer
classe Java, os construtores não necessitam ser explicitamente implementados dado a
existência dos construtores default´s disponibilizados pelo Java.
Adicionalmente existe um método denominado init(), invocado após a criação da
applet (instanciação), utilizado pelos navegadores para iniciar a execução das applet´s. Este
método é normalmente usado para a adição de componentes, recebimento de parâmetros de
execução e outras atividades de preparo. Este método é executado somente uma única vez.

4.1.2- O método start()


O método start() é acionado pelo browser toda vez que a applet torna-se visível,
portanto deve ser utilizado quando é necessário assegurar alguma condição especial para a
apresentação da applet. Geralmente este método é utilizado em conjunto com o método
Programação Orientada a Objetos

stop(). O método start() é acionado pela primeira vez logo após a execução do método
init(), sendo novamente acionado tantas vezes quantas a applet tornar-se visível.

4.1.3- O método paint()


Este método é chamado toda vez que a applet necessita atualizar sua exibição, o que
ocorre quando é exibida pela primeira vez (depois da execução do método start()), quando a
janela do browser é movimentada ou redimensionada como conseqüência do acionamento do
método update.
O método paint() pode ser utilizado para a realização de operações de desenho
especiais na applet, ou seja, quando deseja-se tratar diretamente a renderização do conteúdo
exibido pela applet, tal como no caso da construção de animações ou outras aplicações
gráficas.
A maneira mais simples de construir-se uma applet é através da utilização do método
paint(), pois através deste, temos acesso ao contexto gráfico da applet que permite a
utilização das primitivas gráficas da AWT.

4.1.4- O método stop()


Como complemento funcional do método start(), dispomos do método stop(). Este
método é ativado toda vez que a applet deixa de ser visível, ou seja, quando ocorre um
rolamento (scrolling) da página exibida pelo browser ou quando a applet se torna encoberta
por outra janela do sistema.
Isto significa que a applet, durante seu ciclo de vida, pode ter seus métodos start()
e stop() acionados inúmeras vezes, conforme a sua exibição no sistema. Geralmente são
utilizados para parar animações ou outras rotinas que consumam recursos e só devam ser
executadas durante a exibição da applet.
O método stop() é chamado imediatamente antes do método destroy(), descrito a
seguir.

4.1.5- O método destroy()


Este método é acionado quando a applet está sendo descarregada da página para que
seja realizada a liberação final de todos os recursos utilizados durante sua execução. É
acionado pelo browser quando ocorre a troca de páginas. Raramente necessita ser utilizado de
forma explícita, exceto quando utilizado em conexões em rede ou comunicação com outras
applet´s.
Segue um outro exemplo simples de applet que demonstra a ocorrência destes
métodos especiais. No exemplo são declaradas e inicializadas quatro variáveis inteiras que
serão utilizadas como contadores do acionamento dos métodos init(), start(), paint() e
stop() (o método destroy() não necessita ser contabilizado pois só ocorre uma única vez, e
exatamente quando a applet deixará de existir). Em cada um dos métodos coloca-se a
respectiva variável de controle sendo modificada por uma operação simples de incremento, ou
seja, cada vez que tal método é acionado a variável de controle conta quantas vezes isto
ocorreu. O método paint() é o único com código extra pois nele se exibe o valor dos
contadores.

//AppletMetodos.java

import java.awt.*;
import java.applet.*;

public class AppletMetodos extends Applet {


private int inits = 0;
private int starts = 0;
private int paints = 0;
private int stops = 0;

public void init() {


inits++;
Programação Orientada a Objetos

public void start() {


starts++;
}
public void paint(Graphics g) {
paints++;
g.drawString("Init: "+inits,5,15);
g.drawString("Start: "+starts,5,30);
g.drawString("Paint: "+paints,5,45);
g.drawString("Stop: "+stops,5,60);
}
public void stop() {
stops++;
}
}

Veja o que acontece quando se executa a applet pela primeira vez, e na seqüência,
veja o que acontece a cada minimização e maximização da applet.

Usando as opções do menu “Applet” do appletviewer é possível comandar operações


de: start, stop, restart, reload e clone (duplicação da applet), o que permite testar
adequadamente as applet´s em execução.

4.2- Entrada e Saída Simples


Ao se programar applet´s, deve-se se adaptar à interface gráfica do usuário (GUI –
Graphical User Interface), ou seja, não poderão ser usados os mesmos métodos de entrada e
saída de dados do ambiente texto.

4.2.1- Exibindo Texto numa Applet


É muito simples exibir uma linha texto. Mas como a saída de texto será gráfica, você
precisará usar um dos métodos de exibição de textos em modo gráfico. O mais comumente
usado é drawString(), que faz parte da classe Graphics contida no pacote awt. O programa a
seguir mostra uma applet simples que usa este método para exibir uma única linha de texto.

import java.awt.*;
import java.applet.*;
public class ExibeTexto extends Applet {
public void paint(Graphics g) {
g.drawString("Alo mundo!",25,25);
}
}

Informe ao Java que o programa usa classes do pacote awt.


Informe ao Java que o programa usa classes do pacote applet.
Derive a classe ExibeTexto da classe Applet do Java.
Sobregrave o método paint da classe Applet.
Desenhe uma string na superfície da applet.
Programação Orientada a Objetos

Esta applet quando executada simplesmente mostrará a mensagem “Alo mundo!” em


modo gráfico, seja na janela do appletviewer ou num browser.
Você deve estar se perguntando, como este programa pode ser executado sem ter o
método main()? A resposta é que o método paint() sempre é chamado quando a área de
exibição da applet precisa ser “repintada”. Quando a applet é executada ela tem que ser
“pintada” e o método paint() será acionado pelo controle de eventos do Java. Caso se
coloque algum código neste método, ele será executado normalmente. Desta forma, você roda
a applet, Java chama o método paint(), que chama drawString() que, finalmente, mostra a
mensagem na tela.
Qual o significado daquele “g” seguido de um ponto antes da chamada a
drawString()? Foi dito que drawString() é um método da classe Graphics. Se você verificar
a primeira linha do método paint(), verá Graphics g entre parêntese. Isto significa que Java
está enviando um objeto da classe Graphics ao método paint() e que o objeto é chamado g.
Como já foi visto, toda vez que você precisar chamar um método de um objeto, o nome do
método deve ser precedido pelo nome do objeto seguido de um ponto. Portanto a linha

g.drawString("Alo mundo!",25,25);
instrui o Java a chamar o método drawString() do objeto.

4.2.2- Obtendo Entradas do Usuário


Novamente, pelo fato de você estar programando num ambiente gráfico, obter
entrada do usuário não é tão fácil como simplesmente chamar um comando de entrada. É
necessário primeiramente criar uma área da tela na qual o usuário possa digitar e editar uma
resposta à sua solicitação. Há diversas maneiras de fazer isto, porém uma das mais fáceis é
acrescentar um controle da classe TextField em sua applet. Um objeto TextField é muito
semelhante às caixas de edição que você vê ao usar o Windows. O programa a seguir mostra
como incluir um objeto TextField em sua applet.

// Entrada.java
import java.awt.*;
import java.applet.*;
public class Entrada extends Applet {
TextField campo;
public void init() {
campo = new TextField(20);
add(campo);
}
}

Informe ao Java que o programa usa classes no pacote awt.


Informe ao Java que o programa usa classes no pacote applet.
Derive a classe Entrada da classe Applet do Java.
Declare campo como um objeto da classe TextField.
Sobregrave o método init da classe Applet.
Crie o novo objeto TextField.
Acrescente o objeto TextField à exibição da applet.

Veja esta applet sendo executada:


Programação Orientada a Objetos

Como funciona a applet Entrada


A applet Entrada é um tanto diferente da ExibeTexto. Primeiramente, ela declara um
campo de dados chamado campo como objeto da classe TextField, o que representa uma
caixa de texto. O programa declara o controle assim:

TextField campo;

Observe que o objeto campo é declarado da mesma forma que se declararia qualquer
outro tipo de objeto.
Outra diferença entre Entrada e ExibeTexto é que a primeira possui um método
init() ao invés de paint(). O método init() é mais um daqueles métodos que o Java
chama automaticamente, ou seja, podemos utilizá-lo para montar a applet, pois este é um dos
primeiros métodos a serem acionados pelo controlador de eventos do Java.
Quando init() é chamado, campo já foi declarado como um objeto da classe
TextField, porém ainda não lhe foi atribuído nenhum valor. A primeira linha de código em
init() cria um objeto TextField e o atribui a campo da seguinte forma:

campo = new TextField(20);

O valor entre parênteses é a largura do TextField. Tenha em mente que o TextField


pode armazenar mais texto do que sua largura permite. Se você digitar além do final da caixa
de texto, o texto rola horizontalmente.
A próxima etapa é adicionar o objeto à área de exibição da applet, como segue:

add(campo);

O argumento único do método add() é o controle que você quer acrescentar à applet.

Recuperando texto de um Controle TextField


Na applet Entrada, você pode digitar tudo o que quiser no controle TextField, porém
como você recupera o texto do controle e realmente faz algo com ele? Escreva o código da
applet RecuperaTexto mostrado abaixo:

//RecuperaTexto.java
import java.awt.*;
import java.applet.*;
public class RecuperaTexto extends Applet {
TextField campo;
public void init() {
campo = new TextField(20);
add(campo);
}
public void paint(Graphics g) {
String s = campo.getText();
g.drawString(s,40,50);
}
public boolean action(Event event, Object arg) {
repaint();
return true;
}
}

Informe ao Java que o programa usa classes no pacote awt.


Informe ao Java que o programa usa classes no pacote applet.
Derive a classe RecuperaTexto da classe Applet do Java.
Declare campo como um objeto da classe TextField.
Sobregrave o método init da classe Applet.
Crie o novo objeto campo (TextField)
Programação Orientada a Objetos

Acrescente o objeto campo à exibição da applet.


Sobregrave o método paint da classe Applet.
Obtenha a string do controle TextField.
Exiba o texto na área de exibição da applet.
Sobregrave o método action da classe Applet.
Force a applet a repintar sua área de exibição.
Informe ao Java que o método action terminou com sucesso.

Quando você rodar esta applet, digite algum texto no controle TextField e pressione
ENTER. Este evento irá acionar o método action() que forçará que a applet seja “repintada” e
consequentemente o texto digitado na caixa de texto será escrito no corpo da applet.

Como funciona a applet RecuperaTexto


Se você examinar o código de programa desta applet, poderá ver que foi adicionado
um método paint(). É neste ponto que o texto digitado no controle TextField() é exibido.
Primeiramente, paint() extrai o texto do controle da seguinte forma:

String s = campo.getText();

Esta linha declara um atributo chamado s como sendo um objeto da classe String e
então estabelece uma igualdade com a string do controle. Pode ser visto nesta linha que o
método getText() do objeto campo está sendo chamado. Este método simplesmente retorna a
string que está armazenada no controle TextField.
Exibir a string é tão fácil como chamar seu velho amigo drawString(), como segue:

g.drawString(s,40,50);

Uma grande diferença entre as duas últimas applet´s mostradas (Entrada e


RecuperaTexto) é o método action(). Java chama este método sempre que o usuário
executar algo com controles na applet. Neste caso, a ação a que action() responde é o ato de
o usuário pressionar a tecla ENTER após digitar o texto. Neste exemplo o método action(),
não faz mais nada além de chamar o método repaint(), que informa ao Java a necessidade
de repintar a área de exibição da applet.

Exibindo Valores Numéricos


O problema com valores numéricos no ambiente das applet´s é o fato de que não se
pode exibi-los sem antes convertê-los em string. Felizmente, esta tarefa é bastante simples de
ser executada em Java. Você precisa apenas chamar o método valueOf() da classe String,
como mostrado abaixo:

//ExValNum.java
import java.awt.*;
import java.applet.*;
public class ExValNum extends Applet {
public void paint(Graphics g) {
int x = 10;
String s = String.valueOf(x);
g.drawString(s,40,50);
}
}

Informe ao Java que o programa usa classes no pacote awt.


Informe ao Java que o programa usa classes no pacote applet.
Derive a classe ExValNum da classe Applet do Java.
Sobregrave o método paint da classe Applet.
Declare o inteiro x e configure seu valor para 10.
Converta x numa string.
Exiba a string que representa o valor de x.
Programação Orientada a Objetos

Como pode ser visto no código da applet, a classe String possui um método chamado
valueOf() que pode converter valores numéricos em string´s. O único argumento do método
é o valor que se deseja converter, que pode ser qualquer um dos tipos de dados numéricos de
Java.
Exercícios
1- Construa uma Applet que obtenha dois números inteiros através de duas caixas de
texto. Após pressionar a tecla ENTER, o programa deverá exibir a soma dos números.
2- Construa uma Applet que obtenha um número inteiro através de uma caixa de
texto e mostre os seus divisores.
3- Construa uma Applet que obtenha um número inteiro através de uma caixa de
texto e mostre o número é ou não primo.

4.2.3- Botões e Rótulos


Num ambiente gráfico e com o uso de janelas, obter informações do usuário constitui-
se num verdadeiro desafio. Isto porque o aplicativo atualmente em execução não controla toda
a tela e desta forma não pode simplesmente assumir o controle do teclado ou do dispositivo de
entrada para obter informações do usuário. É por esta razão que os desenvolvedores de
interfaces gráficas do usuário criaram os diversos controles – tais como as caixas de texto,
botões, rótulos e menus – que permitem que os aplicativos interajam com o usuário sem fazer
como que o restante do sistema entre num estado de parada.

Rótulos
Os rótulos são os mais simples dos controles de Java e nada mais são que string´s de
texto que você pode colocar em qualquer posição da área de exibição de uma applet. Um
rótulo é criado chamando-se o construtor da classe Label, como segue:

Label label = new Label(str, align);

O construtor da classe Label possui dois argumentos: o texto para ser exibido e um
valor de alinhamento. O valor de alinhamento pode ser Label.LEFT, Label.CENTER ou
Label.RIGTH. Após criar o rótulo, você deve adicioná-lo à applet utilizando o método add()
como segue:

add(label)

Criando um Rótulo
Suponha que você queira um label centralizado que exiba o texto “Java is hot!”. Para
fazer isto, digite o programa a seguir:

// Rotulo.java
import java.awt.*;
import java.applet.*;
public class Rotulo extends Applet {
Label rotulo;
public void init() {
rotulo = new Label(“Java is hot!”, Label.CENTER);
add(rotulo);
}
}

Uma aspecto interessante a respeito dos rótulos é que eles guardam automaticamente
seus alinhamentos quando o tamanho da área de exibição de uma applet se modifica. As
figuras a seguir mostram o resultado desta applet. A segunda figura foi redimensionada para
ilustrar o alinhamento automático do rótulo.
Programação Orientada a Objetos

Métodos da Classe Label


Após ter criado um objeto Label, você pode usar os métodos da classe para manipular
o rótulo. Especificamente, é possível obter o texto e alinhamento do rótulo de acordo com os
métodos enumerados na tabela abaixo.

Método Descrição
int getAlignment() Recupera a configuração de alinhamento do rótulo.
String getText() Recupera a string do rótulo.
SetAlignment(int align) Configura o alinhamento do rótulo.
void setText(String label) Configura a string do rótulo.

Obs.: Os textos dos rótulos são exibidos com a fonte atualmente em uso. É possível
criar rótulos com fontes distintas desde que se crie e configure a fonte antes de criar o rótulo.

Botões
Os botões são uma excelente forma de disparar eventos em applet´s, pois eles são
fáceis de criar e gerenciar e, mais importante ainda, são simples em termos de utilização pelo
usuário. Para criar um botão, você deve fazer o seguinte:

Button button = new Button(str);

Neste caso, str é a string que aparecerá no botão.


Como acontece em outras classes de Java, Button dispõe de métodos que podem ser
usados pelo programador de modo a manipular um objeto botão. Estes métodos são utilizados
para recuperar ou configurar o texto do botão, como por exemplo:

String button.getLabel()
button.setLabel(str)

Acrescentando um Botão numa Applet


Adicionar botões numa applet é extremamente simples. Basta criar o botão e depois
chamar o método add() para acrescentá-lo na applet. Quando a applet for executada, o
usuário estará apto a interagir com o botão, gerando eventos a que a applet deverá responder
adequadamente.

Manipulando Eventos de Botões Múltiplos


Nas applet´s anteriores os eventos eram respondidos pelo método action() da
applet. Caso exista somente um botão, este método poderá ser utilizado normalmente, porém,
se existirem mais botões, como será feita a identificação de qual botão gerou tal evento? Para
isto deve-se utilizar os dois parâmetros do método action():

public boolean action (Event evt, Object arg)

O primeiro parâmetro, evt, é um objeto Event, e arg, o segundo parâmetro, é, no


caso de um botão, o rótulo do botão. (O tipo do segundo parâmetro modifica-se conforme o
objeto de interface.) O atributo target de um objeto Event indica o tipo de objeto que gerou o
evento. Para determinar o objeto, usamos a palavra-chave instanceof, como a seguir:
Programação Orientada a Objetos

if (evt.target instanceof Button)

Se esta instrução if for true, foi um botão que gerou o evento. Para determinar
exatamente qual botão causou o evento, examinamos o parâmetro arg, como segue:

if (arg == str)

Nesta linha, str é o rótulo do botão. Se a comparação for verdadeira, saberemos


exatamente qual botão recebeu o clique.

Manipulando Múltiplos Botões numa Applet


Para compreender melhor o funcionamento dos eventos provocados por botões,
observe a applet abaixo:

//Botoes.java
import java.awt.*;
import java.applet.*;
public class Botoes extends Applet
{ Button button1, button2, button3;

public void init()


{ button1 = new Button("Button1");
button2 = new Button("Button2");
button3 = new Button("Button3");
add(button1);add(button2);add(button3);
}

public boolean action(Event evt, Object arg)


{ if (evt.target instanceof Button)
TrataBotoes(arg);
return true;
}

protected void TrataBotoes(Object label)


{
if (label == "Button1")
button1.setLabel("1nottuB");
else if (label == "Button2")
button2.setLabel("2nottuB");
else if (label == "Button3")
button3.setLabel("3nottuB");
else
{ button1.setLabel("Button1");
button2.setLabel("Button2");
button3.setLabel("Button3");
}
}
}

Informe ao Java que o programa usa classes no pacote awt.


Informe ao Java que o programa usa classes no pacote applet.
Derive a classe Botoes da classe Applet do Java.
Declare três objetos botão.
Sobregrave o método init().
Crie os três botões.
Adicione os botões à área de exibição da applet.
Sobregrave o método action().
Se um botão foi pressionado, chame o método TrataBotoes().
Informe ao Java que o evento foi tratado de forma adequada.
Defina o método TrataButoes().
Se o rótulo do botão estiver no estado normal, coloque-o em modo inverso.
Caso contrário, configure todos os rótulos dos botões de volta ao estado normal.
Programação Orientada a Objetos

A applet Botoes exibe três botões em sua área de exibição, como apresentado na
figura abaixo. Toda vez que um botão é clicado com rótulo normal, seu respectivo rótulo é
invertido como mostra a segunda figura.

Exercícios
1- Crie uma applet que coloque em sua área de exibição um label, duas caixas de
texto, quatro botões e mais um label. O primeiro label deverá dar uma breve descrição do que
o programa faz. As duas caixas de texto servirão para receber do usuário dois valores inteiros.
Cada um dos botões representará cada uma das operações básicas da matemática (+, -, / e
*). O último label servirá para apresentação do resultado, ou seja, o programa servirá como
uma calculadora.
2- Crie uma applet que coloque em sua área de exibição um label, uma caixa de texto,
três botões e mais um label. O primeiro label deverá dar uma breve descrição do que o
programa faz. A caixa de texto servirá para receber do usuário um valor inteiro. Cada um dos
botões representará uma operação e o último label servirá para exibir os resultados. O botão
“Divisores” deverá exibir os divisores do número. O botão “Qtd Divisores” deverá exibir a
quantidade de divisores do número e o botão “Primo” deverá exibir a mensagem de que o
número é ou não primo.

5- Manipulação de Evento da AWT


O desenvolvimento de applet´s baseia-se no modelo de execução de programa
conhecido como execução orientada a eventos. Este paradigma de programação difere
significativamente do tradicional na forma como se dá o controle de fluxo da execução.
Na programação tradicional, quando o programa precisa ler um dado do teclado, por
exemplo, há a chamada para uma função do sistema que realiza a leitura do teclado. Essa
função fica continuamente monitorando o teclado para poder capturar o valor da tecla
pressionada. Assim, a execução do programa fica suspensa até o momento em que o usuário
resolve prosseguir, pressionando uma tecla.
Por outro lado, na programação orientada a eventos, quando o programa necessita de
um dado ele simplesmente avisa ao usuário sobre essa necessidade, geralmente imprimindo
alguma mensagem na tela, e em seguida continua o processamento realizando alguma outra
tarefa, se for o caso. Quando o usuário pressiona uma tecla, o sistema operacional se
encarrega de avisar ao programa sobre a ocorrência desse "evento" e dar a ele a chance de
realizar o que for preciso com a informação fornecida pelo usuário. Há, contudo, outros tipos
de eventos. Um evento pode ser o clicar ou mover do mouse, entrada de texto, necessidade
de atualizar uma janela, disparo de um temporizador, etc. Processar eventos provenientes do
mouse, por exemplo, é uma grande dificuldade para a programação tradicional, pois
geralmente o programa não tem como prever sobre qual "botão virtual" o usuário vai clicar.
No caso da applet, simplesmente indicamos o que fazer para cada alteração do mouse.
Programação Orientada a Objetos

Os principais originadores de eventos de uma applet são:

➢ teclado
➢ mouse

5.1- Teclado
Existem apenas dois eventos que podem provir do teclado: keyDown e keyUp.

public boolean keyDown(Event evento, int keyCode)

Este método é chamado quando alguma tecla for pressionada. keyCode armazena o
código ASCII correspondente à tecla pressionada. Como existem teclados sem padronização,
existem determinados códigos especiais para designar algumas teclas:

Event.F1 a Event.F12: Tecla de função F1-F12


Event.LEFT: seta para esquerda
Event.RIGHT: seta para direita
Event.UP: seta para cima
Event.DOWN: seta para baixo
Event.END: tecla End
Event.HOME: tecla Home
Event.PGDN: tecla Page Down
Event.PGUP: tecla Page Up
Event.ENTER: tecla ENTER

A informação de que a tecla shift, control e alt foi pressionada é obtida do parâmetro
evento recebido, usando método correspondente. Todos eles retornam um dado boolean
indicando a situação da respectiva tecla. Suponha que o nome do parâmetro de evento (do
tipo Event) é evento. Então temos

evento.shiftDown()- retorna true, se a tecla Shift estiver pressionada no momento


da ocorrência do evento
evento.ctrlDown() – retorna true se a tecla Ctrl estiver pressionada
evento.metaDown() – retorna true se a tecla Alt estiver pressionada

public boolean keyUp(Event event, int keyCode)

Este método é chamado quando a tecla pressionada é liberada pelo usuário. Os


parâmetros recebidos são os mesmo do método keyDown().
Não se esqueça de que ocorrem dois eventos ao pressionar uma tecla: keyDown() e
keyUp(). Não é, porém, obrigatório tratar ambos os eventos. Esses métodos já estão
codificados na classe Applet provendo um tratamento padrão para os respectivos eventos.
Implemente o exemplo a seguir para uma melhor compreensão:

//EventosTeclado.java
import java.awt.*;
import java.applet.*;
public class EventosTeclado extends Applet
{ TextField texto;
Label tecla;
public void init()
{ texto = new TextField(20);
add(texto);
tecla = new Label("Tecla", Label.CENTER);
add(tecla);
}
public boolean keyDown(Event evento, int keyCode)
Programação Orientada a Objetos

{ tecla.setText(String.valueOf(keyCode));
return true;
}
}

Para que os eventos do teclado ocorram, eles devem ser estimulados a partir de
algum componente da applet, é justamente para isto que foi incluído no exemplo acima o
componente TextField. Para a executar corretamente o exemplo você deve startar a applet e
logo após clicar na caixa de texto, aí então pode-se começar a pressionar as teclas para ver os
resultados. Veja o que acontece quando a barra de espaço é pressionada.

5.2- Mouse
Os métodos associados a eventos provenientes do mouse recebem dois parâmetros:
evento do tipo Event e coordenadas x e y da posição do ponteiro mouse (do tipo inteiro)
relativos às coordenadas da janela atual.

public boolean mouseDown(Event event, int x, int y)


O método mouseDown é chamado sempre que o usuário der um clique com o mouse
sobre a área da janela. Os argumentos desse método são um objeto da classe Event e as
coordenadas x e y do ponto da janela em que ocorreu o clique.

public boolean mouseUp(Event event, int x, int y)


Este método é chamado quando botão do mouse que estava pressionado for solto.

public boolean mouseMove(Event event, int x, int y)


Este método é chamado sempre que ocorrer mudança de posição do mouse dentro da
área do applet. O seu argumento é objeto Event e coordenadas x e y do mouse.

public boolean mouseDrag(Event event, int x, int y)


Este método é chamado, quando o usuário arrastar o mouse (pressionar o botão,
mudar de posição sem soltar o botão e em seguida, soltar o botão).

public boolean mouseEnter(Event event, int x, int y)


public boolean mouseExit(Event event, int x, int y)
São chamadas respectivamente quando mouse entra e sai do objeto em que o método
pertence. Podemos usar este método por exemplo, para acender o botão em que o mouse
está, antes mesmo do clique do mouse.
Obs.: No evento do mouse, não há como detectar o botão (se é o direito ou o
esquerdo) do mouse pressionado. Isto deve-se ao fato de que o mouse do computador
Machintoch possui apenas um botão, e Java, por poder ser executado em qualquer plataforma,
assume que o mouse possui apenas um botão.
Implemente o exemplo a seguir para uma melhor compreensão sobre os
acionamentos dos método correspondentes aos eventos do mouse.
Programação Orientada a Objetos

// EventosMouse.java
import java.awt.*;
import java.applet.*;

public class EventosMouse extends Applet


{ Label metodo, coordx, coordy, entrada;
int cont = 0;

public void init()


{ metodo = new Label("---Metodo---");
add(metodo);
coordx = new Label("coordx");
add(coordx);
coordy = new Label("coordy");
add(coordy);
entrada = new Label("Enter");
add(entrada);
}

public boolean mouseDown(Event event, int x, int y)


{ metodo.setText("mouseDown");
coordx.setText(String.valueOf(x));
coordy.setText(String.valueOf(y));
return true;
}
public boolean mouseUp(Event event, int x, int y)
{ metodo.setText("mouseUp");
coordx.setText(String.valueOf(x));
coordy.setText(String.valueOf(y));
return true;
}
public boolean mouseMove(Event event, int x, int y)
{ metodo.setText("mouseMove");
coordx.setText(String.valueOf(x));
coordy.setText(String.valueOf(y));
return true;
}
public boolean mouseDrag(Event event, int x, int y)
{ metodo.setText("mouseDrag");
coordx.setText(String.valueOf(x));
coordy.setText(String.valueOf(y));
return true;
}

public boolean mouseEnter(Event event, int x, int y)


{ metodo.setText("mouseEnter");
coordx.setText(String.valueOf(x));
coordy.setText(String.valueOf(y));
cont++;
entrada.setText(String.valueOf(cont));
return true;
}
public boolean mouseExit(Event event, int x, int y)
{ metodo.setText("mouseExit");
coordx.setText(String.valueOf(x));
coordy.setText(String.valueOf(y));
return true;
}
}
Programação Orientada a Objetos

Veja o resultado:

Exercícios de Revisão
1-Descreva os três argumentos usados com o método drawString().
2-Descreva o funcionamento do método init().
3-Como um valor numérico pode ser convertido em String?
4-Implemente uma applet que obtenha do usuário o seu nome e sua idade. Logo após
a entrada dos dados o programa deverá mostrar o que foi digitado pelo usuário. Veja como
deve ficar a interface:

5-Implemente uma applet que obtenha do usuário três valores inteiros. A seguinte
expressão deverá ser resolvida: valor1 + valor2 / valor3. A applet deverá mostrar uma
interface parecida com a que segue:

6-Escreva uma applet que contenha dois rótulos e dois botões dispostos em duas
linhas. Cada linha deve começar com um rótulo seguido de um botão.
7-O que você por evento?
8-Explique o funcionamento do método mouseEnter().
9-Explique a utilização do método shiftDown().

You might also like