Disciplina: Programação III Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 70

Documentos relacionados
Orientação a Objetos

INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DE ALAGOAS CURSO TECNICO EM INFORMATICA DISCIPLINA:

Introdução a Java. Hélder Nunes

Desenvolvimento OO com Java Orientação a objetos básica

ARRAYS. Um array é um OBJETO que referencia (aponta) mais de um objeto ou armazena mais de um dado primitivo.

DEFINIÇÃO DE MÉTODOS

ATRIBUTOS PRIVADOS 6. ENCAPSULAMENTO MÉTODOS PRIVADOS MÉTODOS PRIVADOS

Roteiro do Programa e Entrada/Saída

2 Orientação a objetos na prática

PROGRAMAÇÃO ESTRUTURADA. CC 2º Período

Implementando uma Classe e Criando Objetos a partir dela

CONVENÇÃO DE CÓDIGO JAVA

3 Classes e instanciação de objectos (em Java)

CURSO DE PROGRAMAÇÃO EM JAVA

Unidade IV: Ponteiros, Referências e Arrays

Programação de Computadores - I. Profª Beatriz Profº Israel

Para criar uma animação precisamos de uma imagem e que ela contenha alguns frames. O número de frames é uma escolha sua.

Engenharia de Software III

UNIVERSIDADE FEDERAL DO PARANÁ

Noções sobre Objetos e Classes

Orientação a Objetos

FBV - Linguagem de Programação II. Um pouco sobre Java

PROGRAMANDO EM C# ORIENTADO A OBJETOS

EXERCÍCIOS SOBRE ORIENTAÇÃO A OBJETOS

Unidade Acadêmica: Faculdade de Computação FACOM Disciplina: Programação Orientada a Objetos I Professor: Fabiano Azevedo Dorça Prática 01

Lógica de Programação

Armazenamento de Dados. Prof. Antonio Almeida de Barros Junior

2ª LISTA DE EXERCÍCIOS CLASSES E JAVA Disciplina: PC-II. public double getgeracaoatual() {return geracaoatual;}

Bacharelado em Ciência e Tecnologia Processamento da Informação. Equivalência Portugol Java. Linguagem Java

JSP - ORIENTADO A OBJETOS

NetBeans. Conhecendo um pouco da IDE

Programação Orientada a Objetos: Lista de exercícios #1. Bruno Góis Mateus

Orientação a Objetos com Java

Criando um script simples

PROGRAMAÇÃO ESTRUTURADA. CC 2º Período

Resolução da lista de exercícios de casos de uso

SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2

Java 2 Standard Edition Como criar classes e objetos

Projeto de Software Orientado a Objeto

Linguagem de Programação JAVA. Técnico em Informática Professora Michelle Nery

Algoritmos I Aula 13 Java: Tipos básicos, variáveis, atribuições e expressões

Entendendo como funciona o NAT

Prototype, um Design Patterns de Criação

2. OPERADORES ALGORITMOS, FLUXOGRAMAS E PROGRAMAS FUNÇÕES... 10

Universidade da Beira Interior Cursos: Matemática /Informática e Ensino da Informática

GUIA BÁSICO DA SALA VIRTUAL

Guia de Fatores de Qualidade de OO e Java

NOVIDADES DO JAVA PARA PROGRAMADORES C

LP II Estrutura de Dados. Introdução e Linguagem C. Prof. José Honorato F. Nunes honorato.nunes@ifbaiano.bonfim.edu.br

Para desenvolver a atividade a atividade desta aula utilizaremos o ambiente de desenvolvimento integrado NetBeans.

Reuso com Herança a e Composiçã

public Agenda() { compromissos = null; } public int getnumerodecompromissos() { if (compromissos==null) return 0; else return compromissos.

APOSTILA 2015 TÉCNICAS DE PROGRAMAÇÃO PROFESSOR: ALEXANDRE. Técnicas de Programação 2º PD

CRIANDO BANCOS DE DADOS NO SQL SERVER 2008 R2 COM O SQL SERVER MANAGEMENT STUDIO

Exercícios de Revisão Java Básico

CAPÍTULO 3 - TIPOS DE DADOS E IDENTIFICADORES

INF1013 MODELAGEM DE SOFTWARE

BC0501 Linguagens de Programação

Prática da Disciplina de Sistemas Distribuídos Serviços Web IFMA DAI Professor Mauro Lopes C. Silva

2 echo "PHP e outros.";

Relacionamentos entre objetos. Relacionamentos entre objetos. Relacionamentos entre objetos. Relacionamentos entre objetos

5 - Vetores e Matrizes Linguagem C CAPÍTULO 5 VETORES E MATRIZES

PARANÁ GOVERNO DO ESTADO

Programação Orientada a Objetos Prof. Rone Ilídio UFSJ/CAP

MANUAL DO ANIMAIL Terti Software

Algoritmos e Programação Estruturada

Especificação do 3º Trabalho

ALGORITMOS PARTE 01. Fabricio de Sousa Pinto

Java. Marcio de Carvalho Victorino

Curso de Programação Computadores

Resumo da Matéria de Linguagem de Programação. Linguagem C

Programação por Objectos. Java

Algoritmos em Javascript

Tabela de Símbolos. Análise Semântica A Tabela de Símbolos. Principais Operações. Estrutura da Tabela de Símbolos. Declarações 11/6/2008

Análise e Projeto de Sistemas

1) Ao ser executado o código abaixo, em PHP, qual será o resultado impresso em tela?

Desenvolvendo Websites com PHP

GUIA MUDANÇA E FORMATAÇÃO DE SERVIDOR - MILLENNIUM

Persistência de Dados

Computação II Orientação a Objetos

Estrutura de Dados Básica

Manual do Ambiente Moodle para Professores

Dadas a base e a altura de um triangulo, determinar sua área.

Capítulo 13. Encapsulamento. Rui Rossi dos Santos Programação de Computadores em Java Editora NovaTerra

Análise e Desenvolvimento de Sistemas ADS Programação Orientada a Obejeto POO 3º Semestre AULA 03 - INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETO (POO)

Criar a classe Aula.java com o seguinte código: Compilar e Executar

Aula 30 - Sockets em Java

INTRODUÇÃO AO JAVA PARA PROGRAMADORES C

Procedimentos para Reinstalação do Sisloc

OCOMON PRIMEIROS PASSOS

Na Figura a seguir apresento um exemplo de uma "mini-tabela" de roteamento:

Linguagem de Programação III

Google Drive. Passos. Configurando o Google Drive

Bem- Vindo ao manual de instruções do ECO Editor de COnteúdo.

Curso: Desenvolvendo Jogos 2d Com C# E Microsoft XNA. Mostrar como funciona a programação orientada a objetos

02 - Usando o SiteMaster - Informações importantes

Técnicas de Programação II

BSI UFRPE Prof. Gustavo Callou

GUIA MUDANÇA E FORMATAÇÃO DE SERVIDOR - SLIM

Transcrição:

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 70 3.7 TRABALHANDO COM CLASSES E OBJETOS Origem: Capítulo 3 Introdução a classes e Objetos. Livro: Java Como Programar, Deitel & Deitel, 6ª. Edição; capítulo 4 Orientação a Objetos Básica, capítulo 6 Modificadores de Acesso e Atributos de Classe. Apostila FJ-11 (Java e Orientação a Objetos) Escrever um programa utilizando uma linguagem de programação orientada a objeto significa criar um programa que será composto por uma série de objetos (identificados a partir do mundo real), com propriedades, características e interações. Um conjunto de objetos com características similares é representado através de uma classe, e assim, a programação orientada a objeto foca sua atenção na identificação das classes que irão compor um problema. Qualquer característica, seja informacional ou comportamental, na programação orientada a objeto deverá ser definida através de uma classe. Mesmo que o programa seja muito pequeno e requeira apenas o método main(), ainda sim este deverá ser declarado através de uma classe, como já comentado anteriormente. 3.7.1 UMA CLASSE EM JAVA Considere um programa para um banco. Uma entidade extremamente importante para o sistema é a conta. A idéia aqui é generalizar alguma informação, juntamente com funcionalidades que toda conta deve ter. O que toda conta tem de importante? Número da conta; Nome do cliente; Saldo; Limite. O que toda conta faz de importante? Sacar uma quantidade x; Depositar uma quantidade x; Imprimir o nome do dono da conta; Devolver o saldo atual; Transferir uma quantidade x entre uma conta e outra; Devolver o tipo de conta. Com isso, tem-se o projeto de uma conta bancária. Podemos pegar esse projeto e acessar seu saldo? Não. O que temos ainda é o projeto (a classe). Antes, precisamos construir (instanciar) uma conta, para poder acessar o que ela tem, e pedir a ela que faça alguma coisa. Declaração básica de uma classe em Java Considerando as propriedades que uma Conta deve ter (e não o que ela faz), teria-se o seguinte código Java: /* Arquivo: Conta.java Contém o tratamento de uma Conta Bancária */

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 71 public class Conta { int numero; String nome; double saldo; double limite; //.. Estes são os atributos que toda conta, quando criada, vai ter. Repare que essas variáveis foram declaradas fora de um bloco de método, sendo diferente de variáveis locais a métodos. Quando uma variável é declarada diretamente dentro do escopo da classe, é chamada de variável de objeto (ou de instância), ou atributo. A declaração de toda classe deve conter a palavra-chave class seguida pelo nome da classe. A palavra-chave public é um modificador de acesso, que declara que o acesso à classe é público. O corpo de cada classe estará entre os delimitadores { e A declaração de todo atributo segue a sintaxe de declaração de variáveis, visto os atributos serem as variáveis de instância de um objeto. 3.7.2 CRIANDO E USANDO UM OBJETO Criar uma classe é apenas declarar as definições de suas características. Para utilizar essas características é preciso instanciar um objeto. Uma vez que se criou uma classe, ela poderá ser utilizada em outras classes, através de sua instanciação. Cada objeto criado terá seu estado e comportamento próprios, além da identidade única, e essas serão justamente as características que poderão ser acessadas pelos objetosclientes (de acordo com a especificação de acesso da característica, claro). Para criar (construir, instanciar) uma Conta, basta usar a palavra-chave new. Utiliza-se também os parênteses, que serão explicados em item posterior: /* Arquivo: Programa.java Programa responsável por utilizar a classe Conta */ public class Programa { public static void main(string[] args) { new Conta(); O código acima é conhecido como Expressão de criação de instância de classe (formado pela palavra-chave new e o nome da classe seguido por parênteses disparando um construtor que será posteriormente detalhado). O código acima cria um objeto do tipo Conta, mas como acessar esse objeto que foi criado? É preciso ter alguma forma de nos referenciarmos a esse objeto, o que é feito através de uma variável. O código acima deve ser substituído por:

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 72 /* Arquivo: Programa.java Programa responsável por utilizar a classe Conta */ public class Programa { public static void main(string[] args) { Conta minhaconta; minhaconta = new Conta(); Uma classe, após ser criada em Java, pode ser considerada como um tipo definido pelo usuário, e portanto, podemos ter uma variável declarada como sendo desse tipo. Pode parecer estranho escrevermos duas vezes Conta: uma vez na declaração da variável e outra vez no uso do new. As duas instruções acima descritas (declaração de uma variável do tipo da classe e instanciação dessa variável) podem ser disponibilizadas em uma única instrução, como no exemplo abaixo: Conta minhaconta = new Conta(); //forma mais comum de declaração Através da variável minhaconta, agora é possível acessar o objeto recém criado para alterar seu nome, seu saldo, etc: /* Arquivo: Programa.java Programa responsável por utilizar a classe Conta */ public class Programa { public static void main(string[] args) { Conta minhaconta = new Conta(); /* Alteração de valores de atributos do objeto minhaconta */ minhaconta.nome = "Duke"; minhaconta.saldo = 1000.0; System.out.println("Saldo atual: " + minhaconta.saldo); É importante destacar que o acesso aos atributos/métodos de um objeto ocorre através da notação de ponto, com o nome do objeto à esquerda do ponto e o atributo/método à direita. OBSERVAÇÃO: (1) Apesar do acesso direto aos valores de um objeto ser possível, segundo os princípios da orientação a objeto (encapsulamento) ele deve ser evitado. Um objeto-cliente não deve acessar diretamente os atributos de um outro objeto. Para tal acesso / atualização devem ser criados métodos getters e setters (e habitualmente tem-se um método get() e outro set() para cada atributo da classe que precise ser manipulado).

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 73 (2) É comum criar uma classe separada para conter o método main() e fazer a chamada do(s) método(s) que irão efetivamente realizar a execução do programa, similar ao que ocorre no exemplo acima com as classes Conta e Programa. 3.7.3 MÉTODOS Dentro da classe, também deve ser declarado o que cada conta faz e como isto é feito, ou seja, o comportamento que cada classe tem. Por exemplo, de que maneira uma conta saca dinheiro? Isso é especificado dentro da própria classe Conta, e não em um local desatrelado das informações da própria conta. É por isso que essas funções são chamadas de métodos. Pois é a maneira de fazer uma operação com um objeto. Assim, qualquer tarefa que precise ser realizada em um programa Java deve ser declarada através de um método, que irá conter os mecanismos necessários para a execução da tarefa. Uma declaração de método é composta por: Cabeçalho / Assinatura formado por especificador de acesso (opcional) + tipo de dados de retorno (void para nenhum retorno) + nome do método + parênteses (e dentro deles a lista de parâmetros - a declaração das variáveis locais que são parâmetros de entrada para o método em questão. Parênteses vazios indicam que não há parâmetro de entrada); Corpo contém o código-fonte a ser executado, delimitado entre chaves. Em caso de método com retorno indicado no cabeçalho em algum momento antes do delimitador final deve estar presente a palavra-chave return, seguido do retorno esperado. Por exemplo: Para criar um método que saca uma determinada quantidade e não devolve nenhuma informação para quem acionar esse método tem-se o seguinte código. /* Arquivo: Conta.java Contém o tratamento de uma Conta Bancária */ public class Conta { //Declaração de variáveis de instância int numero; String nome; double saldo; double limite; //Declaração de método void sacar (double quantidade) { double novosaldo = this.saldo - quantidade; this.saldo = novosaldo; A palavra-chave void indica que não há nenhum retorno para o método, ou seja, quando você pedir para a conta sacar uma quantia, nenhuma informação será enviada de volta a quem pediu. Quando alguém pedir para sacar, ele também vai dizer quanto quer sacar. Por isso precisamos declarar o método com tal informação de entrada - um argumento do método (ou parâmetro).

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 74 Essa variável é uma variável comum, chamada também de temporária ou local, pois, ao final da execução desse método, ela deixa de existir. Dentro do método, é declarada uma nova variável (novosaldo). Essa variável, assim como o argumento, vai morrer no fim do método, pois este é seu escopo. Para diferenciar o uso de variáveis locais ao método e variáveis de instância da classe é utilizada a palavra-chave this, para se referenciar a um valor do objeto (como é feito no exemplo acima para this.saldo). Da mesma forma, temos o método para depositar alguma quantia: class... { //... outros atributos e métodos... void depositar (double quantidade) { this.saldo += quantidade; Observe que, agora, não foi usada uma variável auxiliar e, além disso, usou-se o comando reduzido += para deixar o método bem simples. O += soma quantidade ao valor antigo de saldo e guarda no próprio saldo o valor resultante. Para mandar uma mensagem ao objeto e solicitar que ele execute um método, também é usada a notação de ponto. O termo usado para isso é invocação (chamada) de método. O método main() é o único método executado automaticamente pela Java Virtual Machine. Qualquer outro método para ser executado deverá ser invocado por algum outro método. O código a seguir saca dinheiro e depois deposita outra quantia na conta exemplo que estamos trabalhando. /* Arquivo: SacaEDeposita.java Classe responsável por realizar saques e depósitos em uma conta */ public class SacaEDeposita { public static void main(string[] args) { // criando a conta Conta minhaconta = new Conta(); // alterando os valores de minhaconta minhaconta.nome = "Duke"; minhaconta.saldo = 1000; // saca 200 reais minhaconta.sacar(200); // deposita 500 reais minhaconta.depositar(500);

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 75 // exibe saldo da conta System.out.println(minhaConta.saldo); Uma vez que seu saldo inicial é 1000 reais, se sacarmos 200 reais, depositarmos 500 reais e imprimirmos o valor do saldo, o que será impresso? OBSERVAÇÃO: A chamada de um método deve estar sempre associada aos parênteses ao final do nome do método, mesmo que o método em questão não contenha argumentos de entrada; Observar no exemplo acima que a chamada dos métodos sacar() e depositar() são realizadas com o informe de um argumento cada, que será o valor passado para o método, já que ambos requerem parâmetros de entrada em suas execuções; Um método pode especificar múltiplos parâmetros, separando cada um deles do próximo com uma vírgula. O número de argumentos em uma chamada de método deve corresponder ao número de parâmetros na lista de parâmetros da declaração do método chamado. Além disso, os tipos de dados dos argumentos na chamada de método devem ser consistentes com os tipos dos parâmetros correspondentes na declaração do método. Não precisa haver correspondência de nome entre o argumento passado para o método e o parâmetro no método declarado. 3.7.4 MÉTODOS COM RETORNO Um método sempre tem que retornar alguma coisa, nem que essa coisa seja nada, como nos exemplos anteriores onde é usada a palavra-chave void. Um método pode retornar um valor para o cliente que o chamou. No caso do exemplo do método sacar() pode-se devolver um valor booleano indicando se a operação foi bem sucedida. /* Arquivo: Conta.java Contém o tratamento de uma Conta Bancária atualização */ public class Conta { //Declaração de variáveis de instância int numero; String nome; double saldo; double limite; //Método para realização da operação de saque, com retorno boolean sacar (double valor) { if (this.saldo < valor) { return false; else { this.saldo = this.saldo - valor; return true;

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 76 //Método para realização da operação de depósito, sem retorno void depositar (double quantidade) { this.saldo += quantidade; Agora a declaração do método mudou. O método sacar() não tem void na frente, isto quer dizer que, quando é acessado, ele devolve algum tipo de informação. No caso, um boolean. A palavra-chave return indica que o método vai terminar ali, retornando tal informação. Exemplo de uso: minhaconta.saldo = 1000; boolean consegui = minhaconta.sacar(2000); if(consegui) { System.out.println("Consegui sacar"); else { System.out.println("Não consegui sacar"); Ou então, posso eliminar a variável temporária, se desejado: minhaconta.saldo = 1000; System.out.println(minhaConta.sacar(2000)); Mais adiante, veremos que algumas vezes é mais interessante lançar uma exceção (exception) nesses casos. Trabalhando com mais de um objeto O programa pode manter na memória não apenas uma conta, porém várias. Essa possibilidade é demonstrada no exemplo abaixo. /* Arquivo: TestaDuasContas.java Classe que trabalha com dois objetos da classe conta */ public class TestaDuasContas { public static void main(string[] args) { Conta minhaconta = new Conta(); minhaconta.saldo = 1000; System.out.println( Saldo da 1ª. Conta: + minhaconta.saldo); Conta meusonho = new Conta(); meusonho.saldo = 1500000; System.out.println( Saldo da 2ª. Conta: + meusonho.saldo);

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 77 3.7.5 VARIÁVEIS POR REFERÊNCIA Quando declaramos uma variável para associar a um objeto, na verdade, essa variável não guarda uma cópia do objeto (como ocorre com tipos de dados primitivos), e sim uma maneira de acessá-lo, chamada de referência, que é uma referência a memória onde o objeto está armazenado. É por esse motivo que é necessário o uso do comando new após a declaração da variável. Seja o exemplo parcial de código: public static void main(string args[]) { Conta c1 = new Conta(); Conta c2 = new Conta(); O correto aqui é dizer que c1 se refere a um objeto. Não é correto dizer que c1 é um objeto, pois c1 é uma variável por referência, apesar de, depois de um tempo, os programadores Java falarem Tenho um objeto c1 do tipo Conta, mas apenas para encurtar a frase Tenho uma referência c1 a um objeto do tipo Conta. Esse código nos deixa na seguinte situação: Internamente, c1 e c2 vão guardar um número que identifica em que posição da memória as contas instanciadas se encontram. Dessa maneira, ao utilizarmos o. para navegar, o Java vai acessar a conta que se encontra naquela posição de memória, e não uma outra. Para quem conhece, é parecido com um ponteiro, porém você não pode manipulá-lo e utilizá-lo para guardar outras coisas. Agora vamos a um outro exemplo. /* Arquivo: TestaReferencias.java Aplicativo responsável por testar declaração de variável por referência */ public class TestaReferencias { public static void main(string args[]) { Conta c1 = new Conta(); c1.depositar(100); Conta c2 = c1; // linha importante!

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 78 c2.depositar(200); System.out.println(c1.saldo); System.out.println(c2.saldo); Qual é o resultado do código acima? O que aparece ao rodar? O que acontece aqui? O operador de atribuição ( = ) copia o valor de uma variável. Mas qual é o valor da variável c1? É o objeto? Não. Na verdade, o valor guardado é a referência (endereço) de onde o objeto se encontra na memória principal. Na memória, o que acontece nesse caso é descrito pela figura abaixo. Quando fizemos c2 = c1, c2 passa a fazer referência para o mesmo objeto que c1 referencia nesse instante. Então, nesse código em específico, quando utilizamos c1 ou c2 estamos nos referindo exatamente ao mesmo objeto! Elas são duas referências distintas, porém apontam para o mesmo objeto! Compará-las com == irá nos retornar true, pois o valor que elas carregam é o mesmo! Outra forma de perceber, é que executamos apenas um new, então só pode haver um objeto Conta na memória. Atenção: não estamos discutindo aqui a utilidade de fazer uma referência apontar pro mesmo objeto que outra. Essa utilidade ficará mais clara quando passarmos variáveis do tipo referência como argumento para métodos. new O que exatamente faz o new? O new executa uma série de tarefas, que veremos mais adiante. Mas, para melhor entender as referências no Java, saiba que o new, depois de alocar a memória para esse objeto, devolve uma flecha, isto é, um valor de referência. Quando você atribui isso a uma variável, essa variável passa a se referir para esse mesmo objeto. Podemos então ver outra situação no código a seguir. /* Arquivo: TestaReferencias2.java Aplicativo responsável por testar declaração de variável por referência */

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 79 public class TestaReferencias2 { public static void main(string args[]) { Conta c1 = new Conta(); c1.nome = "Duke"; c1.saldo = 227; Conta c2 = new Conta(); c2.nome = "Duke"; c2.saldo = 227; if (c1 == c2) { System.out.println("Contas iguais"); else { System.out.println("Contas diferentes"); O operador == compara o conteúdo das variáveis, mas essas variáveis não guardam o objeto, e sim o endereço em que ele se encontra. Como em cada uma dessas variáveis guardamos duas contas criadas diferentemente, eles estão em espaços diferentes da memória, o que faz o teste no if retornar false. As contas podem ser equivalentes no nosso critério de igualdade, porém elas não são o mesmo objeto. Quando se trata de objetos, pode ficar mais fácil pensar que o == compara se os objetos (referências, na verdade) são o mesmo, e não se são iguais em termos de estado. Para saber se dois objetos têm o mesmo conteúdo, você precisa comparar atributo por atributo. Veremos uma solução mais elegante para isso também. Mais um exemplo: E se quisermos ter um método que transfere dinheiro entre duas contas? Podemos ficar tentados a criar um método que recebe dois parâmetros: conta1 e conta2 do tipo Conta. Mas cuidado: assim estamos pensando de maneira procedural. A idéia é que, quando chamarmos o método transferir(), já teremos um objeto do tipo Conta (o this), portanto o método recebe apenas um parâmetro do tipo Conta, a conta destino (além do valor). Seja o código abaixo: /* Arquivo: Conta.java Tratamento de uma conta acréscimo de código */ public class Conta { // atributos e métodos... //Método que realiza transferência entre uma conta origem e //outra destino void transferir(conta destino, double valor) { this.saldo = this.saldo - valor; destino.saldo = destino.saldo + valor;

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 80 Para deixar o código mais robusto, poderíamos verificar se a conta possui a quantidade a ser transferida disponível. Para ficar ainda mais interessante, pode-se chamar os métodos depositar() e sacar() já existentes para fazer essa tarefa. Um possível código está a seguir transcrito. /* Arquivo: Conta.java Tratamento de uma conta acréscimo de código */ public class Conta { // atributos e métodos... boolean transferir(conta destino, double valor) { boolean retirou = this.sacar(valor); if (retirou == false) { // não deu pra sacar! return false; else { destino.depositar(valor); return true; Quando passamos uma conta como argumento, o que será que acontece na memória? Será que o objeto é clonado? No Java, a passagem de parâmetro funciona como uma simples atribuição, como no uso do =. Então, esse parâmetro vai copiar o valor da variável do tipo Conta que for passado como argumento. E qual é o valor de uma variável dessas? Seu valor é um endereço, uma referência, nunca um objeto. Por isso não há cópia de objetos aqui. Esse último código poderia ser escrito com uma sintaxe muito mais clara. Como? Perceber que o nome deste método poderia ser transferirpara() ao invés de só transferir(). A chamada do método fica muito mais natural, pois é possível ler a frase em português que ela tem um sentido. conta1.transferirpara(conta2, 50); A leitura deste código seria conta 1 transfere para conta 2 R$50.

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 81 3.7.6 ATRIBUTOS Os atributos ou variáveis de instância declaradas em uma classe têm valores exclusivos para cada objeto da classe, e portanto, havendo mais de um objeto da mesma classe declarados em um mesmo método, esses terão seus valores tratados completamente em separado. Ao contrário da maior parte das classes e dos métodos, os atributos costumam ser declarados com o modificador de acesso private, indicando que tais variáveis são acessíveis apenas dentro da própria classe na qual estão declaradas. Essa especificação é seguida para preservar o princípio de encapsulamento da orientação a objetos. Normalmente as variáveis de instância são declaradas logo após a declaração do cabeçalho da classe, como forma de ficarem mais legíveis e fáceis de serem localizadas para serem utilizadas nos métodos das classes. No entanto suas declarações podem ficar em qualquer ponto de uma classe, desde que estejam fora da declaração de um método. Lembrando que se estiverem dentro da declaração de um método serão consideradas variáveis locais ao método, e não variáveis de instância. As variáveis do tipo atributo, diferentemente das variáveis temporárias (declaradas dentro de um método), recebem um valor padrão. No caso numérico valem 0, no caso de boolean valem false, no caso de classes valem null. Também é possível estabelecer valores default, como segue no exemplo: public class Conta { //Declaração de atributos private int numero = 1234; private String nome = "Duke"; private String cpf = "123.456.789-10"; private double saldo = 1000; private double limite = 1000; /* Declaração de método set para manipulação do atributo numero Recebe um Parâmetro de entrada cujo valor será repassado para o atributo */ public void setnumero (int numero) { this.numero = numero; //this.numero se refere à variável de //instância. numero se refere ao //parâmetro de entrada /* Declaração de método get para manipulação do atributo numero retorna o valor do atributo, para o método que o houver chamado */ public int getnumero() { return this.numero; Nesse caso, quando você criar uma conta, seus atributos já estão populados com esses valores colocados. Essa solução não é a mais comum para inicialização de atributos, normalmente trabalha-se com construtores (que serão posteriormente detalhados).

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 82 Imagine que, agora, começamos a aumentar nossa classe Conta e queremos adicionar sobrenome e cpf do cliente dono da conta. Começaríamos a ter muitos atributos relacionados ao cliente e, se você pensar direito, uma conta não tem nome, nem sobrenome, nem cpf, quem tem esses atributos é um cliente. Então podemos criar uma nova classe e fazer uma composição. Os atributos também podem ser referências para outras classes. Suponha a seguinte classe Cliente, e uma declaração alterada da classe Conta: class Cliente { String nome; String sobrenome; String cpf; class Conta { int numero; double saldo; double limite; Cliente titular; //.. E dentro do main() da classe de teste, tem-se: class Teste { public static void main(string[] args) { Conta minhaconta = new Conta(); Cliente c = new Cliente(); minhaconta.titular = c; //... Aqui, simplesmente houve uma atribuição. O valor da variável c é copiado para o atributo titular do objeto ao qual minhaconta se refere. Em outras palavras, minhaconta agora tem uma referência ao mesmo cliente ao qual c se refere, e pode ser acessado através de minhaconta.titular. Você pode realmente navegar sobre toda essa estrutura de informação, sempre usando a notação de ponto: Cliente clientedaminhaconta = minhaconta.titular; clientedaminhaconta.nome = "Duke"; Ou ainda, pode fazer isso de uma forma mais direta e até mais elegante: minhaconta.titular.nome = "Duke";

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 83 Um sistema orientado a objetos é um grande conjunto de classes que vai se comunicar, delegando responsabilidades para quem for mais apto a realizar determinada tarefa. A classe Banco usa a classe Conta que usa a classe Cliente, que usa a classe Endereco. Dizemos que esses objetos colaboram, trocando mensagens entre si. Por isso acabamos tendo muitas classes em nosso sistema, e elas costumam ter um tamanho relativamente curto. Mas, e se dentro do meu código eu não desse new em Cliente e tentasse acessá-lo diretamente? public class Teste { public static void main(string[] args) { Conta minhaconta = new Conta(); minhaconta.titular.nome = "paulo"; //... Quando damos new em um objeto, ele o inicializa com seus valores default, 0 para números, false para boolean e null para referências. null é uma palavra-chave em Java, que indica uma referência para nenhum objeto. Se, em algum caso, você tentar acessar um atributo ou método de alguém que está se referenciando para null, você receberá um erro durante a execução (NullPointerException, que veremos mais à frente). Dá para perceber, então, que o new não traz um efeito cascata, a menos que você dê um valor default (ou use construtores, que também veremos mais a frente). Uma forma de resolver a questão comentada poderia ser como no código seguinte. class Conta { int numero; double saldo; double limite; Cliente titular = new Cliente(); // quando chamarem new Conta, //haverá um new Cliente para ele. Com esse código, toda nova conta criada já terá um novo cliente associado, sem necessidade de instanciá-lo logo em seguida da instanciação de uma conta. Qual alternativa você deve usar? Depende do caso: para toda nova conta você precisa de um novo cliente? É essa pergunta que deve ser respondida. Nesse nosso caso a resposta é não, mas depende do nosso problema. Atenção: para quem não está acostumado com referências, pode ser bastante confuso pensar sempre em como os objetos estão na memória para poder tirar as conclusões do que ocorrerá ao executar determinado código, por mais simples que ele seja. Com o tempo, você adquire a habilidade de rapidamente saber o efeito de atrelar as referências, sem ter de gastar muito tempo para isso. É importante, nesse começo, você estar sempre pensando no estado da memória. E realmente lembrar que, no Java uma variável nunca carrega um objeto, e sim uma referência para ele facilita muito.

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 84 3.7.7 UM NOVO EXEMPLO Além do exemplo do Banco criado anteriormente, vamos ver como ficariam certas classes relacionadas a uma fábrica de carros. Se uma classe Carro, com certos atributos, que descrevem suas características, e com certos métodos, que descrevem seu comportamento. /* Arquivo: Carro.java Classe com o tratamento de um carro */ //classe Motor componente de um carro class Motor { int potencia; String tipo; //inicialização das características de um motor Motor() { this.potencia = 10; this.tipo = Flex ; //Classe carro, com as características de um carro public class Carro { String cor; String modelo; double velocidadeatual; double velocidademaxima; Motor motor; //liga o carro void ligar() { System.out.println("O carro está ligado"); //acelera uma certa quantidade void acelerar(double quantidade) { double velocidadenova = this.velocidadeatual + quantidade; this.velocidadeatual = velocidadenova; //devolve a marcha do carro int pegarmarcha() { if (this.velocidadeatual < 0) {

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 85 return -1; if (this.velocidadeatual >= 0 && this.velocidadeatual < 40) { return 1; if (this.velocidadeatual >= 40 && this.velocidadeatual < 80){ return 2; return 3; Agora, vamos testar nosso Carro em um programa de testes. /* Arquivo: TestaCarro.java Classe com o tratamento para teste de um carro */ import java.util.scanner; public class TestaCarro { public static void main(string[] args) { Carro meucarro = new Carro(); meucarro.motor = new Motor(); Scanner input = new Scanner(System.in); System.out.print( Informe a cor do carro: ); meucarro.cor = input.nextline(); //método que lê uma linha de texto System.out.print( Informe o modelo do carro: ); meucarro.modelo = input.nextline(); System.out.print( Informe a velocidade atual do carro: ); meucarro.velocidadeatual = input.nextdouble(); //método para //leitura de //valor double System.out.print( Informe a velocidade máximo do carro: ); meucarro.velocidademaxima = input.nextdouble(); // liga o carro meucarro.ligar(); // acelera o carro meucarro.acelerar(20); System.out.println(meuCarro.velocidadeAtual);

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 86 OBSERVAÇÃO: (1) Da classe Scanner já foram estudados os seguintes métodos: nextint() leitura de um valor numérico inteiro; nextdouble() leitura de um valor numérico em ponto flutuante; nextline() leitura de uma linha de caracteres (do início da linha ao fim, quando se encontra um caracter de nova linha, que não é incluído na string que recebe o valor lido). Um outro método é o seguinte: next() leitura de uma palavra até que se encontre um espaço em branco (espaço, tabulação ou nova linha). Se naquela linha ainda sobrar outros textos esses poderão ser acessados com a chamada de novos métodos. Discussão sobre o comando nextline() e problemas com sua saída -> O uso do nextline() lê o caracter de pula linha, enquanto os outros métodos de leitura de Scanner não. Recomenda-se o uso de um nextline() após cada next() lido só para garantir que o caracter de pula linha será lido. O problema só ocorre se após algum next() tentar-se usar o nextline(), pois este irá reconhecer o caracter de pula linha e assumir que o necessário já foi lido. (2) Sobre a declaração de importação de classe No exemplo acima há uma instrução de importação de classe (a Scanner, pertencente ao pacote java.util). Essa declaração indica ao compilador que o programa utiliza a classe Scanner. A dúvida é: Por que precisa dessa instrução para Scanner, mas não para System, String ou Carro? A maioria das classes utilizadas em programas Java precisa ser importada. As classes System e String pertencem ao pacote java.lang, que é implicitamente importado em todo programa Java, daí não ser necessária uma importação explícita (como no caso de Scanner). Há um relacionamento especial entre as classes que são compiladas no mesmo diretório no disco, como as classes Carro e TestaCarro. Por padrão, considera-se que essas classes estão no mesmo pacote (conhecido como pacote padrão). As classes no mesmo pacote também são importadas implicitamente nos arquivos de código-fonte de outras classes no mesmo pacote, sem requerer a importação explícita. Uma outra forma de declaração de importação de classe pode ser utilizada. Ela é conhecida como nome de classe completamente qualificado. Se o nome da classe for completamente utilizado, a declaração de importação, através da palavra-chave import não é necessária. Por exemplo, a declaração de importação da classe Scanner poderia ser feita da seguinte maneira, reunida com a declaração de criação: java.util.scanner input = new java.util.scanner(system.in); 3.7.8 O CONSTRUTOR DE UMA CLASSE O que devemos fazer quando queremos inicializar as variáveis de instância de um objeto no momento de sua instanciação? A resposta a essa pergunta está no Construtor da Classe. E o Java requer a chamada de um construtor para cada objeto que for criado. Quando usamos a palavra chave new, estamos construindo um objeto. Sempre quando o new é chamado, ele executa o construtor da classe. O construtor da classe é um bloco declarado com

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 87 o mesmo nome da classe, seguido por parênteses (que pode, ou não, conter argumentos como ocorre com um método comum): class Conta { int numero; Cliente titular; double saldo; double limite; // construtor Conta() { System.out.println("Construindo uma conta."); //.. Então, quando fizermos: Conta c = new Conta(); A mensagem Construindo uma conta aparecerá. É como uma rotina de inicialização que é chamada sempre que um novo objeto é criado. Um construtor pode parecer, mas não é um método. O construtor default Até agora, as nossas classes não possuíam nenhum construtor. Então como é que era possível dar new, se todo new chama um construtor obrigatoriamente? Quando você não declara nenhum construtor na sua classe, o Java cria um para você. Esse construtor é o construtor default, ele não recebe nenhum argumento e o corpo dele é vazio. A partir do momento que você declara um construtor, o construtor default não é mais fornecido. O interessante é que um construtor pode receber um argumento, podendo assim inicializar algum tipo de informação, e não da forma fixa que ocorreria com a inicialização da variável no momento de sua declaração. Pode-se perceber tal situação pelo exemplo abaixo. class Conta { int numero; Cliente titular; double saldo, limite; // construtor Conta (Cliente titular){ this.titular = titular; //..

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 88 Esse construtor recebe o titular da conta. Assim, quando criarmos uma conta, ela já terá um determinado titular. O trecho de código acima pode ser complementado por: Cliente carlos = new Cliente(); carlos.setnome("carlos"); Conta c = new Conta(carlos); System.out.println(c.getTitular().setNome()); A necessidade de um construtor Tudo estava funcionando até agora. Para que utilizamos um construtor? A idéia é bem simples. Se toda conta precisa de um titular, como obrigar todos os objetos que forem criados a ter um valor desse tipo? Basta criar um único construtor que recebe essa entrada! O construtor se resume a isso! Dar possibilidades ou obrigar o usuário de uma classe a passar argumentos para o objeto durante o processo de criação do mesmo. Por exemplo, não podemos abrir um arquivo para leitura sem dizer qual é o nome do arquivo que desejamos ler! Portanto, nada mais natural que passar uma String representando o nome de um arquivo na hora de criar um objeto do tipo de leitura de arquivo, e que isso seja obrigatório. Você pode ter mais de um construtor na sua classe e, no momento do new, o construtor apropriado será escolhido. Os diferentes construtores são diferenciados pela sua assinatura. Como nesse caso o nome é o mesmo, será a lista de parâmetros que irá indicar o construtor adequado a ser disparado. Construtor: um método especial? Um construtor não é um método. Algumas pessoas o chamam de um método especial, mas definitivamente não é, já que não possui retorno e só é chamado durante a construção do objeto. Chamando outro construtor Um construtor só pode rodar durante a construção do objeto, isto é, você nunca conseguirá chamar o construtor em um objeto já construído. Porém, durante a construção de um objeto, você pode fazer com que um construtor chame outro, para não ter de ficar copiando e colando. Isso pode ser observado no exemplo a seguir. class Conta { private int numero; private Cliente titular; private double saldo; private double limite; // construtores public Conta (Cliente titular) { // faz mais uma série de inicializações e configurações this.titular = titular; public Conta (int numero, Cliente titular) {

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 89 this(titular); // chama o construtor que foi declarado acima //Precisa ser a 1ª. Instrução do código this.numero = numero; //.. Existe um outro motivo, o outro lado dos construtores: facilidade. Às vezes, criamos um construtor que recebe diversos argumentos para não obrigar o usuário de uma classe a chamar diversos métodos do tipo set. No nosso exemplo do Banco, podemos forçar que a classe Cliente receba no mínimo o CPF, dessa maneira um cliente já será construído com um CPF válido. OBSERVAÇÃO: Normalmente os construtores são declarados públicos, isto é, contém a palavrachave public em sua declaração. Java Bean Quando criamos uma classe com todos os atributos privados, seus getters e setters e um construtor vazio (padrão), na verdade estamos criando um Java Bean (mas não confunda com EJB, que é Enterprise Java Beans componentes utilizados em servidores). Um Java Bean é um componente de software reutilizável, seguindo algumas convenções de nomeclatura de métodos, construtores e comportamento. Para saber mais acesse: http://java.sun.com/products/javabeans/ 3.7.9 LEITURA RECOMENDADA Material indicado no início do tópico, como origem do texto disponibilizado; Fóruns na Internet. 3.7.10 EXERCÍCIOS 1. O objetivo dos exercícios a seguir é fixar o conceito de classes e objetos, métodos e atributos. Dada a estrutura de uma classe, basta traduzí-la para a linguagem Java e fazer uso de um objeto da mesma em um programa simples. a) Programa 1 b) Programa 2 Classe: Pessoa Atributos: nome, idade. Método: void fazeraniversario() Crie uma pessoa, coloque seu nome e idade iniciais, faça alguns aniversários (aumentando a idade) e imprima seu nome e sua idade. Classe: Porta Atributos: aberta, cor, dimensaox, dimensaoy, dimensaoz

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 90 3) Programa 3 Métodos: void abrir(), void fechar(), void pintar(string s), boolean checarestaaberta() Crie uma porta, abra e feche a mesma, pinte-a de diversas cores, altere suas dimensões e use o método ChecarEstaAberta() para verificar se ela está aberta. Classe: Casa Atributos: cor, porta1, porta2, porta3 Método: void pintar(string s), int verficarportasestaoabertas() Crie uma casa e pinte-a. Crie três portas e coloque-as na casa; abra e feche as mesmas como desejar. Utilize o método verificarportasestaoabertas() para imprimir o número de portas abertas. 2. Um método pode chamar ele mesmo. Chamamos isso de recursão. Você pode resolver a série de fibonacci usando um método que chama ele mesmo. O objetivo é você criar uma classe, que possa ser usada da seguinte maneira: Fibonacci fibo = new Fibonacci(); int i = fibo.calcularfibonacci(5); System.out.println(i); Aqui imprimirá 8, já que este é o sexto número da série. Este método calcularfibonacci() não pode ter nenhum laço, só pode chamar ele mesmo como método. Pense nele como uma função, que usa a própria função para calcular o resultado. a) Por que o modo acima é extremamente mais lento para calcular a série do que o modo iterativo (que se usa um laço)? b) Escreva o método recursivo novamente, usando apenas uma linha. Para isso, pesquise sobre o operador condicional ternário. 3. O modelo de funcionários a seguir será utilizado para os exercícios de alguns dos capítulos posteriores. O objetivo aqui é criar um sistema para gerenciar os funcionários do Banco. a) Modele um funcionário. Ele deve ter o nome do funcionário, o departamento onde trabalha, seu salário (double), a data de entrada no banco (String), seu RG (String) e um valor booleano que indique se o funcionário está na empresa no momento ou se já foi embora. Você deve criar alguns métodos de acordo com sua necessidade. Além deles, crie um método bonificar() que aumenta o salário do funcionário de acordo com o parâmetro passado como argumento. Crie, também, um método demitir(), que não recebe parâmetro algum, só modifica o valor booleano indicando que o funcionário não trabalha mais aqui. A idéia aqui é apenas modelar, isto é, só identifique que informações são importantes e o que um funcionário faz. Desenhe no papel tudo o que um Funcionario tem e tudo que ele faz. b) Transforme o modelo acima em uma classe Java. Teste-a, usando uma outra classe que tenha o main(). Você deve criar a classe do funcionário chamada Funcionario, e a classe de teste você pode nomear como quiser. A de teste deve possuir o método main().

Conteúdo: Programação Orientada a Objetos Linguagem JAVA Página: 91 Incremente essa classe. Faça outros testes, imprima outros atributos e invoque os métodos que você criou a mais. Lembre-se de seguir a convenção Java, isso é importantíssimo. Isto é, nomedeatributo, nomedemetodo, nomedevariavel, NomeDeClasse, etc... c) Crie um método mostrar(), que não recebe nem devolve parâmetro algum e simplesmente imprime todos os atributos do nosso funcionário. Dessa maneira, você não precisa ficar copiando e colando um monte de System.out.println() para cada mudança e teste que fizer com cada um de seus funcionários, você simplesmente vai fazer: Funcionario f1 = new Funcionario(); //brincadeiras com f1... f1.mostrar(); d) Construa dois funcionários com o new e compare-os com o ==. E se eles tiverem os mesmos atributos? e) Crie duas referências para o mesmo funcionário, compare-os com o ==. Tire suas conclusões. f) Em vez de utilizar uma String para representar a data, crie uma outra classe, chamada Data. Ela possui 3 campos int, para dia, mês e ano. Faça com que seu funcionário passe a usá-la. (é parecido com o último exemplo, em que a Conta passou a ter referência para um Cliente). Modifique sua classe TestaFuncionario para que você crie uma Data e atribua ela ao Funcionário. Modifique seu método mostrar() para que ele imprima o valor de datadeentrada daquele Funcionário. Agora, o que acontece se chamarmos o método mostrar() antes de atribuirmos uma data para este Funcionario? g) Garanta que qualquer atributo que precisar ser manipulado em suas classes estará sendo feito através dos métodos get() / set() quando não forem atributos da própria classe, mas uma variável.