Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas UNIDADE CURRICULAR DE PROGRAMAÇÃO ORIENTADA A OBJETOS Material desenvolvido para a unidade curricular de Programação Orientada a Objetos no curso superior de Análise e Desenvolvimento de Sistemas. Pág|1 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. DOCENTE: ANDRÉ LUIZ SILVA DE MORAES Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas SUMÁRIO 1 APRESENTAÇÃO DA UNIDADE CURRICULAR ____________________________________________4 2 UMA ABORDAGEM INICIAL _________________________________________________________4 4 ALGUNS DETALHES SOBRE A ABORDAGEM JAVA __________________________________________ 6 2.3 Continuando a abordagem a alguns códigos escritos em Java _______________________________11 Uma introdução na orientação a objetos _____________________________________________13 3.1 Criando Novas classes _______________________________________________________________13 3.2 Entendendo um pouco sobre as classes _________________________________________________13 3.3 Qual a diferença entre Classe e Objeto? ________________________________________________14 VARIÁVEIS JAVA _________________________________________________________________18 4.1 Tipos Primitivos ____________________________________________________________________18 4.2 Palavras Reservadas ________________________________________________________________19 4.3 Detalhes sobre os objetos ____________________________________________________________19 4.4 Comportamento de Objetos __________________________________________________________22 5 Exercícios sobre métodos e classes. _________________________________________________23 6 Comportamento dos Objetos_______________________________________________________26 7 8 6.1 Parâmetros e Argumentos ___________________________________________________________26 6.2 PASSANDO MAIS VARIÁVEIS PARA Métodos E retornando valores ___________________________28 6.3 UTILIZANDO MELHOR OS PARÂMETROS E TIPOS DE RETORNO ______________________________29 6.4 ENCAPSULAMENTO COM OS MODIFICADORES PUBLIC E PRIVATE____________________________31 CONSTRUTORES _________________________________________________________________35 7.1 INICIALIZAÇÃO DE VARIÁVEIS DE INSTÂNCIA OU CAMPOS __________________________________35 7.2 DETALHANDO OS CONSTRUTORES _____________________________________________________35 7.3 EXEMPLO 1 – Criando um construtor para a classe pessoa __________________________________35 7.4 EXEMPLO 2 - Criando mais construtores ________________________________________________36 7.5 Exemplo 3 – Criando um controle Bancário com construtores _______________________________37 7.6 DETALHANDO O PROCESSO DE PROJETO E IMPLEMENTAÇÃO DE UMA CLASSE _________________39 EXERCÍCIOS _____________________________________________________________________41 8.1 9 Implemente as modificações nas classes abaixo: _________________________________________41 Revisão de conteúdos para Atividade 1 ______________________________________________43 9.1 Elabore as classes abaixo e Detecte os seus erros: ________________________________________43 10 CORREÇÃO DE QUESTÕES DE AVALIAÇÃO 1 ___________________________________________51 11 RESPONDA AS QUESTÕES ABAIXO: __________________________________________________51 12 COMPLETE AS FRASES ABAIXO: _____________________________________________________51 Pág|2 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 3 2.2 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 13 DESENVOLVA Os APLICATIVOS SOLICITADOS __________________________________________52 14 Construindo um jogo e testando novos comandos ______________________________________58 14.1 CRIANDO O SIMPLEDOTCOM – O BATALHA NAVAL VERSÃO SIMPLES _________________________59 14.2 CRIANDO O BATALHA NAVAL VERSÃO FULL _____________________________________________61 14.3 ANALISANDO O CÓDIGO DO JOGO DE BATALHA NAVAL ____________________________________64 14.4 SIMPLEDOTCOM ___________________________________________________________________64 14.5 GAMEHELPER ______________________________________________________________________64 14.6 LAUNCHGAME _____________________________________________________________________65 15.1 Estendendo a classe de Animais _______________________________________________________66 15.2 POLIMORFISMO ____________________________________________________________________68 15.3 PROJETANDO UMA APLICAÇÃO COM USO DE HERANÇA ___________________________________68 15.4 Herança – O TESTE É-UM e TEM-UM ___________________________________________________71 15.5 A Referência This ___________________________________________________________________73 15.6 A PALAVRA-CHAVE SUPER ___________________________________________________________74 15.7 PROJETOS COM O USO DE HERANÇA SÃO OBRIGATÓRIOS? _________________________________76 15.8 EXERCÍCIOS: _______________________________________________________________________76 16 CLASSES ABSTRATAS _____________________________________________________________77 16.2 ACESSO PROTEGIDO ________________________________________________________________81 16.3 RELEMBRANDO CONCEITOS:__________________________________________________________82 17 A SUPERCLASSE OBJECT ___________________________________________________________87 18 INTERFACES ____________________________________________________________________91 19 Exercícios DE INTERFACES _________________________________________________________94 20 Manipulando Exceções ___________________________________________________________96 20.1 Utilizando o try/catCh _______________________________________________________________96 21 Utilizando a Parte Gráfica no Java _________________________________________________102 22 Utilizando a API do JavaDoc ______________________________________________________111 Pág|3 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 15 HERANÇA ______________________________________________________________________66 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes 1 AULA 01 APRESENTAÇÃO DA UNIDADE CURRICULAR A unidade curricular de Programação Orientada a Objetos tem por objetivo promover o estudo dos principais conceitos do Paradigma Orientado a Objetos, através da utilização de uma linguagem de programação como estudo de caso. A programação orientada a Objetos será estudada juntamente com linguagens que adotam seu uso e constante modificação, juntando toda a teoria de orientação a objetos juntamente com a prática das linguagens estudadas. 2 UMA ABORDAGEM INICIAL Como funciona de fato a linguagem Java? O que é que acontece quando precisamos programar para utilizar esta linguagem? Onde: Código-fonte: é o próprio código do programa que está-se desenvolvendo. Neste caso é necessário utilizar alguma linguagem de programação, que estabeleceremos inicialmente a linguagem Java. Compilador: Precisamos executar o código-fonte anteriormente desenvolvido para ser examinado pelo compilador, o qual procurará por erros. Caso existam erros, o mesmo não nos deixará avançar enquanto existirem problemas no código. Saída: Após a compilação será gerado um novo documento com nosso código, o qual chamamos de bytecode. Os bytecodes podem ser executados por qualquer equipamento que estiver preparado para executar a linguagem Java A seguir executaremos nosso primeiro exemplo de código feito em Java para podermos nos familiarizar com a linguagem: 2.1.1 EXEMPLO 1: O FAMOSO ALÔ MUNDO Inicialmente escreveremos nosso código no editor textpad para posterior compilação e execução Java. Pág|4 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Se fosse necessário descrever um processo inicial para poder entender como funcionam as tarefas que necessitamos realizar para programar em Java, poderíamos descrever os seguintes passos: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Após a digitação salve o arquivo com o nome PrimeiroCodigo.java (obedecendo as letras maiúsculas que estão no nome indicado). Em seguida passamos ao processo de compilação da linguagem desenvolvida, para isso vá até Ferramentas/Compilar Java: E veremos a execução do código feito anteriormente: A tela anterior demonstra que o código digitado está sendo executado, pois o mesmo consiste em apenas imprimir na tela as mensagens de “Estamos testando” e “Olá Mundo”. 2.1.2 EXEMPLO 2: OUTRO TESTE QUALQUER. Elaboraremos outro teste, porém agora envolvendo atribuições e a chamada de uma função interna para associação com a variável d. Salve com o nome SegundoCodigo.java, compile e em seguida execute o aplicativo para ver o resultado, demonstrado a seguir: Pág|5 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. O textpad retornará uma mensagem de compilação executada com êxito e então passaremos a execução de nosso código via textpad: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 2.2 ALGUNS DETALHES SOBRE A ABORDAGEM JAVA Alguns detalhes serão importantes para o entendimento da linguagem Java e o formato de trabalho em seu ambiente, para tanto serão demonstrados alguns questionamentos. 2.2.1 O QUE EXISTE NO CHAMADO ARQUIVO-FONTE? Um arquivo de código-fonte Java contém uma definição de classe. A classe representa uma parte de um programa, embora um aplicativo pequeno possa precisar apenas de uma classe, o que não é muito comum. Mas a classe deve ficar dentro de um par de chaves. O QUE EXISTE EM UMA CLASSE? Uma classe tem um ou mais métodos. Os métodos representam as ações que serão executadas. Um pequeno exemplo poderia ser representada pela classe humano. Os métodos do humano tudo o que ele pode fazer. Os métodos serão sempre declarados dentro de uma classe, ou seja, dentro das chaves existentes na classe. 2.2.3 O QUE EXISTE DENTRO DE UM MÉTODO? Nas chaves de um método serão escritas as instruções de como ele será executado. O código do método é basicamente um conjunto de instruções. E inicialmente, poderíamos comparar o método como se fosse uma função ou um procedimento. No caso da classe humano, os seus métodos poderiam ser seriam falar, caminhar, pegarAlgo, etc 2.2.4 COMO SÃO EXECUTADOS OS PROCEDIMENTOS QUANDO A CLASSE É EXECUTADA? Quando a Jvm começar a ser executada procurará a classe fornecida na linha de comando e em seguida o método escrito na forma: Depois a JVM executará tudo o que estiver entre as chaves { } de seu método principal. Todo o aplicativo escrito em Java precisa ter pelo menos uma classe e um método main(não um método main em cada classe que você criar, apenas por aplicativo desenvolvido). No código fornecido anteriormente no exemplo 1, tínhamos o código completo: Pág|6 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 2.2.2 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas E os detalhes do método principal são: : esta classe é publica para que todas as outras possam acessá-la. : este é o nome da classe que está sendo criada (deve ser o mesmo nome do arquivo .Java que será salvo). : chave de abertura da classe, onde abrangerá todo o restante do código. O código seguinte tem a linha onde: : novamente, o público é para que os elementos externos possam acessá-lo. A diferença é que agora estamos lidando com um método. : este item será abordado posteriormente, apenas precisamos entender que sempre irá compor a linha. sugere o tipo de retorno, void significa que não teremos um valor de retorno. : significa o nome deste método. : serão os argumentos do método em questão, este método deverá receber uma matriz de strings e a matriz se chamará args : chave de abertura do método. E o código que está dentro do método criado: são de linha mesmo. : aqui fizemos apenas uma linha de comentários. Note que estes comentários : significa uma instrução para exibir na saída padrão do sistema, normalmente utilizada para exibir qualquer item que precise ser exibido ao usuário. : a string que queremos exibir para o usuário. : esta é a chave de fechamento do método main; : esta é a chave de fechamento da classe PrimeiroCodigo. OBSERVAÇÕES: Em Java, tudo é inserido em uma classe, sempre precisaremos do arquivo de código-fonte (com a extensão .java); em seguida, o compilador o converterá em um novo arquivo de classe (com extensão .class); quando executarmos o programa, na verdade estaremos executando uma classe. Executar a classe significa informar à Java Virtual Machine (JVM) para carregar a classe criada e, em seguida executar o método main(); Toda a aplicação desenvolvida em Java, independente do tamanho, dependerá de algum método main() para dar início ao processo; Pág|7 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. : Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 2.2.5 EXEMPLO 3: EXECUTANDO PEQUENAS ITERAÇÕES Um outro exemplo agora utilizando laços de repetição para compilar e executar no Java. Salve o seu arquivo Java como TerceiroCodigo.java OBSERVAÇÕES: Porque inserir todo o código em uma classe? Por ser uma linguagem orientada a objetos estamos condicionados a este propósito. Diferente de linguagens mais antigas onde utiliza-se um código-fonte com uma pilha de procedimentos. É necessário sempre um método main em todas as classes? Não, um programa Java poderá usar várias classes, mas precisaremos apenas de um único método main responsável por fazer o programa começar a ser executado. Pág|8 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Visualizando o resultado na execução do programa: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 2.2.6 EXEMPLO 4: O CÓDIGO DE FIBONACCI: UMA RECURSÃO SIMPLES Aqui utilizaremos um código bastante conhecido na área de programação, a recursão de fibonacci, exemplificada a seguir: OBSERVAÇÕES: • O código de Fibonacci consiste em uma sequência iniciando com os termos 1 e 1 e cada termo seguinte sendo a soma dos dois termos anteriores. • Um programa para imprimir Fibonacci é simples e ele demonstra como declarar variáveis, escrever um laço simples e executar aritmética básica. • O exemplo declara uma classe Fibonacci que, como nos exemplos anteriores, possui um método main. As primeiras duas linhas de main são comandos que declaram duas variáveis locais lo e hi. • Neste programa, hi é o termo atual e lo é o termo anterior, variáveis locais são declaradas dentro de um bloco de código. 2.2.7 EXEMPLO 5: FIBONACCI COM USO DE CONSTANTES Constantes, ou literais como são conhecidos, consistem em uma maneira de especificar valores que não são calculados e recalculados, mas permanecem como constantes durante a vida de um programa. Pág|9 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve o arquivo como Fibonacci.java Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Salve o arquivo como Fibonacci2.java • O código Fibonacci anterior imprimia todos os números com valor inferior a 50. A constante 50 foi utilizada na expressão do laço while; • De certa forma, fica um pouco difícil se quiséssemos alterar o valor da lista de fibonacci para os números com valor inferior a 100, pois seria necessário percorrer todas as ocorrências de 50 e deixando o código sujeito a erros; • Uma constante denominada é um valor constante que é referido pelo seu nome melhorando a legibilidade; 2.2.8 EXEMPLO 6: IMPRIMINDO OS NÚMEROS DE FIBONACCI MARCANDO OS NÚMEROS PARES Tente desenvolver agora a sequência de Fibonacci marcando sempre os números da sequência que forem pares. DICA: Em Java usa-se o % para equivaler ao comando Mod utilizado em Pascal. P á g | 10 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. OBSERVAÇÕES: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes 2.3 AULA 02 CONTINUANDO A ABORDAGEM A ALGUNS CÓDIGOS ESCRITOS EM JAVA Faremos mais alguns programas apenas para nos certificarmos do comportamento da linguagem e dos recursos de compilação e execução da linguagem Java. EXEMPLO 1 – AS GARRAFAS DE CERVEJA SOBRE A MESA Salve o arquivo com o nome Cerveja.java OBSERVAÇÕES: • Neste exemplo montamos um contador de garrafas que decresce até finalizar a contagem, o código é implementado em um loop while inicial e através de testes decide a impressão das mensagens com o contador de garrafas; • Note que o contador no loop verifica a quantidade de cervejas para poder decidir sobre o que irá escrever na variável palavra; • As cervejas estão armazenadas na variável num_Cerveja e são decrescidas até chegarem a 1, onde será impressa a útima frase e finalizando o aplicativo; P á g | 11 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 2.3.1 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 2.3.2 EXEMPLO 2 – GERADOR DE PALAVRAS AUTOMÁTICO Neste exemplo desenvolveremos um gerador automático de frases, ainda nos exemplos para a interação da linguagem, utilizaremos um jogo de variáveis com uso de matrizes de strings. OBSERVAÇÕES: Etapas do programa: 1. A primeira etapa é criar uma matriz de strings, que serão os contêineres que armazenarão todas as palavras. Neste caso foram usadas as variáveis listaPalavras1, listaPalavras2 e listaPalavras3. Todas as palavras estão entre aspas e foram separadas por vírgulas; 2. Em cada uma das três listas, o objetivo é selecionar uma palavra aleatória, portanto, temos que saber quantas palavras existem em cada lista. Se houver 14 palavras na lista, precisaremos de um número aleatório entre 0 e 13. O detalhe interessante de matrizes é o código: a. Na sua declaração: i. String[ ] testando = {“andre”, “ana”, “laura”}; b. Obtendo a quantidade de elementos da matriz: i. int x = testando.length; 3. Precisaremos de 3 números aleatório. O Java vem empacotado, independente, predefinido e habilitado em sua memória central com um conjunto de métodos de cálculo (por enquanto as consideraremos como funções). 4. O método random(), utilizado anteriormente, retorna um número aleatório entre 0 e 1, e foi usado para multiplicar pela quantidade de elementos (considerando o tamanho da matriz) da nossa listagem de elementos. Para conseguir fazer uma saída com um número inteiro aleatório, tivemos de forçar que o resultado fosse um inteiro com a conversão (int) que foi utilizada no código. 5. E por último realizamos a construção da frase, selecionando uma palavra em cada uma das três listas e unindo-as (inserindo espaços em branco entre elas). Note que para conseguirmos realizar a seleção de uma palavra foi utilizada as variáveis [rand1], [rand2] e [rand3] para isso. P á g | 12 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Seja o código a seguir: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 3 UMA INTRODUÇÃO NA ORIENTAÇÃO A OBJETOS Faremos uma pequena explanação sobre classes e objetos, porém é interessante inicialmente criarmos uma a partir de um exemplo para podermos visualizar melhor o que está acontecendo em nosso código e em seguida tirarmos nossas próprias conclusões. 3.1 CRIANDO NOVAS CLASSES Agora veremos como são os procedimentos para a criação de classes e também os nossos objetos a serem utilizados nos projetos Java. Iniciaremos criando um pequeno exemplo muito simples para testarmos uma comunicação entre métodos e objetos. 3.1.1 EXEMPLO 3 – CRIANDO A PRIMEIRA CLASSE Salve como Cachorro.java Em seguida, criaremos outra classe com o nome TestaCachorro Salve como TestaCachorro.java OBSERVAÇÕES: • Logicamente se pode perceber que realizamos a criação de duas classes, e podemos notar que existe uma relação entre as duas de alguma forma; • A classe cachorro possui apenas declarações de variáveis e um método com um retorno de impressão de tela com o latido do cachorro; • A classe TestaCachorro é a classe onde tudo acontece de fato, note que nesta classe existe o método main (que sempre existirá na classe principal do software). Esta classe utiliza uma operação com uso do operador 3.2 . (ponto). Este operador lhe dará acesso ao estado e comportamento de um objeto. ENTENDENDO UM POUCO SOBRE AS CLASSES Por enquanto, a abordagem principal sobre o assunto de classes pode ser entendida da seguinte maneira: Quando projetarmos uma classe precisamos pensar nos objetos que serão criados com a classe, e precisamos considerar: P á g | 13 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Criaremos uma classe inicial com o nome Cachorro: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas • As coisas que o objeto conhece; • As coisas que o objeto faz; Exemplos: Pessoa Nome Tamanho Sexo setNome( ) getNome( ) dormir( ) Conhece Faz As coisas que um objeto conhece sobre ele são chamadas de variáveis de instância. Elas representam o estado de um objeto (os dados) e podem ter valores exclusivos para cada objeto desse tipo. É comum um objeto ter métodos que leiam ou gravem os valores das variáveis de instância. Por exemplo, um objeto despertador tem uma variável de instância que armazena a hora de despertar e dois métodos que poderiam capturar e configurar esta hora. Despertador Hora setHora( ) getHora( ) despertar( ) 3.3 QUAL A DIFERENÇA ENTRE CLASSE E OBJETO? Uma classe não é um objeto, mas é usada para construí-los. A classe pode ser entendida como um projeto de um objeto. Ela informa à máquina virtual como criar um objeto desse tipo específico. Cada objeto criado a partir dessa classe terá seus próprios valores para as variáveis de instância da classe. Por exemplo, podemos usar a classe Botão para criar vários botões diferentes, e cada botão poderá ter sua própria cor, tamanho, forma, rótulo e assim por diante. 3.3.1 EXEMPLO 4 – CRIANDO A CLASSE FILME Neste exemplo criaremos a classe filme, que armazenará algumas informações sobre filmes e a classe testadora para podermos visualizar as informações sendo atualizadas nas variáveis de objeto. Salve o arquivo como Filme.java P á g | 14 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Podemos considerar a instância como outra maneira de dizer objeto. E as coisas que um objeto faz são chamadas de métodos. Assim, quando projetarmos uma classe, precisaremos pensar nos dados que um objeto terá de conhecer sobre si mesmo e também projetar os métodos que operarão sobre esses dados. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas E agora a classe testadora: OBSERVAÇÕES: A classe filmeTestDrive cria objetos (instâncias) da classe Filme e usa o operador ponto ( ) para configurar as variáveis de instância com um valor específico. • A classe filmeTestDrive também referencia (chama) um método em um dos objetos. 3.3.2 EXEMPLO 5 – CRIANDO UM PEQUENO JOGO EM JAVA Criaremos um jogo de adivinhação, envolvendo um objeto “jogo” e três objetos “jogadores”. O jogo gera um número aleatório entre 0 e 9 e os três objetos jogadores tentam adivinhá-lo. Classe Jogador.java P á g | 15 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. . • Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Classe JogoAdivinha,Java Classe principal do aplicativo: LancaJogo.java P á g | 16 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas OBSERVAÇÕES: • Podemos notar que é na classe LancaJogo que o jogo é realmente inicializado, pois é a classe que contém o método Java principal main( ); • No método main( ), um objeto GuessGame é criado e seu método startGame( ) é chamado; • É no método StartGame do objeto AdivinhaJoo que o jogo inteiro se desenrola. Ele cria 3 jogadores e, em seguida, “pensa” em um número aleatório (o que os jogadores devem adivinhar). Depois ele solicita a cada jogador que adivinhe, verifica o resultado e exibe informações sobre o(s) jogador(es) vencedor(es) ou pede que adivinhem novamente. Em outras palavras: LancaJogo main(String[ ] args ) Cria um objeto AdivinhaJogo e solicita que inicie o jogo. AdivinhaJogo p1 p2 p3 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Variáveis de instância dos 3 jogadores startGame( ) Jogador numero Palpite do jogador para o número adivinhação( ) Método para dar um palpite P á g | 17 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes 4 AULA 03 VARIÁVEIS JAVA As variáveis Java são interessantes, pois podem adotar mais de uma forma de visão. Até agora utilizamos variáveis em duas situações: • Como variáveis de instância (representando o estado do objeto) • Como variáveis locais (dentro do método) Variáveis ainda podem ser detalhadas de outras maneiras, como exemplo os seus tipos, e também com relação a declaração de variáveis como objetos. Já foi possível perceber que o Java considera o tipo como sendo bastante importante na declaração de variáveis. Neste sentido, podemos então imaginar que algumas coisas não serão permitidas como a inclusão de valores de ponto flutuante em tipos inteiros ou até mesmo tipos de dados que são objetos com métodos de outro objeto diferente. 4.1 TIPOS PRIMITIVOS Vejamos a seguir os tipos de variáveis primitivas e suas configurações aceitas pelo Java: Tipo Quantidade de Bits Intervalo de Valores Booleano (específica da JVM) Verdadeiro ou falso Char 16 bits 0 a 65535 byte 8 bits -128 a 127 curto 16 bits -32768 a 32767 Int 8 bits -2147483648 a 2147483647 long 64 bits Números enormes float 32 bits Variável double 64 bits Variável Booleano e Char Inteiros Ponto Flutuante P á g | 18 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Como sabemos, as variáveis se diferem em tipos e também tamanhos diferentes. Existem variáveis chamadas de primitivas por representarem informações comuns às linguagens de alto nível que são utilizadas pela maioria dos programadores. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas EXEMPLOS DE ATRIBUIÇÕES: Sabemos então agora as capacidades das variáveis e como poderemos utilizá-las. A tarefa agora é conseguir sempre utilizar o tipo certo de variável para o tamanho de dados adequado a ser armazenado. 4.2 PALAVRAS RESERVADAS • Devem começar com uma letra, um sublinhado ( _ ), ou cifrão ($); • Não devem começar com números; • Após o primeiro caractere é possível a utilização de números; • O nome pode ser qualquer um, desde que obedeça as regras e não utilize as palavra reservadas do Java; As palavras reservadas são palavras-chave que o compilador reconhece e as usa para determinadas tarefas internas, como a declaração de classes, funções internas e até mesmo tipos de variáveis. Vejamos os nomes reservados do Java que não podem ser utilizados: boolean byte char double float int long short public private protected abstract final native static stricfp synchronized transient volatile If else do while switch case default for break continue assert class extends implements import instanceof interface new package super this catch finally try throw throws returns void const goto enum 4.3 DETALHES SOBRE OS OBJETOS Sabemos como declarar uma variável primitiva e atribuir valores a ela. Mas a situação muda quando falamos em objetos: • Na verdade não existem variáveis de OBJETO; • O que existem são variáveis de referência de objetos; • Estas variáveis não contém o objeto propriamente dito, mas podem ser considerados como ponteiros, ou endereços. Não é necessário saber exatamente o que existe dento de uma variável de referência, mas precisamos saber que cada vez que criamos um novo objeto existe uma variável apontando para cada um dos objetos criados. A máquina virtual Java sabe como utilizar estas referências para acessar a estes objetos. • Enquanto as variáveis primitivas ficam cheias de bits que representam o valor real da variável, uma variável de referência de objeto fica cheia de bits que representam uma maneira de chegar ao objeto. o Exemplos: Int x = 10 (atribuição de variável primitiva) P á g | 19 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Aqui detalhamos apenas as palavras que não podem ser utilizadas como nomes de suas variáveis, métodos ou classes em programas feitos através da linguagem Java e também as regras para nomeá-las de forma correta: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Cachorro = new Cachorro(); (atribuição de variável de referência) AS 3 ETAPAS DA DECLARAÇÃO, CRIAÇÃO E ATRIBUIÇÃO DE OBJETOS: Seja o exemplo da classe Cachorro que criamos em outra aula: 1) Declarar uma variável de referência i. Solicita a JVM para alocar espaço para uma variável de referência e nomeia essa variável como x. Esta variável será sempre do tipo Cachorro. 2) Criar um objeto a. new Cachorro(); i. Solicita à JVM para alocar espaço para um novo objeto do tipo Cachorro no acervo (detalhado mais tarde) do objeto Cachorro. 3) Vincular objeto e a referência a. Cachorro x = new Cachorro(); i. Atribui o novo objeto Cachorro à variável de referência x. O Operador new força a criação de um objeto quando o utilizamos, neste caso do exemplo criamos um novo objeto do tipo Cachorro. O processo de construção de um novo objeto é chamado de construção. Classes diferentes exigirão parâmetros de construção diferentes. Por exemplo, para construir um objeto do tipo Retângulo, precisamos fornecer quatro números que descrevem a posição e o tamanho do retângulo. E para construir um objeto Carro, provavelmente precisaremos fornecer o modelo e o ano. Algumas classes deixam criar seus objetos de várias maneiras, como exemplo podemos também criar um objeto Retângulo sem fornecer parâmetros de construção (ainda assim fornecendo os parênteses): new Retângulo(); P á g | 20 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. a. Cachorro x Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 4.3.1 MATRIZES Também são consideradas como objetos. Normalmente as matrizes são interessantes para armazenar uma lista de itens para acessá-los posteriormente de forma rápida, ordenada e eficiente. São acessadas através de um índice de posição que permite acessar qualquer elemento existente nelas. Todo o elemento de uma matriz é apenas uma variável, ou seja, pode ser um dos oito tipos primitivos de variáveis. Qualquer coisa que inserirmos em uma variável desse tipo poderá ser atribuído a um elemento de matriz do mesmo tipo. Exemplo 1 - Criando uma matriz Cachorro com uso de controle de Objetos: Criaremos duas classes a exemplo da criada anteriormente com o mesmo propósito de exibir as ações de um cão. Porém neste caso faremos o mesmo através de matrizes. Salve o arquivo como testaCachorro2.java OBSERVAÇÕES: • Note que agora utilizamos uma matriz para armazenar e trabalhar as informações. Mas desta vez utilizamos a criação de novos objetos com o operador new porém também utilizamos a matriz para armazenar os novos objetos meusCaes que eram criados. P á g | 21 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve o arquivo como Cachorro.java Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas • Note que no início do programa, utilizamos a seguinte notação: o Isto significa que estamos declarando uma variável matriz do tipo Cachorro[ ] (onde os colchetes explicitam isto) Em seguida, criamos um objeto Cachorro instanciado com tamanho total de 3 elementos Depois, usando a notação de matriz, basta realizar as atribuições de valores utilizando sempre a notação de matriz[ ] para acessar cada elemento dela; As matrizes são sempre objetos, não importando se foram declaradas para conter tipos primitivos ou referências de objeto. Mas podemos ter um objeto de matriz que tenha sido declarado para conter vários valores primitivos. Em outras palavras, o objeto de matriz pode ter elementos que sejam primitivos, mas a matriz propriamente dita nunca é de um tipo primitivo. Independentemente do que a matriz armazenar, ela sempre será um objeto. 4.4 COMPORTAMENTO DE OBJETOS Seja a classe cão e suas configurações, podemos fazer com que dependendo do tamanho do cão o seu latido possa ser alterado. Isto será totalmente dependente de qual instância de objeto desejar chamar o método latir: Exemplo 2 – Criando a classe Cachorro com comportamentos diferentes: Salve o arquivo como Cachorro3.java Salve o arquivo como TestaCachorro3.java P á g | 22 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Lembrando, uma classe é um projeto de um objeto. Ao criarmos uma classe, estamos descrevendo como a JVM deve criar um objeto deste tipo, mas os métodos podem sim influenciar no comportamento dos objetos. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 5 EXERCÍCIOS SOBRE MÉTODOS E CLASSES. 1) Descubra o que está faltando nas classes abaixo e corrija-as: A. Classes para um toca-fitas, com os métodos de grava e de play. a. Salve como TocaFitas.java i. Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. b. Salve como TestaFita.java i. B. Classe DVD, com um método grava. a. Salve como DVDPlayer.java i. b. Salve como DVDPlayerTeste.java i. P á g | 23 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas C. Uma classe livros, com apenas duas variáveis de referência e a classe para teste e uso de matrizes de livros: a. Salve como Livros.java i. i. D. Uma classe coelho com apenas uma variável de instância nome e uma classe testadora e com alocação de dados em matrizes; a. Salve como Coelhos.java i. P á g | 24 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. b. Salve como LivrosTestDrive.java Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas b. Salve como TestaCoelhos.java 2) Crie as seguintes classes de acordo com as instruções: A. Escreva uma classe Veiculo que possua, no mínimo, as variáveis de referência para armazenar as informações sobre velocidade atual, direção atual em graus e nome do proprietário. Escreva também os métodos para: a. Retornar a velocidade atual do veículo; b. Retornar a direção atual do veículo; c. Retornar o nome do proprietário do veículo; Veiculo velocidade direcao nome Variáveis de instância do veículo. getVelocidade( ) getDirecao( ) Getnome( ) P á g | 25 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. i. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes 6 AULA 04 COMPORTAMENTO DOS OBJETOS Sabe-se que os objetos possuem um estado e comportamento, representados pelas variáveis de instância e também os métodos. Mas ainda estão faltando alguns detalhes de como é estado e o comportamento estão relacionados. Vimos em exemplos anteriores que as instâncias podem ter seus próprios valores exclusivos para as variáveis de instância. Vimos em exemplos anteriores um comportamento da classe cachorro onde cães de nomes diferentes que tinham um método latido() , e o som do latido a ser emitido pode ser diferente de acordo com a altura ou idade do cachorro que está latindo. Em outras palavras, vimos que os métodos usam os valores das variáveis de instância para poderem ser executados. O fato é que podemos enviar valores para um método, no caso do Cachorro, poderíamos enviar como parâmetro latido(4) e o mesmo seria executado 4 vezes. Porém sabemos que o método não exige que seja enviado argumento algum. 6.1 PARÂMETROS E ARGUMENTOS Dependendo da formalidade de alguns livros e/ou cursos relacionados a Ciência da Computação, é comum o uso do termo argumentos ou parâmetros para valores que são passados para um método. Embora sejam distinções formais na informática, precisaremos convencionar estes termos: Um método usa parâmetros, um chamador usa argumentos. Ou seja, argumentos serão os valores que serão passados aos métodos, podendo ser um valor como 2, ou uma string A, B, C; ou até mesmo uma referência que aponte para um objeto. Estes argumentos serão inseridos em um parâmetro, que por sua vez não passa de uma variável local. Uma variável com um tipo e um nome, que poderá ser usada dentro do corpo do método. Poderíamos realizar uma pequena alteração na classe Cachorro3, para que o método latido() possua parâmetros, referentes a quantidade de latidos a serem executados. Vejamos o exemplo: 6.1.1 EXEMPLO 1 – MODIFICANDO A CLASSE CACHORRO3 PARA POSSUIR PARÂMETROS DE LATIDOS Modificaremos as classes Cachorro3 para possuir parâmetros da quantidade de latidos a aceitar e TestaCachorro3 para que possa enviar a quantidade de latidos a ser executada. P á g | 26 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. No exemplo anterior da classe cachorro, utilizávamos o método latido() para fazer com que uma das instâncias criadas (Cachorro x = new Cachorro()) pudessem chamar o método e executar o latido. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Chamaremos a classe agora de Cachorro4.java Visualizando: OBSERVAÇÕES: • Na classe testadora (TestaCachorro4) chamamos o método latido() na variável de referência cao1 e passamos como argumento do método um valor qualquer, neste caso para cada variável de referência cao um valor de latidos; • Os valores informados serão os argumentos que foram passados para o método latido(); • Por sua vez, o método latido(), em sua estrutura, possui parâmetros da quantidade de latidos, que deverão ser sempre inteiros; P á g | 27 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve a classe testadora como TestaCachorro4.java Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 6.2 PASSANDO MAIS VARIÁVEIS PARA MÉTODOS E RETORNANDO VALORES Métodos retornam valores. Todos os métodos são declarados com um tipo de retorno, mas até agora foram criados todos os métodos com um tipo de retorno void, significando que não retornam nada. Aqui, o método está trabalhando com valores inteiros, o que significa que o chamador também deverá ser inteiro e esperar que sejam retornados valores inteiros. Exemplificando: 6.2.1 EXEMPLO 2 – PASSANDO MAIS DE UMA VARIÁVEL PARA UM MÉTODO Criaremos duas novas classes simulando uma conta utilizando algumas variáveis. Estas variáveis trocarão valores por cópia, típico do Java, e veremos como as duas trocam informações em sua execução. Salve esta classe como TestaSomaNumeros.java Resultado: OBSERVAÇÕES: • Desta vez criamos uma classe SomaNumeros.java e declaramos apenas um método onde foram criadas duas variáveis inteiras (x e y) como parâmetros. • Ainda, internamente foi declarada uma variável z recebendo o valor de x e y somados, note que estes valores serão informados pelo chamador que enviará os números a serem utilizados; P á g | 28 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve esta classe com o nome SomaNumeros.java Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas • Ainda, o retorno deste método é apenas uma impressão de tela contendo o valor de z, que é a soma de x e y; • Na classe testadora TestaSomaNumeros.java, foram declaradas duas variáveis inteiras (com nomes diferentes), criamos uma variável de referência t ao objeto SomaNumeros e chamamos o método somatorio; • O método somatorio() exige que sejam informadas as variáveis de argumento que são esperadas como inteiros, elas serão recebidas pelos parâmetros x e y do método, calculadas e retornados com o valor atribuído a z, visível ao usuário; Alguns detalhes a mais: 1. Os métodos podem usar variáveis de instância para que objetos do mesmo tipo possam se comportar diferentemente; 2. Um método pode ter parâmetros, o que significa que podemos passar um ou mais valores para ele; 3. A quantidade e o tipo dos valores que forem passados devem corresponder à ordem e tipo dos parâmetros declarados pelo método; 5. Se um método declarar um tipo de retorno que não seja void, deve retornar um valor compatível com o tipo declarado. 6.3 UTILIZANDO MELHOR OS PARÂMETROS E TIPOS DE RETORNO Agora que sabemos que os parâmetros e tipos de retorno podem ser utilizados, podemos fazer uma outra abordagem sobre o uso deles. Existem métodos comumente utilizados no Java que são denominados como Getter e Setter, podemos visualizá-los como acessadores e modificadores. Em outras palavras, métodos Getter (captura) e Setter (configuração), permitirão que capturemos e configuremos normalmente valores de variáveis de instância dos objetos. A única finalidade de um método de captura é enviar, como valor de retorno, o valor do que quer que esse método de captura específico capture. Um exemplo disto seria: GuitarraEletrica cor numCordas defineUso getCor() setCor() getNumCordas() setNumCordas() getDefineUso() setDefineUso() Aqui estamos seguindo a convenção de nomes do Java. Os gets e sets trabalham as informações da classe e podem “setar” e “recuperar” os valores das variáveis. P á g | 29 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 4. Um método deve declarar um tipo de retorno, um tipo de retorno void significa que o método não retorna nada; Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 6.3.1 EXEMPLO 3 – ELABORANDO UMA PROTEÇÃO AOS SEUS DADOS DE UMA CLASSE Criaremos uma classe GuitarraEletrica, esta será composta pelas variáveis de instância cor, numCordas e defineUso. E desta vez teremos uma série de métodos, utilizados para efetuar o tráfego dos dados das suas variáveis. Salve a classe testadora como TestaGuitarraEletrica.class OBSERVAÇÕES: • Agora o que estamos fazendo chama-se Encapsulamento. Significa que estamos ocultando o acesso direto às informações existentes na classe. • Por exemplo, não mais permitiremos que os dados sejam acessados diretamente com o operador ponto como: P á g | 30 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve esta classe como GuitarraEletrica.class Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas o • dadosPessoa.altura = 0; O que acontece é que estamos construindo métodos de configuração para todas as variáveis de instância e encontrando uma maneira de forçarmos os outros códigos a chamarem estes métodos em vez de acessar os dados diretamente. 6.4 ENCAPSULAMENTO COM OS MODIFICADORES PUBLIC E PRIVATE O que precisamos fazer agora é ocultar e proteger os dados.Fazemos isto com os modificadores de acesso public e private, o public foi utilizado em todos os métodos main até agora e em quase todas as classes que foram desenvolvidas. Para todos os efeitos, podemos proteger as variáveis de instância da classe através do modificador private, e com o modificador public deixarmos acesso somente aos métodos que modificam ou recuperam as informações das variáveis de instância. O encapsulamento permite que possamos definir os limites de valores que são apropriados de serem atribuídos as variáveis de instância. P á g | 31 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Ainda assim, se tentarmos acessar os dados com o operador ponto na classe GuitarraEletrica será possível: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 6.4.1 EXEMPLO 4 – MODIFIQUE A CLASSE GUITARRAELETRICA Agora a classe testadora não mais conseguirá acessar diretamente os valores das variáveis de instância utilizando o operador ponto. Praticamente todas as classes devem proteger as suas informações, sob pena de serem utilizados valores inválidos para elas ou corrermos o risco de serem alteradas com valores fora do normal. Por exemplo, uma conta de banco onde o saldo da conta for zerado, ou aumentado sem a devida situação. P á g | 32 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Se tornarmos as variáveis da classe GuitarraEletrica privadas, veremos que ao tentar compilar a classe testadora teremos o seguinte erro (parte dele): Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 6.4.2 EXEMPLO 5 – ENCAPSULANDO A CLASSE CACHORRO Agora faremos o mesmo com a classe cachorro, encapsularemos suas informações para que possam ser validadas para serem modificadas ou acessadas externamente pelo código de outras classes: Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Esta é a classe Cachorro5.java Esta é a classe testadora TestaCachorro5.java OBSERVAÇÕES: • Qualquer local onde um valor específico puder ser usado, uma chamada de método que retorne esse tipo poderá ser empregada; P á g | 33 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas o Int x = 3 _+ 24; Int x = 3 + um.getSize(); Ainda que métodos não adicionem realmente uma nova funcionalidade, o interessante é que você pode mudar de idéia posteriormente e mudar para tornar o método de privado para público e vice versa. Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. • Ex: P á g | 34 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes 7 AULA 05 CONSTRUTORES Até o momento, definimos classes para projeto de objetos onde existiam apenas as variáveis de instância e os seus métodos para a manipulação de suas informações. Um objeto recém-criado recebe um estado inicial. Campos podem ser inicializados com um valor quando eles são declarados, ou podemos simplesmente aceitar o valor default, como temos feito. As variáveis, quando definidas, possuem valores default quando não atribuímos valor algum em sua definição. 7.1 INICIALIZAÇÃO DE VARIÁVEIS DE INSTÂNCIA OU CAMPOS 7.2 Tipo Valor Inicial boolean false byte, short, int, long 0 float, double +0.0 referência a objeto null DETALHANDO OS CONSTRUTORES Para objetivos além da simples inicialização, classes podem ter construtores. Que consistem em blocos de comandos que podem ser usados para inicializar um objeto antes que a referência ao objeto seja retornada por new. Os construtores devem possuir o mesmo nome da classe que inicializam. Da mesma forma que métodos, podem ter zero ou mais argumentos, mas construtores não são métodos e portanto não possuem nenhum tipo de retorno. Para os argumentos, quando existirem, são fornecidos entre parênteses e seguem o nome do tipo quando o objeto é criado com o operador new. Vejamos um exemplo: 7.3 EXEMPLO 1 – CRIANDO UM CONSTRUTOR PARA A CLASSE PESSOA Salve como Pessoa.class P á g | 35 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Quando uma variável é declarada, ela pode ser inicializada pela atribuição ou receber o seu valor default. Como exemplo de valores default podemos visualizar: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Salve como TestaPessoa.java OBSERVAÇÕES: Neste exemplo fizemos a declaração de nosso primeiro construtor. Note que o construtor deve sempre possuir o mesmo nome da classe que é definida, esta é a regra geral de construtores. Via de regra, se tivermos pelo menos um construtor definido, será obrigatório existirem construtores para tipos de argumentos diferentes. Por exemplo, podemos alterar a classe pessoa e criar outro construtor para que aceite apenas a idade da pessoa. Vejamos o exemplo abaixo: 7.4 EXEMPLO 2 - CRIANDO MAIS CONSTRUTORES Aqui, alteramos um pouco a classe pessoa para que tenha agora outro construtor e o método para alterar o nome da instância que está sendo modificada. P á g | 36 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. No exemplo feito, percebemos que se tentarmos instanciar um novo objeto Pessoa sem declarar um nome quando invocamos o new isto não será permitido. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Sempre que informarmos parâmetros diferentes na criação de instâncias de objeto, será procurado pela máquina virtual algum construtor que possa receber aquele argumento, caso contrário termos receberemos um erro como resultado na criação da instância. Por exemplo, não poderíamos tentar nesta classe algo como: Pois não existe um construtor que possa receber um valor float como argumento, deverá ser criado algum para que isto seja aceito pela classe. De forma geral, o construtor tem a tarefa de impor as regras gerais para, como o nome diz, a construção dos itens dos objetos. Eles ajudam a manter a integridade dos dados que são projetados na classe. 7.5 EXEMPLO 3 – CRIANDO UM CONTROLE BANCÁRIO COM CONSTRUTORES Neste exemplo criaremos uma espécie de sistema de contas bancárias, onde criaremos diversas instâncias de objetos para representar vários clientes que podem alterar ou verificar o saldo de suas contas. O exemplo ilustra de forma prática o que estamos implementando quanto à classes que utilizam construtores e variáveis de instância definidas como privadas e acessadas por métodos. P á g | 37 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Aqui, percebemos que podemos criar uma nova instância do objeto Pessoa informando um novo argumento em sua criação, neste caso a sua idade. Isto é possível devido à situação de que existe um construtor que permite receber um inteiro como argumento. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Salve como ContaBancoTeste.class OBSERVAÇÕES: Observe que a variável de instância é declarada com o especificador de acesso private. Ou seja, o saldo bancário pode ser acessado apenas pelos construtores da mesma classe. A maneira como o estado de uma conta bancária é mantido é um detalhe privado da implementação da classe. Lembre-se de que a prática de ocultar os detalhes da implementação e fornecer métodos para acesso a dados é chamado de encapsulamento. P á g | 38 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve como ContaBanco.class Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 7.6 DETALHANDO O PROCESSO DE PROJETO E IMPLEMENTAÇÃO DE UMA CLASSE É comum a solicitação de projeto e implementação de classes em Java, a este momento, estamos precisando de algum certo detalhamento da construção de uma. Passo 1 – Descobrir o que lhe foi pedido para fazer com um objeto da classe Seja um pedido de implementação da classe Carro. Precisaremos saber quais os detalhes realmente no aspecto de um veículo será necessário simular. O interessante é termos uma lista das operações que um objeto de uma classe deve executar, como exemplo: • Encher o tanque de gasolina; • Dirigir por uma certa distância; • Verificar a quantidade de gasolina restante no tanque; Passo 2 – Encontrar nomes para os métodos Crie nomes de métodos e aplique-os a um objeto, como exemplo: Carro Gol = new Carro; Gol.dirigir(100); Gol.getGasolina; Passo 3 – Determinar as variáveis de instância Devemos pensar quais são as informações que o objeto precisa para armazenar e fazer o seu trabalho. O objeto precisa ter métodos que façam pelo menos as ações básicas do objeto. No caso do carro, os nomes que pensamos já deram este início de exemplo, como encher o tanque, dirigir, ver a quantidade de gasolina, etc. E para isso, devem existir variáveis de instância que permitam que estas informações possam ser validadas e modificadas no processo de execução dos métodos. Passo 4 – Determinar os construtores Podemos pensar no que é necessário para construir um objeto. Com freqüência, podemos simplesmente configurar todos os campos para 0 ou para um valor constante. Às vezes, precisamos de algumas informações essenciais, que devem ser configuradas em um construtor. Em alguns casos são necessários dois construtores, um que configura todos os campos para um padrão e outro que os configura para valores fornecidos pelo usário. No caso do veículo, podemos começar com um tanque vazio, e alimentá-lo ao longo do programa. Passo 5 – Implementar os métodos Neste momento é colocar a mão na massa e implementar todos os métodos e construtores nas classes, um por vez, começando pelos mais fáceis. Normalmente é interessante revisar algo nas propriedades dos construtores e/ou dos métodos que foram projetados. Passo 6 – Testar a classe É sempre interessante escrever um pequeno programa para poder testar as classes que foram elaboradas, o programa só pode execuar as chamadas de método que foram criadas no passo 2. P á g | 39 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Gol.addGasolina(20); Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 7.6.1 EXEMPLO 4 – CRIANDO A CLASSE CARRO Salve como CarroTeste.class OBSERVAÇÕES: Aqui criamos a classe carro, com alguns métodos para modificar o valor da gasolina atual e também retornar o valor atual de gasolina existente no tanque. Temos um método andar, que como deve consumir combustível, fizemos com que ele consuma a quantidade de gasolina existente atualmente no tanque e atualize o esta quantidade em função da quilometragem por litros. Nem todos os métodos foram implementados, poderíamos ter outros ainda, como a atualização do consumo do carro, por exemplo. P á g | 40 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve como Carro.class Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 8 EXERCÍCIOS 8.1 8.1.1 IMPLEMENTE AS MODIFICAÇÕES NAS CLASSES ABAIXO: CRIANDO UM PROJETO ZOO Um biólogo deve observar o comportamento de animais em um zoológico, mais especificamente, lhe foram destinados os seguintes animais para observação: Dois rinocerontes; Um antílope; Três Hipopótamos; Criaremos uma classe diferente para cada espécie de animal que for criado, cada classe poderá conter características e operações distintas. Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve como Rinoceronte.class Salve como Antilope.class Salve como Hipopotamo.class P á g | 41 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas A. Teste a classe para ver se o resultado dos métodos utilizados estão corretos; B. Defina as variáveis de instância nome e peso para cada animal com o atributo de private para todas; C. Implemente os métodos get() e set() para que possamos recuperar e alterar o nome e o peso dos animais; D. Implemente um método para que os animais possam emitir algum som que os identifique; E. Faça com que o método de emitir som, dependendo do peso do animal modifique para pelo menos duas formas de emitir um som, quando chamado. P á g | 42 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve como a classe Coordenador.class Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes 9 AULA 06 REVISÃO DE CONTEÚDOS PARA ATIVIDADE 1 A seguir serão propostos alguns exercícios da unidade curricular envolvendo a elaboração de programas utilizando os conceitos de programação orientada a objetos e também alguns questionamentos teóricos sobre os assuntos abordados nas aulas. 9.1 1 ELABORE AS CLASSES ABAIXO E DETECTE OS SEUS ERROS: Elabore as classes relógio Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve como Clock.java 1.1 Salve como ClockTestDrive.java P á g | 43 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Escreva um programa para criar um objeto da classe Conta para controlar a conta do Sr. Ronaldo, realize um depósito de R$200 atualizando o saldo da conta (método deposita). Logo após escrever o novo saldo da conta (método getSaldo) e o nome do correntista (atributo nome). 2.1 Classe Conta.java 2.2 Classe ContaTeste.java Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 2 P á g | 44 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Utilizando como início a classe Conta, escreva um programa para ler o nome de um correntista e o respectivo saldo inicial da conta. A seguir criar um objeto da classe Conta com o nome do correntista, atualizando o saldo com o valor inicial informado. Depois, executar 5 movimentos de retirada a partir de 5 valores informados. Para cada retirada exibir o saldo atualizado da conta. Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 3 P á g | 45 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Implemente uma classe chamada Estudante. Para o objetivo desde exercício, um aluno tem um nome e uma contagem do total de provas. Forneça um construtor apropriado e os métodos obterNome(), obterProva(int nota), obterNotaTotal() e obterMedia(). Para calcular a última, você também precisa armazenar o número de provas que o aluno fez. Classe Estudante.java Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 4 Classe EstudanteTeste.java P á g | 46 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Implemente a classe Produto. Um produto tem um nome e um preço, por exemplo new Produto (“Torradeira”, 29.95). Forneça métodos obterNome(), obterPreco() e estabelecerPreco(). Escreva um programa que crie dois produtos, imprima o nome e o preço, reduza seus preços em R$10.00 e depois os imprima. Classe Produto.java Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 5 Classe TestaProduto.java P á g | 47 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 6 Acrescente no programa do exercício 2 uma validação para que não seja possível executar uma retirada se não houver saldo disponível na conta. Caso isso ocorra deve ser impressa a mensagem "Saldo insuficiente". Classe Conta.java Aqui foi inserida apenas a alteração solicitada pelo exercício. Implemente uma classe PopulacaoBaratas que simule o crescimento de uma população de baratas. O construtor recebe o tamanho da população inicial de baratas. O método WaitForDouble simula um período durante o qual a população dobra. O método spray pulveriza as baratas com inseticida, o que reduz a população em 10%. O método obterBaratas devolve o número atual de baratas. Implemente a classe e um programa de teste que simule uma cozinha que começa com 10 baratas. Use o inseticida spray, e imprima a contagem de baratas. Repita a operação 3 vezes. Classe PopulacaoBaratas.java Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 7 P á g | 48 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 8 Implemente a classe Funcionario. Um empregado tem um nome (String) e um salário (double). Escreva um construtor default, um construtor com dois parâmetros (nome e salário) e métodos para devolver nome e salário. Escreva um pequeno programa para poder testar a sua classe. Clase Funcionario,java P á g | 49 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Classe PopulacaoBaratasTeste.java Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Classe FuncionarioTeste.java Aprimore a classe do exercício 8 para adicionar um método aumentarSalario (double) que aumente o salário do funcionário em uma porcentagem de 10% . Classe Funcionario (apenas modificação) Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 9 P á g | 50 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes AULA 08 10 CORREÇÃO DE QUESTÕES DE AVALIAÇÃO 1 PARTE I - AVALIAÇÃO TEÓRICA 11 RESPONDA AS QUESTÕES ABAIXO: A) Qual a diferença entre um construtor e um método? Dê um exemplo prático. Construtores definem como serão instanciados os objetos e também como serão inicializados os seus valores, eles são declarados com o mesmo nome da classe e não possuem declaração de tipos e nem void. Métodos são as ações que a classe pode executar, normalmente o padrão é existirem métodos get’s e set’s para cada variável de instância existente na classe. public Cachorro(String n){ nome = n; } O que são os parâmetros de um método? Dê um exemplo. São valores que serão passados pelo chamador quando invocar um método que faça algo. Normalmente o método deve estar preparado para recebê-los. Public void setNome(String n){ nome = n; } C) Defina o que são variáveis de instância. Mostre um exemplo de definição. São as informações que serão armazenadas ou trabalhadas pelos objetos que forem instanciados. Estas variáveis possuirão valores únicos e diferentes para cada objeto que for instanciado. Quando são declaradas com a palavra chave private são acessíveis apenas pelos métodos da própria classe. String nome; int quantidade; 12 COMPLETE AS FRASES ABAIXO: A) O código intermediário que é gerado após a compilação e utilizado pela máquina virtual, que é o responsável pela linguagem Java ser conhecida como multiplataforma é chamado de bytecode. B) Um item muito utilizado na elaboração de uma classe, que obriga a ser obedecido na construção de instâncias de objetos de classe quando é criado é chamado de construtor. Uma técnica utilizada para proteger a manipulação das variáveis de uma classe que normalmente obriga ao programador de criar métodos para gravar e obter dados chama-se de encapsulamento. P á g | 51 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. B) Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas PARTE II - AVALIAÇÃO PRÁTICA 13 DESENVOLVA OS APLICATIVOS SOLICITADOS 1) Crie uma classe Carro que contenha as variáveis de instância nome, marca, ano, consumo, capacidade e litrosTanque; a. Crie uma classe CarroTeste que imprima na tela o nome e a marca do carro informado no seu código de teste; i. b. Configure a variável litrosTanque para uma quantidade de litros e imprima na tela quantos litros o carro atual possui em seu tanque; i. 2) Amplie a classe Carro para que tenha um construtor recebendo o nome do carro e o ano; Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Classe Carro Classe CarroTeste P á g | 52 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 3) Modifique a classe Carro e Crie os seguintes métodos: a) setMarca para modificar a marca do veículo; b) setConsumo para modificar o consumo atual do veículo; c) abastecer, recebendo um valor de litros e adicionando a quantidade de litros a variável litosTanque do carro; d) getLtTanque, retornando o número de litros existentes no tanque do carro; e) getNome, retornando o nome que foi setado ao veículo atual; f) Imprima na tela novamente o nome do veículo juntamente com a sua marca e, logo abaixo o consumo e a quantidade de litros existente no seu tanque (lembrando que o consumo deve ser definido por você, em carros populares o consumo varia entre 12 e 18Km/lt ); ii. Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Classe Carro P á g | 53 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Classe CarroTeste 4) Modifique a classe carro e adicione as seguintes características: a) No método setMarca, crie uma validação para verificar o nome atual do veículo e atribuir automaticamente uma marca o mesmo. Os nomes de veículos a serem aceitos apenas serão Ka, Gol e Uno. Faça uma validação para que o método setMarca altere a marca do veículo utilizando as marcas Ford, Volkswagem e Fiat. 5) Modifique a classe carro e adicione os métodos: a. Um método andar(), que recebe como argumento a quantidade de Kilometros e realiza uma dedução nos litros existentes no tanque do carro utilizando a seguinte fórmula: i. Litros = litros – (kilômetros / consumo por litro) b. Execute o método andar() para rodar 150Km e exiba a quantidade de litros existente antes e após a rodagem do Carro; Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. iii. Classe Carro Classe CarroTeste P á g | 54 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 6) Altere o método abastecer() para as seguintes situações: a) Emitir um aviso ao usuário quando tentar abastecer mais do que a capacidade do veículo = “combustível maior do que a capacidade do tanque” b) Emitir um aviso para quando o combustível exceder a capacidade atual de litros do tanque = “Insira no máximo x litros” c) Caso contrário, o tanque deverá ser abastecido normalmente; 7) Abasteça o tanque 3 vezes com 5Lt, mostrar a quantidade de litros a cada abastecimento; iv. a) Quando for chamado o método, criar uma validação para quando a Kilometragem informada for maior do que a capacidade de litros possível de rodar com o veículo e emitir uma informação ao usuário = “Combustível insuficiente para andar esta kilometragem!” 9) Simule uma viagem com o Carro em duas etapas: c. Mostre a quantidade atual de litros, viaje 300Km e em seguida mostre novamente a quantidade de litros; i. d. Viaje mais 300Km e mostre a quantidade de litros. i. P á g | 55 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 8) Altere o método andar() para a seguinte condição: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Classe Carro (versão final) P á g | 56 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Classe CarrroTeste (versão final) Visualização de saída final: P á g | 57 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 14 CONSTRUINDO UM JOGO E TESTANDO NOVOS COMANDOS Realizando uma nova abordagem a novos comandos, faremos o desenvolvimento de um jogo. O jogo a ser desenvolvido será a “Batalha Naval”, onde é necessário disparar um míssil e afundar alguns navios. Porém, como ainda não criamos interfaces visuais para visualizar o que estamos criando, não teremos nenhum navio. Em vez disso, a tarefa será adivinhar as coordenadas no menor número de tentativas possível. E ao invés de navios, serão afundadas as Dot Coms (empresas na Internet). • Objetivo: afundar todas as Dot Coms (nomenclatura para de empresas do ramo .com ) do computador no menor número de tentativas. Será exibida uma classificação ou nível, baseado em como foi o desempenho. • Preparação: quando jogo for iniciado, o computador inserirá e 3 Dots em uma grade virtual. Em seguida o game solicitará que o usuário insira seus palpites. • Como será a forma de jogar: como ainda não construímos nenhum ambiente visual, a versão do jogo funcionará na linha de comando. O computador solicitará um palpite e quando acertar verá a mensagem de certo ou errado ou a mensagem de Kill, para quando conseguirmos eliminar uma das empresas. ESQUEMATIZANDO O JOGO: 1) O usuário inicia o jogo a. O jogo cria três empresas dot.com b. O jogo insere as 3 dots em uma grade virtual 2) Começando o jogo Repita as etapas a seguir até não haver mais dots a. Solicita ao usuário um palpite (“A2”, “B5”, etc) b. Confronta o palpite do usuário com as dots que foram criadas aleatoriamente para procurar um acerto, um erro ou uma eliminação. Toma a medida apropriada: se for um acerto, excluir a célula (A2, B5, etc) Se for uma eliminação total da dot, excluir a dot 3) O jogo termina a. Fornece ao usuário uma classificação, baseando-se na quantidade de palpites. Com esta idéia será possível pensar nas possibilidades existentes no jogo e nas coisas que ele precisa saber para funcionar. A próxima etapa é definir que tipos de objetos serão necessários para fazer o trabalho. P á g | 58 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Faremos duas versões, uma mais simples e outra que será o jogo completo, iniciaremos pela versão do Batalha Naval Simples, que chamaremos pela nomenclatura de classe SimpleDotCom. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 14.1 CRIANDO O SIMPLEDOTCOM – O BATALHA NAVAL VERSÃO SIMPLES Nesta versão do jogo as opções serão bem mais simples, a grade de navios (dots) conterá apenas uma única linha, e também teremos apenas uma dot (navio). O objetivo geral do jogo será o mesmo, o jogo precisará criar uma instância da Dot Com, atribuir a ela um local qualquer na linha, solicitar a entrada do usuário e, quando todas as células da Dot tiverem sido adivinhadas o jogo terminará. Esta versão simples a classe Game não terá variáveis de instância, o código do jogo ficará em duas classes, a classe SimpleDotCom e a classe SimpleDotComTestDrive. FUNCIONAMENTO GERAL DO JOGO Quando o programa for iniciado, ele criará uma única instância de SimpleDotCom, selecionará um local para ela (três células consecutivas na única linha vertical de sete células), e solicitará do usuário um palpite, verificará se este palpite está ou não correto e repetirá isto até que as 3 células sejam adivinhadas. Como esta versão simples não possuirá todas as características do jogo completo, as 3 células que consistirão no local correto das empresas serão apenas 3 posições únicas do vetor. Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Salve como SimpleDotCom.java P á g | 59 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas SimpleDotCom int[ ] localCelulas int numAcertos A descrição UML da classe SimpleDotCom String checkYourself(String stringPalpite) Void setLocalCelulas(int[ ] locais) Em seguida precisaremos de uma classe de teste que consiga criar um objeto SimpleDotCom e executas seus métodos. Para a classe SimpleDotCom só nos procupamos realmente com o método checkYourSelf( ), embora seja preciso implementar o método setLocalCelulas( ) para que o método checkYourSelf( ) seja executado corretamente. • Instanciar um objeto SimpleDotCom; • Atribuir um local para ele (uma matriz de 3 ints, como {2,3,4}) • Criar uma String que represente um palpite do usuário (“2”, “0”, etc) • Exibir o resultado e avaliar se está correto (“bem-sucedido” ou “mal-sucedido”) Salve como SimpleDotComTestDrive.class Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Para o teste de SimpleDotCom precisamos: Detalhe: Esta é a classe main() P á g | 60 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas DETALHES DO CÓDIGO IMPLEMENTADO Nada mais é do que um acesso ao objeto Integer e ao método parseInt() que converte (ou tenta converter) algo que é String para inteiro, existem outros que realizam outras funções. Consiste em um aprimoramento do for tradicional, em português claro significa: “A cada elemento de localCelulas, atribua o elemento a variável cell e exeucute o loop”. Este for, dependendo da linguagem utilizada, é equivalente a comandos como for each ou for in, porque é assim que será interpretado: “para (for) cada (each) elemento do (in)” Note que ainda não implementamos o código final do jogo, este código que implementamos é apenas um protótipo para podermos preparar o raciocínio de como será executado o jogo na íntegra. O que queremos realizar realmente é ver o jogo completo e funcionando, para isso teremos de implementar algumas coisas a mais no Java. Para ter o jogo na íntegra, precisaremos de algumas coisas ainda: 14.2 • Validar a entrada do usuário para poder deixar que ele insira um palpite ; • Criar um código dinâmico para a geração das localizações corretas a serem adivinhadas; • Contar os palpites utilizados pelo usuário; • Verificar sempre quando o usuário acertou eliminou todas as dots do jogo; CRIANDO O BATALHA NAVAL VERSÃO FULL Agora criaremos o código na íntegra e poderemos visualizar o seu funcionamento final. Para isso teremos de criar duas classes que trabalharão diretamente com a classe SimpleDotCom, serão as classes launchGame e GameHelper, as duas terão as suas tarefas detalhadas em seguida. P á g | 61 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. VISUALIZANDO O RESULTADO DA IMPLEMENTAÇÃO SEMI-FINAL: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Criando a classe GameHelper Juntando estas duas classes + a classe SimpleDotCom poderemos agora sim visualizar o funcionamento do jogo. Note que a classe launchGame é a classe principal da aplicação (main) e ela é a que será executada para iniciar o jogo de fato. P á g | 62 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Criando a classe launchGame Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. VISUALIZANDO A SAÍDA DO JOGO: P á g | 63 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes 14.3 AULA 09 ANALISANDO O CÓDIGO DO JOGO DE BATALHA NAVAL O jogo da batalha naval utilizou vários recursos interessantes que devem ser explorados. Vimos que no total foram utilizadas 3 classes, a classe SimpleDotCom.java, GameHelper.java e launchGame.java. Vejamos alguns detalhes existentes na implementação do referido jogo: 14.4 SIMPLEDOTCOM simpleDotCom A descrição UML da classe simpleDotCom Esta classe é a principal classe do aplicativo. Note que é nele que declaramos o vetor de localizações de células existentes em nossa grade virtual através da variável localCelulas e do método setLocalCelulas, recebemos os palpites do usuário verificamos se estão ou não certos, e ainda é incrementado o número de palpites feitos e o controle do número de acertos. Note que o método setLocalCelulas() recebe como argumento os locais que serão utilizados para os navios (dots) ocuparem na grade. Não necessariamente estamos afirmando que este método definirá os locais, ele receberá de algum chamador os locais como inteiros e os inserirá na variável localCelulas[ ]; Em outras palavras, esta classe praticamente define quando o jogo acaba ou não, pois é responsável pela contagem dos acertos e de modificar a variável resultado para “você acertou” ou para “kill”. 14.5 GAMEHELPER GameHelper A descrição UML da classe GameHelper getUserInput( ) Esta classe foi criada exclusivamente para uma única tarefa: capturar as entradas do usuário via linha de console. Como o seu nome diz GameHelper, é chamado assim pelo fato de ser um ajudante para o funcionamento geral do jogo. Utilizamos um novo método envolvendo os comandos de um componente das classes Stream, chamado BufferedReader, que é responsável por realizar a comunicação de dispositivos no Java para entrada e saída de informações, e o InputStreamReader, que também pertence as classes Stream e é reponsável pela leitura de linhas de caracteres. Pelo fato das classes Stream possuírem uma grande quantidade de detalhes, apenas precisamos saber agora que a classe GameHelper nos permite capturar o que o usuário digita, valida esta entrada e retorna o que foi digitado como uma string de saída para que possa ser utilizada pelo jogo. P á g | 64 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. localCelulas[ ] numAcertos resultado setLocalCelulas( ) checkYourSelf( ) Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Ainda, nesta classe, utilizamos o comando try{}cath{}, responsável por realizar um tratamento de exceções, ou seja, uma espécie de acumulador e controlador de erros que os organiza para que possam ser mostrados corretamente ao usuário. 14.6 LAUNCHGAME launchGame A descrição UML da classe launchGame main() E por fim a classe launchGame, como o nome diz, é a classe que realiza a inicialização do jogo e, portanto, nossa classe principal da aplicação. Esta classe gera um número aleatório para as posições do vetor e armazena na variável localizações, chamando o método setLocalizacoes da classe simpleDotCom e passando-as como argumentos. Esta classe repetirá o pedido de palpite até que isAlive seja configurada como false, e por fim, informar ao usuário as totalizações de palpites que foram utilizados. 14.6.1 RANDOM( ) E GETUSERINPUT( ) No código a seguir, temos vários detalhes que devem ser explicados: • Primeiro, declaramos uma variável int que armazenará o número aleatório fornecido. • Em seguida, utilizamos (int) para que o retorno do cálculo retorne algo convertido para o formato de inteiro, uma vez que o método Math.random retornará um número com format Double; • O método Math.random retornará m número no intervalo entre zero e menor que um. Portanto o método mais a conversão que foi feita retornarão um número de 0 a 4,999..., convertido como um inteiro. De fato, o que estamos criando é uma conversão que forçará o for retornado pelo cálculo com o método Math.random, que retorna um tipo Double. O que teremos no final então será uma eliminação da parte fracionária do cálculo . Aqui estamos criando uma instância de uma classe que foi construída para auxiliar o jogo, visto o seu nome. O método getuserInput solicita ao usuário que insira algo na linha de comando, a lê depois que a tecla enter é pressionada e retorna o resultado como uma string. Por ora, vimos também a utilização do método de outros recursos como BufferedReader e InputStream, porém como ainda não iremos detalhá-lhos ainda precisamos apenas saber que são códigos que auxiliam para a captura de entrada de dados no console por parte do usuário. P á g | 65 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Também é utilizada uma variável isAlive, responsável por manter o usuário com “vida” ao longo do jogo. Como esta variável é booleana, poderá ter apenas os valores “true” ou “false”, e quando false o usuário não poderá mais continuar o jogo. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 15 HERANÇA A herança consiste em um mecanismo da qual a classe filha herda os estados e comportamentos da classe pai. Foi criado para aprimorar as classes de trabalho existentes. Se precisarmos implementar uma nova classe e já há disponível uma classe que representa um conceito mais geral, a nova classe pode herdar as características da classe existente. Para utilizarmos a herança se faz necessário a utilização da palavra-chave extends seguida do nome da classe ancestral, neste caso devemos sempre lembrar que a classe que é entendida irá possibilitar de utilizar todos os métodos existentes na mesma. 15.1 ESTENDENDO A CLASSE DE ANIMAIS Note que temos um item que precisará ter características comuns à outros itens que também existirão em seu projeto. Em outras palavras, quando projetar utilizar a herança inserirá o código comum em uma classe e, em seguida, informará a outras classes mais específicas que a classe comum é a sua superclasse. Quando uma classe herda de outra, a subclasse herda da superclasse. Animal nome cor getNome() setNome() fazerRuido() A descrição UML da classe Animal Em java, dizemos que a subclasse estende a superclasse. Um relacionamento de herança significa que a subclasse herdará os membros da superclasse. Com o temo “membros de uma classe”, queremos nos referir às variáveis de instância e métodos. E para ativar a herança precisamos apenas utilizar o comando extends na classe que herdará as propriedades gerais. Vejamos o exemplo na íntegra: Leao juba A descrição UML da classe Animal setJuba() P á g | 66 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Para entender o conceito de herança, precisamos nos ater sobre a questão de evitar cada vez mais a replicação de códigos. Veremos uma pequena exemplificação da herança aplicada à uma classe animais. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Exemplo 1 – Criado e Estendendo a classe Animal Criaremos aqui 3 classes para implementar o exemplo: uma para a superclasse Animal, outra para uma subclasse Leão, e uma classe Início que testará as propriedades de herança que queremos visualizar. Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Classe Animal Classe Leao Classe Início P á g | 67 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Visualizando o resultado: No exemplo feito a superclasse criada é a classe Animal, e a subclasse Leão automaticamente está adquirindo todas as variáveis de instância e métodos comuns a todos os possíveis animais que podem ser criados. Mas a subclasse leão poderá adicionar novos métodos e variáveis de instância exclusivos e sobrepor os métodos que herdar da superclasse Animal. 15.2 POLIMORFISMO Sobrepor os métodos significa que se desejarmos alterar algum método que foi herdado para que funcione de maneira diferente originalmente isto poderá ser feito, e a isto damos o nome de POLIMORFISMO. O detalhe é que o método funcionará apenas para a classe que foi criada, e poderá funcionar diferentemente para cada classe que utiliza o método. Visualizando: As variáveis de instância não são sobrepostas porque não precisam ser. Elas não definem nenhum comportamento especial, logo, uma subclasse pode fornecer a uma variável de instância herdada o valor que quiser. Se criássemos outra classe de animal este pode ter o nome que quiser, e também a cor que quiser. 15.3 PROJETANDO UMA APLICAÇÃO COM USO DE HERANÇA Suponhamos que fossemos solicitados a criar um programa que permitisse ao usuário reunir vários animais diferentes em um ambiente para ver o que acontece. Não é necessário codificar nada agora, mas vejamos como ficaria um projeto que atendesse tal necessidade: Para poder atender à demanda, seria necessário em um primeiro momento separar o máximo possível os animais por espécie, para que possamos detalhar melhor as suas características. P á g | 68 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Exemplo 2 – Sobrepondo o método setNome Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Alguns passos podem ser seguidos para a real implementação das classes: 1. Procurar objetos que possuam atributos e comportamentos em comum, esta tarefa consiste em abstrair o máximo possível o comportamento de cada item e detalhar o relacionamento entre eles. 2. Projetar uma classe que represente o estado e o comportamento mais comum possível, no caso de animais, a criação de uma superclasse Animal é clara. Serão incluídos a ela métodos e variáveis de instância que todos os animais podem precisar. Animal nome cor localizacao getNome() setNome() fazerRuido() dormir() andar() 3. Defina e uma subclasse precisa de comportamentos (implementações de métodos) que sejam específicos desse tipo de subclasse em particular. unhas fazerRuido() 4. Procure mais oportunidades de usar a abstração, encontrando duas ou mais subclasses que possam ter um comportamento comum. 5. Termine a hierarquia de classes, como os animais já têm uma hierarquia organizacional podemos usar o nível que fizer mais sentido ao projeto das classes. P á g | 69 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Tigre Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 15.3.1 EXERCÍCIOS 1. Implemente o restante da estrutura de classes de animais para que seja possível representar toda a hierarquia genealógica dos animais seguindo as seguintes regras: a. Cada animal tem um método fazer ruído e comer próprio; b. Ao final, criar uma classe principal para que seja possível criar uma instância para cada animal, dando-lhe um nome e uma cor, e imprimir na tela as suas características principais. 2. Crie um programa para gerenciar um conjunto de médicos de um hospital. Deve ser criada uma superclasse para a categoria geral de médicos e estender classes específicas para os médicos com a sua especialidade. a. Todos os médicos possuem um nome, uma altura e peso. Nas suas especialidades devem ter o nome do curso de graduação e um método que realize cirurgias ou atendimentos específicos para cada médico. b. As categorias de médicos são cirurgião, oftalmologista, otorrino e gineco. 3. Implemente uma superclasse Pessoa. Faça com que duas classes Aluno e Instrutor herdem de Pessoa suas características. A pessoa tem um nome e ano de nascimento. O aluno tem uma nota e o instrutor tem salário. Escreva as definições de classe, os construtores e os métodos set e get para todas as classes. Ao final forneça um programa de testes que teste essas classes e métodos. 4. Crie uma classe Funcionário com um nome e salário. Crie uma classe Gerente herdada de Funcionário. Adicione uma variável de instância (campo) chamada de departamento, do tipo String. Forneça um método toString que imprima nome, departamento e salário do gerente. Crie uma classe Executivo herdada de Gerente. Forneça métodos apropriados para todas as classes. Crie um programa de testes que testes as classes e os métodos. 5. Escreva uma superclasse Trabalhador e subclasses TrabalhadorPorHora e TrabalhadorAssalariado. Cada trabalhador tem um nome e salário pago mensalmente. a. Escreva um método calcularPagamento (int Horas) que calcule o pagamento semanal de cada trabalhador. b. O trabalhador que ganha por hora é pago, obviamente, de acordo com o número real de horas trabalhadas, sendo horas, no máximo, igual a 40. c. Se ele trabalhou mais de 40 horas, cada hora excedente é paga como uma hora e meia. O trabalhador assalariado é pago pela carga horária de 40 horas e meia. O trabalhador assalariado é pago pela carga horária de 40 horas, independentemente de qual seja o número real de horas trabalhadas. d. Crie um programa de testes para podermos testar as suas classes. P á g | 70 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. c. Após criar as classes para os médicos, crie uma classe principal [main()] para que seja possível dar um nome diferente para cada instância de médico e imprimir na tela a sua especialidade; Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes 15.4 AULA 10 HERANÇA – O TESTE É-UM E TEM-UM A idéia por trás da herança é que podemos criar novas classes com base em classes já existentes. Quando herdamos de uma classe existente, podemos reutilizar, ou herdar, seus métodos e campos (variáveis de instância) e adiciona novos métodos e campos para adaptar sua nova classe a novas situações. É uma das técnicas consideradas como essencial em Java. • Um triângulo É-UMA Forma • Um gato É-UM felino • Um Cirurgião É-UM médico Note que todas as afirmações fazem sentido quando tentamos descrever uma origem de herança entre os itens envolvidos. Para saber se as classes foram corretamente projetadas podemos utilizar este teste, que na verdade é um teste de tipo, ou seja, “Faz sentido dizer X É-UM tipo Y?”, se não fizer, saberemos que algo está errado no projeto das classes que foram elaboradas. Já o teste TEM-UM pode ser utilizado para encontrarmos quais variáveis de instância serão utilizadas no projeto das classes que queremos usar. Em outras palavras, com o teste TEM-UM é possível encontrar itens que possuem relações não de herança de classes, mas sim como variáveis de instância que serão incluídas na classe. por exemplo: Pense na classe conta, elaborada anteriormente. Se aplicarmos uma comparação com os itens CONTA e ID, chegaremos à conclusão do seguinte: conta TEM-UM id, logo, saberemos que a relação de ID com conta não é de herança, mas sim como uma variável de instância. Um outro exemplo que pode ser utilizado é uma classe Funcionario. Imagine que após ter concluído a implementação da classe, foram adicionados funcionários que são Gerentes.. Os gerentes certamente são iguais a quaisquer outros funcionários em vários aspectos. Tanto os funcionários como os gerentes recebem um salário. Entretanto, enquanto os funcionários devem finalizar as tarefas atribuídas a eles como um retorno por receberem um salário, os gerentes ganham bônus se acabarem conseguindo realizar o trabalho a eles atribuído. Esta situação é uma situação que pede o uso de herança. Por que? Precisaremos definir uma nova classe gerente, e adicionar funcionalidades. Mas podemos reter um pouco do que já foi programado na classe Funcionário, e todos os campos (variáveis de instância) da classe original podem ser preservados. De forma mais abstrata, há um relacionamento “é um” óbvio entre gerente e funcionário. Todo gerente É UM funcionário Se olharmos as características da classe Funcionario, ela pode ser considerada uma superclasse, classe-base ou parent-class. Ela é uma superclasse não por ser superior às outras classes ou por conter mais funcionalidades. Na realidade o que acontece é o contrário: as subclasses geralmente têm mais funcionalidades do que as superclasses. P á g | 71 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Quando uma classe herda propriedades de outra, dizemos que esta é chamada de subclasse.E neste caso podemos afirmar que a subclasse estende a superclasse. Quando precisarmos saber se uma coisa deve estender outra, podemos aplicar o teste É-UM ou TEM-UM. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 15.4.1 EXEMPLO 1 – EXEMPLO DA UTILIZAÇÃO DE HERANÇA COM A CLASSE FUNCIONÁRIO Criando uma classe para testar a classe Funcionario: Com base nestas duas classes, pense como poderíamos fazer para que seja possível projetar duas novas classes que possam atender às demandas de Empregado e de Gerente. Considerando que precisaremos agora desenvolver a classe gerente, a mesma poderia ser elaborada da seguinte maneira: P á g | 72 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Vejamos a classe Funcionario elaborada inicialmente: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Elaborando a classe Gerente. Normalmente, há mais de uma cadeia descendendo de uma classe ancestral distante. Poderíamos ainda formar uma classe Programador ou Secretaria que estendesse Funcionario. A REFERÊNCIA THIS Quando os parâmetros formais de um método têm os mesmos nomes dos campos de dados de uma classe, os campos de dados são escondidos. Neste caso, para acessar as variáveis escondidas, é necessário usar uma das seguintes práticas: • Se a variável escondida x é estática, então a acessamos usando nomeDaClasse.x; • Se a variável escondida x é de instância, então usamos a palavra-chave this como uma representante do objeto que invoca o método, isto é: acessamos a variável usando this.x; Vejamos o exemplo a seguir: Public class Qualquer{ private Double massa; private static Double carga; public Qualquer(double massa, double carga) this.massa = massa; Qualquer.carga = carga; } public void setMassa(double massa){ this.massa = massa; } public static void setCarga(double carga){ Qualquer.carga = carga; } } P á g | 73 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 15.5 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Neste exemplo criamos mais uma classe de nome Faxineira, onde estende novamente a classe Funcionario e adiciona a variável String Aptidoes, usada para definir quais são as tarefas realizáveis pela faxineira. 15.6 A PALAVRA-CHAVE SUPER Subclasses herdam campos de dados e métodos de uma superclasse, mas não herdam seus construtores. Os construtores de uma superclasse só podem ser invocados a partir dos construtores de suas subclasses através do seguinte comando: super(argumentos) O comando invoca o construtor de superclasse que casa com os seus argumentos. Esse comando deve aparecer na primeira linha do construtor da subclasse. Os argumentos podem estar vazios, isto é: super(); 15.6.1 EXEMPLO 3 – EXEMPLO DE UTILIZAÇÃO DA PALAVRA SUPER PARA CRIAR UM CONSTRUTOR DE SUBCLASSE: Lembrando: Estamos dizendo aqui que a classe Jardineiro está herdando todos os construtores que foram elaborados na superclasse, note que para a criação de instâncias de jardineiro estamos ordenando que a classe Funcionário está assumindo o controle na criação das instâncias. P á g | 74 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 15.5.1 EXEMPLO 2 - EXEMPLO DE UTILIZAÇÃO DA PALAVRA-CHAVE THIS: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Além do uso da palavra chave SUPER para construtores de subclasses, podemos ainda utilizá-la para chamar um método da superclasse. Temos uma situação onde na subclasse criamos um método que também existe na superclasse, mas não queremos utilizá-lo neste momento. Vejamos outro exemplo: 15.6.2 EXEMPLO 4 – EXEMPLO DE UTILIZAÇÃO DA PALAVRA SUPER PARA REALIZAR A INVOCAÇÃO DE UM MÉTODO QUE FOI SOBREPOSTO POR UMA SUBCLASSE Testando algumas funcionalidades: OBSERVANDO OS DETALHES: Neste teste, podemos perceber alguns detalhes: Estamos instanciando um funcionário, um gerente e um eletricista. Nestes casos, todos utilizam construtores. O interessante é que a instância da classe de Eletricista está utilizando um construtor que foi herdado da superclasse Funcionário. P á g | 75 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Adicionando mais uma classe de nome Eletricista. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Note que na construção da classe Eletricista, utilizamos a palavra-chave super() informando os argumentos que irão casar com os parâmetros existentes no construtor da superclasse funcionário. Desta forma poderemos tranquilamente utilizar todas as variáveis de instância que são requeridas no construtor. Ao mesmo tempo, note que na classe Eletricista estamos realizando um teste que verifica o argumento informado no método aumentarSalario( ). A verificação testa o aumento (em percentual) e também o grau de perigo para um aumento de salário, caso o perigo seja 2 ou 3 é visto que o salário será multiplicado diretamente pelo valor do perigo, caso seja 1 é utilizado o método aumentarSalario() existente na classe Funcionario e o argumento de periculosidade é descartado. 15.7 PROJETOS COM O USO DE HERANÇA SÃO OBRIGATÓRIOS? Considere a herança sempre quando tivermos um comportamento que deva ser compartilhado entre várias classes do mesmo tipo geral. Existem várias situações onde inicialmente não é perceptível que se pode usar herança, mas a idéia básica é adicionar ao seu código características importantes como a de maior facilidade na manutenção e uma maior extensibilidade. 15.8 • Eliminação de código duplicado; • Generelização de comportamento comum a um grupo de classes; • Definição de um protocolo comum para o grupo de classes; EXERCÍCIOS: 1) Implemente a herança em uma classe veículo que possa reunir métodos em comum na criação de outras classes. A classe veículo deve permitir a criação de classes específicas como caminhão, trator, ônibus e van. Implemente métodos set() e get() para a modificação e alteração as informações referentes a marca do veículo, ao modelo, ano, tanque de gasolina, aro dos pneus, quantidade de passageiros. 2) Modifique o exercício 1 para a criação de mais uma classe estendendo veículo. Deve ser feita a criação de uma classe Motocicleta e ativar o construtor da superclasse nesta recebendo os mesmos argumentos na criação do construtor de uma motocicleta. 3) Modifique a estrutura criada para veículo e adicione o método andar, considerando que os diferentes tipos de veículos deverão andar() com limites de consumo diferentes. Adicione um campo cidade que possa ser utilizado pelas subclasses com métodos get() e set(). 4) Crie uma classe de teste para instanciar 4 veículos diferentes: um Fiesta, uma Moto Titan 125, um caminhão Mercedes e uma Van Escolar. Obedeça às informações exigidas no construtor que foi gerado e configure cada informação individual de cada veículo. Em seguida imprima na tela cada informação que foi configurada para cada veículo. P á g | 76 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. A herança beneficia o projeto de software com alguns benefícios que serão reconhecidos sempre a longo prazo como: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes AULA 11 16 CLASSES ABSTRATAS A medida que vamos subindo na hierarquia de herança, as classes se tornam mais gerais e provavelmente mais abstratas. Em um certo ponto é possível pensarmos que a classe ancestral se torna tão geral que podemos pensar nela mais como uma base para outras classes do que como uma classe com instâncias específicas que seriam utilizadas. A abstração está associada ao grau de detalhe ou de especificação do projeto de uma classe. Quanto maior o nível de abstração, mais geral e menos específico será a classe. Superclasses estão em um nível de abstração mais alto do que suas subclasses, e quando são projetadas com um nível de abstração muito alto, torna-se tão alto que não pode ter todos os seus métodos concretamente implementados. Uma classe abstrata não pode ser instanciada, pois esta contém métodos abstratos, ou seja, sem implementação. Não podemos utilizar classes abstratas diretamente. Devemos utilizar uma classe filha herdando e implementando todos os seus métodos abstratos. Por exemplo, considere um exemplo de uma extensão de classe da hierarquia da classe pessoa, na figura abaixo: Sabemos pelo que foi estudado anteriormente, que alguns atributos como o nome, por exemplo, certamente farão parte de ambas as classes na estrutura. E por isto serão colocadas na superclasse pessoa para que sejam compartilhados nas subclasses Trabalhador e Estudante. Certamente também compartilharemos um método getNome no nível Pessoa para que seja estendido às suas subclasses. Agora, se precisássemos adicionar um método getDescription, cujo propósito é retornar uma descrição da pessoa, por exemplo: É um trabalhador com um salário de R$7000,00 É um estudante se formando em Análise e desenvolvimento de Sistemas É fácil implementar este método para as classes Trabalhador e Estudante. Mas quais informações poderemos fornecer na classe Pessoa? A classe Pessoa não sabe nada sobre a pessoa, exceto o nome. Poderíamos implementar Pessoa.getDescription( ) para retornar uma String Vazia, mas não é uma boa alternativa. Mas o que queremos realmente chegar é em como utilizar as classes Abstratas. Precisamos saber algumas regras sobre elas: P á g | 77 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. EXEMPLO : Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 1. Classes Abstratas utilizam em sua definição a palavra-chave Abstract. abstract class Pessoa{ } 2. Os seus métodos podem ser criados normalmente como fazíamos anteriormente, porém alguns ou todos os métodos também podem ser definidos como Abstract. public abstract String getDescription(){ } 3. Quando utilizar a Palavra-Chave Abstract, estamos informando à máquina virtual do Java que estes não serão implementados de fato, serão apenas estruturados em sua definição, mas não terão nenhuma real implementação. abstract class Pessoa{ Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. public Pessoa(String n){ nome = n; } public abstract String getDescription(); Vejamos a seguir um exemplo real implementando a classe pessoa e uma classe de teste: 16.1.1 EXEMPLO 1 – IMPLEMENTANDO A CLASSE ABSTRATA ESTUDANTE Classe Pessoa P á g | 78 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. SubClasse Trabalhador SubClasse Estudante P á g | 79 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Classe PessoaTeste OBSERVAÇÕES: No programa desenvolvido anteriormente, é definida uma superclasse Pessoa e duas subclasses concretas (não abstratas), Trabalhador e Estudante. Em seguida é preenchido um array de referências a Pessoa com objetos Trabalhador e Estudante: Em seguida são exibidos os nomes e as descrições destes objetos: Podemos ter uma certa confusão visualizando a seguinte chamada: pessoa.getDescricao() Se pensarmos, esta chamada não diz respeito à um método indefinido? A princípio a variável p poderia se referir a um objeto Pessoa, mas ela nunca poderá realizar esta tarefa, pois é impossível construir um objeto da classe abstrata Pessoa. A variável p sempre refere-se a um objeto de uma subclasse concreta, como Trabalhador ou Estudante. Para estes objetos, o método getDescricao está definido. Teria sido possível omitir completamente o método abstrato da superclasse Pessoa e simplesmente definir os métodos getDescricao nas subclasses Trabalhador e Estudante? Se o tivéssemos feito, não poderiamos invocar o método getDescricao para a variável p, pois o compilador o força a invocar somente os métodos declarados na classe. P á g | 80 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. A classe estudante define o método getDescricao. Assim todos os métodos da classe Estudante são concretos, e a classe não é mais abstrata. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 16.2 ACESSO PROTEGIDO No desenvolvimento dos campos das classes até agora estudados utilizamos as definições private ou public em sua declaração. Quaisquer funcionalidades declaradas como private serão invisíveis para outras classes. Isto também vale para as subclasses, que também não poderão acessar aos campos definidos como private em sua superclasse. Entretanto, existem situações onde será necessário restringir um método a apenas suas subclasses. Seria uma restrição controlada. Isto pode ser feito com o uso da palavra-chave Protected. Na prática, o atributo protected deve ser usado com cuidado, pois imagine que tenha projetado uma classe com campos protegidos utilizando protected. Se resolver mudar de idéia e outros programadores tiverem implementado outras classes estendendo a sua não será possível de alterar este atributo sem desagradar a outros programadores. • PUBLIC: Visível a todos; • PRIVATE: Visível somente a classe; • PROTECTED: Visível ao pacote e a todas as subclasses; • PADRÃO: Visível ao pacote, não são necessários modificadores; Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Em resumo: P á g | 81 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes 16.3 AULA 14 RELEMBRANDO CONCEITOS: Vamos “Relembrar” alguns conceitos que devem ser levados em consideração no entendimento da programação orientada a objetos,seja o conteúdo utilizado anteriormente: • A classe pessoa é uma classe abstrata; • As classes trabalhador e estudante estendem a classe pessoa; • Trabalhador e Estudante são consideradas subclasses; • Pessoa é a superclasse de nossa aplicação OBSERVAÇÕES: Porque tornamos a classe Pessoa uma classe Abstrata? - Se pensarmos um pouco, não tem sentido criar uma instância de pessoa, normalmente o que será utilizado em uma aplicação são instâncias de classes específicas como Trabalhador e Estudante. Mas ainda assim continuamos necessitando da classe Pessoa devido à herança e o polimorfismo. O fato é que queremos na verdade, no projeto da classe, que os programadores instanciem somente as subclasses menos abstratas da classe Pessoa, e não a própria classe Pessoa. Felizmente estamos constatando que uma maneira simples de impedir que uma classe seja instanciada (utilizar o operador new), o uso da palavra chave abstract. Com isto, o compilador impedirá que qualquer código, esteja onde estiver, crie uma instância desse tipo. Recordando a classe Pessoa: abstract class Pessoa{ public Pessoa(String n){ nome = n; } public abstract String getDescription(); No projeto da estrutura de heranças de classe, teremos de decidir que classes serão abstratas e quais serão concretas. Entenda classes concretas como classes específicas o suficiente para serem instanciadas. P á g | 82 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Lembrando: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas RESUMINDO: • A utilidade de uma classe Abstrata é realmente visualizada somente quando a classe é estendida; • Em classes abstratas, o encarregado de trabalhar na execução do código em tempo de execução serão as instâncias de uma subclasse que a estendeu; • Os métodos também podem ser abstratos, e isto implica em que a classe que possui pelo menos uma declaração de método abstrato deverá ser uma classe abstrata; • Métodos abstratos não possuem corpo, ou seja, é como se o programador ainda não soubesse qual será a tarefa do método em questão, mas sabe que o mesmo deverá existir; • Métodos abstratos servem também como se fosse definido um protocolo a ser cumprido. E uma classe, ao estender outra que possui métodos deste tipo, deverá implementar o que quiser utilizar. 16.3.1 EXEMPLO 1 – CRIANDO UMA HIERARQUIA DE CLASSES UM POUCO MAIOR: O interessante de utilizar a herança neste caso é que podemos criar um array genérico Pessoa[ ] e incluir nele objetos de qualquer classe que estenda a classe Pessoa. Neste caso as classes Trabalhador e Estudante; Já possuímos as classes Pessoa, Trabalhador e Estudante, faremos algumas pequenas modificações. Além disso, precisaremos apenas criar as classes: Engenheiro, Médico, Universitário e EnsinoMédio. Implementaremos apenas as classes Engenheiro Médico e Universitário além das já existentes para este exemplo, vejamos os códigos das mesmas: P á g | 83 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Seja então, para exemplo, a seguinte estrutura de herança de classes: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Classe Pessoa (inalterada): Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Classe Trabalhador (reduzida para o exemplo): Classe Estudante (inalterada): P á g | 84 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Classe Engenheiro(nova): Classe Medico (nova): P á g | 85 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Com estas classes, temos toda a estrutura sugerida na hierarquia de classes. Agora precisamos de uma classe para testar a estrutura. Também aproveitaremos para criar uma estrutura de array que armazenará qualquer elemento da hierarquia de classes que foram criadas. Em exemplos anteriores, utilizamos arrays para fazer isto. Desta vez criaremos uma classe exclusiva que fará uma validação na quantidade de elementos que podem ser adicionados ao arrray e um método para adicionar elementos a lista. A classe receberá o nome de PessoaLista: Classe PessoaLista: Aqui estamos criando uma matriz de elementos do tipo Pessoa e utilizaremos a variável codigo para controlar a identificação do elemento que está sendo inserido no array. Um detalhe importante é que na liha não estamos criando um novo objeto Pessoa, e sim um objeto Matriz que conterá o tipo pessoa. Pois sabe-se que classes abstratas não podem ser instanciadas. P á g | 86 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Classe Universitario(Nova): Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas E finalmente a classe testadora de todas as funcionalidades: Classe PessoaTeste: OBSERVAÇÕES: • O que estamos testando neste exemplo são as funcionalidades que são permitidas com o uso de herança. Note que embora tenhamos criado um array do Tipo PessoaLista, a classe PessoaLista herda componentes da classe Pessoa, o que permite que criemos instâncias de qualquer tipo de objeto existente na hierarquia. • Por isso é que conseguimos fazer todas as instâncias a, b, c, d, e, f, com tipos diferentes de objetos e argumentos. Pois sabe-se que cada objeto instanciado terá de obedecer o seu construtor na classe de origem. • No final, o que fazemos é testar o método adiciona( ), que faz a inclusão de um novo item no vetor pessoas, que existe na classe listagem. Lembre-se que a variável listagem está ali (linha 10) porque está fazendo referência a um novo objeto da classe PessoaLista, ou seja, é uma instância de objeto. • Por fim, com o uso do método adiciona(), teremos no máximo a possibilidade de inserir 5 elementos no vetor, podemos alterar a quantidade permitida alterando a variável pessoas na classe PessoaLista. 17 A SUPERCLASSE OBJECT A superclasse object é o último ancestral da hierarquia de objetos do Java. Toda a classe que é criada estende a classe object implicitamente. A classe object é a superclasse de tudo, ou seja, mesmo que possamos nos valer das propriedades do polimorfismo, ainda teremos que criar uma classe com métodos que usem e retornem o tipo polimórfico. Se fosse preciso criar uma classe ainda mais genérica do que a classe Pessoa, por exemplo, uma classe que aceite a criação de qualquer tipo de objeto, mais abstrata ainda. Para isto seria necessário que fosse alterado o tipo do array list que foi criado. P á g | 87 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Visualizando o resultado: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas De fato existe uma classe mais abstrata, a classe Object. Qualquer classe que não estender outra classe estenderá implicitamente Object. E quando a classe estende outra, sempre existirá alguma na hierarquia que não estende nenhuma, esta será a que estenderá implicitamente Object. Em nossos exemplos anteriores, a classe que estende Object é a classe Pessoa. A superclasse Object fornece uma gama de métodos que podem ser utilizados para a solução e verificação de diversas propriedades, vejamos algumas: Função equals(object o) Testa se um objeto é igual a outro. É utilizado para verificar, por exemplo, se dois objetos são idênticos. getClass() Retorna um objeto que contém informações sobre o objeto. toString() Retorna uma String contendo o nome da classe e outros, também diz-se que contém o valor do objeto. hashCode() Exibe uma identificação individual e exclusiva para cada objeto. Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Método Vejamos alguns exemplos: 17.1.1 EXEMPLO 2: TESTANDO O EQUALS() Considerando a mesma classe PessoaTeste criada anteriormente: Visualizando o resultado: P á g | 88 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 17.1.2 EXEMPLO 3: TESTANDO O GETCLASS() Considerando a classe PessoaTeste: Visualizando o resultado: Aqui podemos visualizar a classe de origem do objeto que estamos trabalhando. Considerando a classe PessoaTeste: Visualizando o resultado: Aqui podemos visualizar um código exclusivo para o objeto que estamos testando. 17.1.4 EXEMPLO 5: TESTANDO O TOSTRING(): Considerando a classe PessoaTeste: Visualizando o resultado: RESUMINDO: • A classe Object é considerada a superclasse de todas as classes. Isto quer que tudo o que declarar internamente em qualquer classe que for criada, herdará os métodos da superclasse Object mais os métodos que foram criados nela própria. P á g | 89 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 17.1.3 EXEMPLO 4: TESTANDO HASHCODE() Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Object equals() getClass() hashCode() toString() Implicitamente, a classe Estudante herda da Superclasse Object todos os seus métodos e poderá utilizá-los sempre que precisar em suas implementações. Estudante curso Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. getDescricao( ) Aqui visualmente é representado a herança implícita dos métodos da classe Object Java. P á g | 90 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes AULA 15 18 INTERFACES Uma interface é uma maneira de possibilitarmos que uma classe possa herdar propriedades de mais de uma classe ao mesmo tempo. Consiste em criar uma classe 100% abstrata que possa ter os seus métodos implementados sempre em quem os herdar. Em Java, a interface foi desenvolvida para poder suportar o que em outras linguagens de programação fazem com relação às classes: a Herança Múltipla. E os métodos de uma interface ficarão da seguinte forma: Ou seja, são todos abstratos. Note que na interface definida não será implementado nenhum dos métodos. Eles apenas serão definidos com o seu nome e com os seus argumentos, se houverem (assinatura do método). P á g | 91 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Para poder definir uma interface é necessário definir o seguinte código: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas E a classe que quiser utilizar esta interface terá de realizar a seguinte tarefa em seu código: Comando Função implements Utilizada para implementar uma interface, note que podemos implementar uma interface e ainda estender uma classe qualquer public interface Realiza a declaração de uma interface, quando utilizado devemos saber que os seus métodos deverão ser considerados abstract public abstract É o início da declaração de um método abstrato. O uso da palavra chave public é opcional, pois métodos de interface são implicitamente públicos e abstratos. Interfaces trazem flexibilidade em um código, pois em uma estrutura com mais de uma árvore de herança pode necessitar de uma espécie de herança múltipla e a única saída na linguagem Java será o uso de Interfaces. O interessante também é que uma classe pode estender uma única outra classe e, ao mesmo tempo, implementar diversas outras interfaces. Vejamos um exemplo: COMO SABER SE PRECISAMOS CRIAR UMA CLASSE, UMA SUBCLASSE, UMA CLASSE ABSTRATA OU UMA INTERFACE? Projetando classes, subclasses, classes abstratas e interfaces Classes Primeiro criamos uma classe que não estenda nada (a não ser Object) quando sua nova classe não passar no teste É-UM com nenhum outro tipo (lembre que uma classe define o tipo de objeto que será instanciado) Subclasses Estenda uma subclasse somente quando tiver que criar uma versão mais específica de uma classe e precisar sobrepor ou adicionar novos comportamentos. P á g | 92 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. RESUMINDO: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Classe Abstrata Use uma classe abstrata quando quiser definir um modelo para um grupo de subclasses e tiver pelo menos algum código de implementação que todas as subclasses possam usar. Interfaces Utilize uma interface quando quiser definir uma função que outras classes possam desempenhar independentemente de onde essas classes estejam na árvore de herança. Exemplo 1: Uma implementação real da Interface Funcionário Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Interface Funcionario Classe Engenheiro implementando a Interface Funcionario P á g | 93 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 19 EXERCÍCIOS DE INTERFACES 1) Identifique as relações entre os diagramas abaixo. A tarefa é converter em declarações Java válidas: LEGENDA: Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Seguindo a simbologia sugerida, execute as tarefas abaixo: nº1: P á g | 94 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 2) Analise a estrutura de herança abaixo que foi utilizada anteriormente. No modelo, temos a possibilidade de aplicar um modelo de interface para quando ocorrerem situações de duas classes precisarem de um mesmo comportamento. Baseando-se e observando os detalhes das mudanças que devem ser aplicadas, desenvolva os seguintes códigos: A. Transforme as classes trabalhador e estudante em interfaces, passando a apenas definir os métodos que são importantes para um trabalhador. Escreva a implementação de código que seria necessária para tal tarefa. B. Faça com que um Engenheiro seja ao mesmo tempo um Trabalhador e um Estudante. Para isto escreva o código onde a classe Engenheiro implemente as interfaces Trabalhador e Estudante. C. Escreva também o código que possibilite a um Universitário ser um Trabalhador. P á g | 95 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Observando esta estrutura, pense em como poderíamos modificá-la para que as classes Engenheiro e Médico possam ser um Estudante e como um Universitário poderia ser ao mesmo tempo um Trabalhador e um Estudante. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes AULA 16 20 MANIPULANDO EXCEÇÕES Estudaremos algumas características relativas à exceções em Linguagem Java. Iniciaremos um aplicativo que trabalhará com a reprodução de sons baseando-se na API Java Sound, a qual é utilizada para a reprodução de sons em formato MIDI (Musical Instrument Digital Interface). Se elaborarmos o código, veremos que teremos um problema que será avisado pelo NetBeans: Na linha acima, estamos tentando utilizar um método chamado getSequencer(), este método possui uma característica ainda não estudada em conteúdos anteriores: métodos que podem gerar exceções e que permitam lidar com elas. Para tanto, precisamos de alguma forma para podermos manipular as exceções que determinados métodos podem lançar na execução de algum código. 20.1 UTILIZANDO O TRY/CATCH O bloco de código try/catch é o mais famoso manipulador de exceções existente no Java. Normalmente ele informa ao compilador que erros podem ocorrer durante a execução de código e ajuda a manipular os mesmos através de declarações utilizadas para lançar o erro. O código criado anteriormente poderá ser resolvido da seguinte forma: P á g | 96 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Para iniciar a criação do aplicativo de musica é necessário criar um seqüenciador, que permitirá gerar algum som. Para tanto, iniciaremos abordando o código abaixo: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas O código em si não executa tarefa alguma, serve apenas para testarmos um início de execução de um bloco com uso de try/catch. Com o uso de try/catch estaremos sempre executando algum código que pode gerar algum tipo de exceção. Note que o argumento de catch () é uma variável ex do tipo Exception. Normalmente o código que é inserido em um bloco cath dependerá da exceção que for lançada, como exemplo, poderíamos estar tentando acessar um servidor e ter uma exceção informando qual o erro de não ter conseguido. Em programação Java, é comum ficar mais tempo manipulando exceções do que criando e lançando-as. E atualmente é apenas necessário que quando um código chamar um método que lança exceções será este método que lançará a exceção para o código que o chamou. Exemplo: Criando um código com exceção: public void metodoArriscado() throws BadException{ if(abandonarTudo){ throw new BadException(); } } P á g | 97 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Uma exceção consiste em um objeto Exception de tipo Exception, vejamos alguns componentes da hierarquia da classe Exception: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Detalhes: • throws BadException: está informando para qualquer chamador que está lançando uma exceção BadException; • throw new BadException(): cria um novo objeto Exception e o lança; Criando um código que usa, ou chama o método com exceção: public void chamaMetodo(){ try{ umObjeto.metodoArriscado(); }cath(BadException ex){ System.out.println(‘Alô mundo!’); ex.printStackTrace(); } } • ex.printStackTrace(): se não conseguir se recuperar da exceção, pelo menos estamos executando um rastreamento de pilha, que todas as exceções herdam. Um método captura(try) o que o outro método lança (throws). Uma exceção é sempre lançada para o chamador. O método que lança tem que declarar que ele pode lançar a exceção. A utilização de blocos try/catch deve ser utilizada em sua quase totalidade em códigos onde nem sempre teremos a garantia de que será possível executar ações bem-sucedidas, ou exibir ao usuário alguma mensagem de erro que possa identificar a origem do erro. Existe ainda a cláusula finally{ }, que descreve um bloco de código que será sempre executado independentemente do comportamento do try ou do cath. Ela é sempre colocada após o cath da mesma forma que os demais: public void chamaMetodo(){ try{ umObjeto.metodoArriscado(); }cath(BadException ex){ System.out.println(‘Alô mundo!’); ex.printStackTrace(); }finally{ facaAlgo(); } } A seguir criaremos um aplicativo onde através do Java poderemos reproduzir um som utilizando o pacote midi. P á g | 98 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Detalhes: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Criando o início da aplicação de player de música: Neste exemplo será utilizado um recurso da linguagem Java chamado JavaSound, onde é organizado da seguinte maneira: 1. Um dispositivo que reproduzirá a música 2. A música a ser reproduzida 3. A parte da sequência que contém as informações reais Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 4. AS informações reais sobre a música: notas a serem reproduzidas, duração, etc. O resultado deste aplicativo é que conseguiremos a simples reprodução de um som de piano. É pouco, porém teremos uma maneira de testar o uso de um manipulador de exceções em primeira mão. Como o foco inicial é o uso do manipulador try/catch P á g | 99 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Explicando melhor nosso código, para reproduzir um som era necessário: 1. Capture um seqüenciador (Sequencer) e abri-lo 2. Criar uma nova sequência (Sequence) 3. Capturar uma nova faixa (Track) na sequência Aqui estamos fornecendo a sequência ao sequenciador, como se fosse inserir um cd no cd player. 5. Ordenar ao seqüenciador que inicie a reprodução: Aqui é como se pressionássemos a tecla PLAY de um gravador. Outra forma de interagirmos com este código é realizando pequenas alterações na classe, porém faremos isto em uma classe separada. O próximo exemplo possibilita que o usário possa personalizar o código para que o tom e o instrumento possam ser alterados. Exemplo 2 – Personalizando o som a ser reproduzido P á g | 100 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 4. Preencher a faixa com eventos MIDI (MidiEvents) e fornecer a sequência ao seqüenciador Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 3º sem – Análise e Desenvolvimento de Sistemas P á g | 101 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes AULA 17 21 UTILIZANDO A PARTE GRÁFICA NO JAVA Iniciaremos nossos estudos sobre a parte gráfica no Java. Iniciaremos visualizando um Jframe, que consiste em um objeto que representa uma janela na tela. É onde inseriremos todos os elementos da interface gráfica como botões, caixas de seleção, campos de texto entre outros elementos. O JFrame tem aparências diferentes em plataformas de sistemas operacionais diferentes. De forma geral o que mudam são as cores, algum pequeno formato das barras, etc. Para criar nossa primeira moldura precisaremos seguir os seguintes passos: 1. Criar uma moldura (objeto JFrame) 2. Criar um elemento gráfico (botão, caixa de texto, etc) 3. Adicionar o elemento gráfico criado para ser inserido na moldura; Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 4. Exibir a GUI(fornecer uma dimensão para a tela e tornar a mesma visível aos olhos do usuário) Vejamos um código que realiza tal tarefa: Exemplo 1: Criando a primeira interface gráfica P á g | 102 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Agora temos uma interface básica elaborada. Note que além do frame que foi criado, temos um botão alocado na totalidade da extensão do frame. Precisaremos ajustar as dimensões do botão para que não fique ocupando toda a área disponível do frame. Quando clicamos no botão nada acontece, isto se deve ao fato de não estarmos ainda controlando os eventos que acontecem a medida que o usuário realiza a interação com a interface, precisaremos tratar disto também. As classes swing estão localizadas no pacote javax.swing e são, de fato, uma atualização e expansão das funcionalidades da biblioteca awt do Java. Há algum tempo estas classes tinham a fama de serem extremamente lentas em computadores mais antigos, mas com as novas atualizações da virtual machine Java isto não é mais realidade, ainda existe uma pouca degradação de desempenho, mas as possibilidades que existem no swing acabam compensando este fato. Detalhando melhor um frame Por padrão, um frame possui um tamanho de 0x0 pixels. Por isto utilizamos em nosso código o método frame.setSize(300, 300) para que fosse possível setar o tamanho de um frame em uma medida em pixels. Existem também uma forma para controlar o que acontece quando o usuário fechar o frame, na maioria dos aplicativos iniciais do Java é comum querer que o programa termine. Para esta tarefa foi utilizado o comando frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) Por padrão, os frames que são construídos também não são exibidos automaticamente, eles iniciam a suas vidas de forma invisível, isto dá ao programador a oportunidade de adicionar componentes ao frame antes de exibi-lo pela primeira vez. O método utilizado aqui foi frame.setVisible(true). P á g | 103 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. As classes Swing Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Exemplo 2: Utilizando um pouco da manipulação de eventos Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Aqui iniciaremos as propriedades de controle das ações do usuário e sua interação com as interfaces gráficas, vejamos um primeiro exemplo: Visualizando o exemplo: P á g | 104 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Programação Orientada a Objetos - 3º semestre Prof. André Moraes AULA 18 Continuação Interfaces Gráficas Faremos outro exemplo que implementa uma constituição de uma tela onde um aplicativo gera um gradiente em forma de círculo que pode ser trocado de cor a media que o botão é pressionado: Vejamos o seu código: Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Exemplo 1: Inserindo um botão com eventos P á g | 105 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes Visualizando o exemplo criado: OBSERVAÇÕES: Neste exemplo, tivemos de implementar uma interface específica para a escuta de eventos gerados pelo usuário. Neste caso foi implementado a interface ActionListener e o evento actionPerformed. Os dois consistem em capturar eventos gerados pelo usuário e tratá-los como eventos específicos de interação como cliques, arrastes, pressionamentos de tecla, etc. O exemplo possui as seguintes classes: public void main(){ } P á g | 106 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. 3º sem – Análise e Desenvolvimento de Sistemas Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Responsável pela execução do programa, note que esta fica incluída juntamente com a classe de execução do programa. Embora não seja uma prática tão interessante pode economizar tempo para realizar o teste de algumas funcionalidades. public void go(){ } • Criar o frame onde a aplicação será exibida; • Criar o botão que será utilizado pelo usuário; • Enviar uma chamada a interface ActionListener() para que seja possível detectar as ações executadas pelo botão; • Posicionar o a tela do oval criado na variável painel e o botão em alguma das regiões do frame; • Configurar o tamanho do frame; • Configurar o frame para que seja visível ao usuário; public void actionPerformed(){ } Método integrante da interface ActionListener, e é responsável por receber o evento gerado pelo usuário e realizar alguma tarefa. Também diz-se que este é chamado de ouvinte. Neste caso a tarefa realizada é a de atualizar a tela para toda a vez que o usuário acionar um clique no botão que foi criado. public void MyDrawPanel(){ } Esta é uma classe, e é responsável por gerar um elemento gráfico e pintá-lo com uma cor gradiente. No exemplo são utilizadas 3 cores aleatórias para cada chamada. Estas são pintadas no elemento g2d que é chamado no frame criado anteriormente no método go(). Ainda podemos realizar algumas alterações para testarmos o exemplo: E o que será gerado: P á g | 107 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Responsável pela maioria das tarefas executadas no exemplo. Vejamos algumas: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Como estamos utilizando a variável g2d como uma instância de Graphics2D será possível criar diversos elementos gráficos diferentes, desde que obedecidos seus construtores. Quando utilizamos o swing para realizar a criação de elementos gráficos manualmente, devemos estar cientes de que para cada elemento que for criado será necessário posicioná-lo na tela informando isto para o método getContentPane(). P á g | 108 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Outra alteração: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Exemplo 2: Inserindo mais outro botão com eventos P á g | 109 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas A principal alteração que fizemos neste exemplo foi a divisão entre os dois ouvintes de eventos: um evento para alterar a cor e outro para alterar a label que foi criada. P á g | 110 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Visualizando o exemplo dado: Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 22 UTILIZANDO A API DO JAVADOC A API JavaDoc consiste em uma documentação online contendo toda a referência sobre as classes adotadas no padrão Java J2SE e demais implementações disponíveis. A grande vantagem de utilizar a api de documentação é que podemos, por exemplo, explorar as funcionalidades de classes e métodos ainda não explorados pelo programador. Segue abaixo o link e acesso ao JavaDoc na Web: http://java.sun.com/j2se/1.5.0/docs/api/index.html Como utilizamos a interface ActionListener nos exemplos implementados, é interessante visualizarmos a documentação referente a esta interface. P á g | 111 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Aqui estamos visualizando todas as classes atuais disponíveis online na Documentação disponibilizada pela Sun. Acima e a esquerda visualizamos os pacotes e/ou classes da biblioteca Java, ainda a esquerda e abaixo, visualizamos todos os componentes existentes na classe, como interfaces, métodos, classes abstratas, etc. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. É possível notar que como esta interface é responsável pelos principais eventos realizados pelo usuário, como ações com o mouse, interações com elementos, etc. E por isto podemos visualizar uma imensidão de itens que compõem a interface. P á g | 112 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas Para finalizarmos o conteúdo da unidade curricular de Programação Orientada a objetos, faremos a revisão de vários dos conceitos que foram estudados anteriormente. 1. Preencha as lacunas (Classes – Métodos - Modificadores): a) Os membros de uma classe são acessados através do operador______________________, junto com uma referência a um objeto da classe. b) Os membros de uma classe especificados como _______________________ são acessíveis somente para métodos da classe. c) O _______________________é um método especial utilizado para inicializar as variáveis de instância de uma classe. Normalmente ele é utilizado para controlar como são geradas as instâncias de objetos quando são criados com o operador new. d) Os métodos iniciando com a palavra _________ são utilizados para atribuir valores a variáveis de instância private de uma classe. e) Os métodos de uma classe são declarados normalmente como_______________________e as variáveis de instância de uma classe normalmente são declaradas como_______________________. O método inicializado com a palavra_______________________é utilizado para recuperar valores de dados private de uma classe qualquer. g) A palavra chave _______________________introduz uma definição de classe. h) Os membros de uma classe especificados como _______________________são acessíveis em qualquer lugar em que um objeto da classe estiver tentando acessá-los. i) O operador________________é utilizado para alocar memória para um novo objeto de um tipo especificado e retorna uma _______________________para aquele tipo. j) A palavra –chave _______________________especifica que um objeto de uma variável não é modificável depois de inicializado. P á g | 113 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. f) Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 2. Preencha as lacunas (Herança – Classes Abstratas - Polimorfismo): a) Se a classe Alpha herda da classe Beta, a classe Alpha é chamada de ________classe, e a classe Beta é chamada de _______classe. b) A herança permite a _________________, que economiza tempo no desenvolvimento e estimula a utilização de componentes de software previamente testados e de alta qualidade. c) O Objeto de uma________________classe pode ser tratado como objeto de sua_______________classe correspondente. d) Os quatro especificadores de acesso de membro são_____________, _____________, _____________ e _____________. e) O relacionamento “tem um” entre as classes representa _____________e o relacionamento “é um” entre as classes representa _____________. f) Utilizar o polimorfismo ajuda a eliminar a lógica da estrutura condicional estruturada _____________. g) Se uma classe contiver um ou mais métodos abstract, ela é uma classe_____________. 3. Responda as questões abaixo: a) Defina os seguintes itens: herança simples, herança múltipla, interface, superclasse e subclasse. b) Explique a diferença entre herança simples e herança múltipla. Porque Java não suporta herança múltipla? Qual o recurso existente na linguagem Java para os benefícios da herança múltipla? c) Qual a diferença entre métodos abstract de métodos não-abstract? d) Explique como o polimorfismo possibilita a capacidade de reutilizar um método para vários elementos ao mesmo tempo? 4. Responda Verdadeiro ou falso (justifique a sua resposta: a) Um construtor consiste em um método que é chamado quando é criado qualquer tipo de objeto com o uso do operador new. ( ) verdadeiro ( )falso JUSTIFICATIVA:_______________________________________________________________________ :____________________________________________________________________________________ b) Uma variável de instância que definida em um método pode ser acessada por outros métodos através do operador ponto, isto permite que seja alterado o seu valor diretamente sem precisar de métodos get e set. ( ) verdadeiro ( )falso JUSTIFICATIVA:______________________________________________________________________________ ___________________________________________________________________________________________. P á g | 114 Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. h) Uma subclasse pode chamar qualquer método não-private de sua superclasse através da chamada de método com _____________. Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas c) Uma classe só poderá ser considerada Abstract se e somente se tiver pelo menos um método definido como abstract. ( ) verdadeiro ( )falso JUSTIFICATIVA:______________________________________________________________________________ ___________________________________________________________________________________________. d) Para chamar um construtor de uma superclasse é suficiente o uso da palavra-chave super() informando ao construtor da superclasse todos os seus argumentos necessários. ( ) verdadeiro ( )falso JUSTIFICATIVA:______________________________________________________________________________ Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. ___________________________________________________________________________________________. P á g | 115 Prog. Orientada a Objetos UC – Docente: André Luiz Silva de Moraes 3º sem – Análise e Desenvolvimento de Sistemas 5. Projete as seguintes SuperClasses e SubClasses: Considerando as propriedades adquiridas com a Herança, projete as seguintes classes e implemente-as de acordo com as regras de Herança estudadas anteriormente: Superclasse SubClasses AlunoDeGraduacao Aluno AlunoDePosGraduacao Circulo Forma Triangulo Retangulo FinanciamentoDoCarro FinanciamentoDaReformaDaCasa Faculdade de Tecnologia SENAC PELOTAS - Credenciado pela Portaria nº. 3.071, de 01 de outubro de 2004. Financiamento FinanciamentoDaCasa CorpoDocente Empregado Funcionário ContaCorrente Conta Poupanca P á g | 116