Programação Orientada a Objetos Artur Henrique Kronbauer [email protected] 1 Programa de computador É um conjunto de comandos e regras que um programador deve conhecer para poder manipular os recursos de um computador. São escritos programação. em uma linguagem de Para que um programa possa ser executado deve ser traduzido para uma linguagem que possa ser compreendida pelo computador através de um compilador. 2 Programa de computador Programas processam dados. O paradigma de programação orientada a objetos considera que os dados a serem processados e os mecanismos de processamento desses dados devem ser considerados em conjunto. Os modelos representam conjuntamente dados e operações sobre esses dados. 3 Modelos Modelos são representações simplificadas de objetos, pessoas, itens, tarefas, processos, conceitos, idéias etc. São usados comumente por pessoas no seu dia-a-dia, independente do uso de computadores. Restaurante Caseiro Hipotético Mesa 1 Mesa 2 Mesa 3 Kg refeição Kg refeição Kg refeição Sobremesa Sobremesa Sobremesa Refrigerante Refrigerante Refrigerante Cerveja Cerveja Cerveja 4 Modelos e Dados O quadro branco é um modelo do restaurante, representando de forma simplificada as informações do restaurante necessárias para contabilizar os pedidos. O modelo representa certos dados ou informações. Os dados contidos no modelo são somente relevantes à abstração do mundo real feita. 5 Modelos e Operações Um modelo normalmente contém operações ou procedimentos associados a ele, por exemplo: • Inclusão de um pedido para uma mesa. • Modificação do status de um pedido. • Encerramento dos pedidos de uma mesa. Também é possível a criação de modelos que possuem somente dados ou somente operações. Modelos podem conter submodelos e ser parte de outros modelos. 6 Modelos e Orientação a Objetos A simplificação inerente aos modelos é, em muitos casos, necessária: dependendo do contexto, algumas informações devem ser ocultas ou ignoradas. • Pessoa como empregado de empresa • Pessoa como paciente de uma clínica médica • Pessoa como contato comercial A criação e uso de modelos é uma tarefa natural e a extensão desta abordagem à programação deu origem ao paradigma Programação Orientada a Objetos. 7 Programação Orientada a Objetos Os modelos baseados em objetos são úteis para compreensão de problemas, para comunicação com os usuários das aplicações, para modelar empresa, projetar programas, etc. POO é um paradigma de programação de computadores onde se usam classes e objetos, criados a partir dos modelos descritos anteriormente, para representar e processar dados usando programas de computadores. 8 Encapsulamento A capacidade de ocultar dados dentro do modelos, permitindo que somente operações especializadas ou dedicadas manipulem os dados ocultos chama-se encapsulamento. Encapsulamento é um dos benefícios mais palpáveis da POO. Modelos que encapsulam os dados possibilitam a criação de programas com menos erros e mais clareza. 9 Encapsulamento Modelos podem conter dados para representação das informações ou dados relativos ao que se deseja modelar e operações para manipulação dos dados. Em muitos casos, será desejável que os dados não possam ser acessados ou usados diretamente, mas somente através das operações. Por Exemplo: Máquina fotográfica – o mecanismo da câmera oculta os dados e a maneira como são processados. 10 Encapsulamento Em muitos modelos teremos vantagens em usar mecanismos de ocultação de dados: sempre que existir uma maneira de deixar ao modelo a capacidade e responsabilidade pela modificação de um de seus dados, devemos criar uma operação para fazê-lo. Por exemplo: • Modelo que represente conta bancária e operação de retirada. 11 Mais exemplos de modelos Exemplo 1: Uma lâmpada incandescente Lâmpada estadoDaLampada acende() apaga() mostraEstado() Atenção para os nomes de dados e das operações. A abrangência do modelo define os dados e operações. 12 Exemplo 1: em pseudocódigo Representa uma Modelo Lampada lâmpada em uso Início do modelo dado estadoDaLampada; operação acende() Acende a Lâmpada início estadoDaLampada = aceso; fim Apaga a Lâmpada operação apaga() início estadoDaLampada = apagado; fim Mostra o estado da lâmpada operação mostraEstado() início se (estadoDalampada == aceso) imprime “A lâmpada está acesa” senão imprime “A lâmpada está apagada”; fim Fim do modelo 13 Mais exemplos de modelos Exemplo 2: Uma conta bancária simplificada ContaBancariaSimplificada nomeDoCorrentista saldo contaÉEspecial abreConta(nome,deposito,éEspecial) abreContaSimples(nome) deposita(valor) retira(valor) mostraDados() Aspectos práticos de contas reais (senhas, taxas) foram deixados de lado. 14 Exemplo 2: em pseudocódigo Modelo ContaBancáriaSimplificada Dados da conta Inicio do modelo dado nomeDoCorrentista, saldo, contaÉEspecial ; argumentos para a operação operação abreConta(nome,deposito,especial) início nomeDoCorrentista = nome; saldo = deposito; Inicializa simultaneamente contaÉEspecial = especial; todos os dados do modelo fim operação abreContaSimples(nome) início nomeDoCorrentista = nome; saldo = 0.00; contaÉEspecial = false; fim Inicializa simultaneamente todos os dados do modelo, usando o nome passado como argumento e os outros valores com valores default 15 Exemplo 2: em pseudocódigo continuação operação deposita(valor) Deposita um valor na conta início saldo = saldo + valor; fim Retira um valor na conta operação retira(valor) início A conta não é especial se (contaÉEspecial == false) inicio se (valor <= saldo) Existe saldo suficiente saldo = saldo – valor; fim Conta especial, pode retirar a vontade senão saldo = saldo - valor; fim operação mostraDados() Mostra os dados imprimindo seus valores inicio imprime “o nome do correntista é “ + nomeDoCorrentista; imprime “o saldo é “ + saldo; imprime se (contaEEspecial) imprime “A conta é especial” fim Fim do modelo 16 Mais exemplos de modelos Exemplo 3: Uma data Data dia mês ano inicializaData(d,m,a) dataÉVálida(d,m,a) mostraData() Consideramos que o valor do mês é um inteiro; Consideramos também que existem datas válidas e não válidas 17 Classes e objetos Programadores que utilizam POO criam e usam objetos a partir de classes, que são relacionadas diretamente com os modelos descritos. Classes são estruturas utilizadas para descrever os modelos, ou seja, contém a descrição dos dados (atributos) e das operações (métodos) que podem ser realizadas sobre eles. Nome da Classe Atributo 1 Atributo 2 Atributo 3 ••• Método 1 Método 2 ••• Um objeto ou instância é a materialização da classe. 18 Classes e objetos Os dados contidos em uma classe são conhecidos como campos ou atributos daquela classe. Cada campo deve ter um nome e ser de um tipo de dado nativo ou uma classe existente. Valores dentro de classes podem ser variáveis. As operações contidas são os métodos. Métodos podem (parâmetros). receber argumentos O nome mais os parâmetros do método são chamados de assinatura. 19 Classes e objetos Para que objetos ou instâncias possam ser manipulados, é necessária a criação de referências a estes objetos, que são variáveis do “tipo” da classe. Classe -> Planta do edifício, que descreve o edifício, mas não corresponde fisicamente a ele. Instância -> Edifício construído. Referência -> Nome do Objeto (ilhaDoSol) Classe Edifício instâncias Edifício ilhaDoSol Edifício palaci Edifício iguatemi 20 Classes em Java – Sintaxe Básica Uma classe em Java será declarada com a palavra-chave class seguida do nome da classe. O nome não pode conter espaços. Deve começar com uma letra. Deve ser diferente das palavras reservadas. Caracteres maiúsculos e minúsculos são diferenciados. Conteúdo da classe limitado pelas chaves { }. class Empregado Exemplo: Nome da classe { String Nome; Atributo public String ApresentarNome( ) { return Nome; } } Método 21 Classes em Java - Palavras Reservadas abstract boolean break byte case catch char class const Continue default do double else extends false final finally float for if implements import instanceof int interface long native new null package private protected public return short static super switch Syncronyzed this throw throws transient true try void while 22 Classes em Java - Campos da Classe Os campos das classes (atributos) devem ser declarados dentro do corpo da classe. Cada campo deve ser representado por um determinado tipo de dado. Em linguagens OO, é possível declarar campos como referências a instâncias de outras classes já existentes (Objetos). Também é possível declarar campos de tipos primitivos da própria linguagem (Variáveis). 23 Classes em Java – Declaração de Campos A declaração é simples, basta declarar o tipo de dado, seguido dos nomes dos campos que são daquele tipo. Podemos observar que, para cada dado do modelo existe um campo correspondente na classe. Campos podem ser referências a uma classe. Exemplo: class DataSimples 24 Classes em Java – Tipos Primitivos (nativos) Tipo byte short int long float double char boolean Faixa de Valores -128 a 127 -32.768 a 32.767 -2.147.483.648 até 2.147.483.647 -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807 1.401298464324811707e-45 a 3.40282346638528860e+38 4.94065645841246544e-324 a 1.79769313486231570e+308 Representam um único caracter True ou False Armazenamento Inteiro de 8 bits Inteiro de 16 bits Inteiro de 32 bits Inteiro de 64 bits Ponto Flutuante de 32 bits 8 bytes ou 64 bits 16 bits 1 bit A classe String é usada para representar cadeias de caracteres. (Não são dados nativos, sendo instâncias da classe String) 25 Classes em Java – Operadores Aritméticos Operadores Aritméticos + (soma) - (subtração) * (multiplicação) / (divisão) % (resto de uma divisão inteira) int(A) / int(B) (parte inteira de uma divisão) Operação com instâncias da classe String. + (concatenação) 26 Classes em Java - Conversões entre tipos numéricos Conversão entre Tipos Numéricos: Sempre que for realizada uma operação numérica (+, -, *, /) entre dois tipos diferentes será considerado como se os operadores fossem do mesmo tipo. Para isso, o operador de maior capacidade dita o tipo a ser considerado. Maior Menor byte short int long float double Conversões Explicitas: Para fazer conversões que não seguem a regra anterior é necessário realizar conversões explicitar, veja o exemplo: double x = 9.997; int nx = (int) x; Sintaxe para uma conversão Explicita Resultado após a conversão nx = 9 27 Classes em Java - Métodos de Classes A maioria das classes representa modelos que tem dados e operações que manipulam esses dados. As operações são chamadas de métodos. Métodos não podem ser criados dentro de outros métodos, nem fora da classe à qual pertencem. Exemplo: class DataSimples 28 Classes em Java – Exemplo DataSimples class DataSimples { Método da classe byte dia,mes; short ano; Tipos primitivos definidos como atributos (variáveis) void inicializaDataSimples(byte d,byte m,short a) { if (dataEValida(d,m,a) == true) { dia = d; mes=m; ano=a; Parâmetros } baseados em else tipos primitivos { dia = 0; mes=0; ano=0; } Método da classe } boolean dataEValida(byte d,byte m,short a) { if ((d>=1) && (d<=31) && (m>=1) && (m<=12)) return true; else return false; } 29 Classes em Java – Exemplo DataSimples boolean eIgual(DataSimples outraDataSimples) { if ((dia == outraDataSimples.dia) && ( mes == outraDataSimples.mes) && (ano == outraDataSimples.ano)) return true; else return false; Método } da classe Parâmetros baseados em um objeto da própria classe void mostraDataSimples() { System.out.println(dia + “/” + mês + “/” + ano); } } 30 Classes Java – Escopo de Variáveis e Objetos O escopo dos campos e variáveis dentro de uma classe determina a sua visibilidade. Campos declarados em uma classe são válidos por toda a classe, mesmo que os campos estejam declarados depois dos métodos que os usam. Variáveis e instâncias de objetos declarados dentro de métodos só serão válidos dentro desse método. Dentro de métodos e blocos de comandos, as variáveis e objetos devem ser declarados antes de serem utilizadas. Variáveis passadas como argumentos para métodos só são válidas dentro dos métodos. Exemplo: class Data 31 Classes em Java – Modificadores de Acesso Modificadores de acesso podem ser usados tanto em campos como em métodos de uma classe. O objetivo é proteger a integridade e a consistência dos dados e operações que uma determinada classe manipula. Exemplo de Proteção aos Atributos (dados) Por exemplo na classe dataSimples analisada anteriormente, observamos que ao ser inicializada uma data, os campos dia, mês e ano passam por um processo de consistência, ao ser chamado o método dataEValida. Entretanto, como não são usados modificadores, não podemos garantir que sempre as datas serão validadas, pois os campos da classe podem ser acessados diretamente, sem a utilização dos métodos da classe. 32 Classes em Java – Modificadores de Acesso Exemplo de Proteção aos Métodos (ações) Outro exemplo, seria um método imprimeNúmeroDaPágina de uma classe Relatório. Esta classe teria o método imprimeRelatório que sempre que necessário se utilizaria do método imprimeNúmeroDaPágina. Seria inadequado a execução de imprimeNúmeroDaPágina desatrelado do método imprimeRelatório. No primeiro exemplo apresentado, seria conveniente usar um modificador para proteger os dados, assim garantindo que as datas sempre seriam validados. No segundo exemplo, seria conveniente usar um modificador para restringir o acesso ao método imprimeNúmeroDaPágina, já que este só deve ser usado através do método 33 imprimeRelatório. Classes em Java – Modificadores de Acesso Existem quatro modificadores de acesso: public: garante que o campo ou método da classe declarado com este modificador poderá ser acessados ou executado a partir de qualquer outra classe. private: só podem ser acessados, modificados ou executados por métodos da mesma classe, sendo ocultos para o programador usuário que for usar instâncias desta classe ou criar classes herdeiras ou derivadas. protected: funciona como o modificador private, exceto que classes herdeiras ou derivadas também terão acesso ao campo ou método. Finalmente, campos e métodos podem ser declarados sem modificadores. Nesse caso, eles serão considerados como pertencentes à categoria package, significando que seus campos e métodos serão visíveis para todas as classes de um mesmo pacote. 34 Classes em Java – Modificadores de Acesso Ao criar uma classe, o programador deve implementar uma política de ocultação ou de acesso a dados e a métodos internos. Regras básicas para implementação de políticas para classes simples: Todo campo deve ser declarado como private ou protected. Métodos que devem ser acessíveis devem ser declarados com o modificador public. Caso classes não venham a ser agrupadas em pacotes, a omissão não gera problemas. Métodos para controle dos campos devem ser escritos, e estes métodos devem ter o modificador public. Se for desejável, métodos podem ser declarados como private. 35 Exemplo de Escopo e Modificadores public determina que essa classe pode ser instanciada dentro de qualquer outra classe. public class Data { private byte dia, mes; private short ano; private determina que os dados só podem ser manipulados dentro da própria classe. Como “dia”, “mês” e “ano” são declarados fora dos métodos, são variáveis globais (atributos). public void inicializaData(byte d,byte m,short a) { public indica que o método pode ser acessado sem restrições if (dataEValida(d,m,a) == true) { dia = d; mes=m; ano=a; } else As variáveis “d”, “m” e “a” são parâmetros (argumentos) e só podem ser manipulados dentro desse método. { dia = 0; mes=0; ano=0; } } 36 Exemplo de Escopo e Modificadores private indica que esse método só pode ser acessado através de outros métodos da própria classe. private boolean dataEValida(byte d,byte m,short a) A variáveis “validade” é uma variável local e só podem ser manipulada dentro desse método. { boolean validade = false; if ((d>=1) && (d<=31) && (m>=1) && (m<=12)) validade = true; return validade; } protected indica que esse método só pode ser acessado através de métodos dessa classe ou de classes herdeiras ou derivadas. protected void mostraData() { System.out.println(dia + “/” + mês + “/” + ano); } } 37 Programas baseados em Orientação a Objetos Programas orientados a objetos, são compostos por: conjuntos de objetos que representam os objetos existentes no negócio modelado. conjuntos de objetos que representam adequadas para a manipulação de dados. Os objetos que compõem o programa comunicam-se por trocas de mensagens. O programa precisa ter um ponto de entrada que indique à máquina virtual onde iniciar a execução. estruturas public class Aplicacao { public static void main(String[] s) { } } 38 Aplicações em Java public static void main(String[] args) public: é visível para qualquer outra classe. static: dispensa a criação de objetos. void: nenhum retorno esperado. main: convenção para indicar a máquina virtual qual o ponto de entrada da aplicação. String[] args: parâmetros passados pela aplicação via linha de comando. args é o identificador. 39 Exemplo de uma Aplicação public class Aplicacao { private Ponto p1,p2; } Declaração de objetos da classe Ponto como atributos. public void moverPontos() Utilização do método mover da classe { p1.mover(4F,2F); Ponto, através do objeto p1. p2.mover(-2F,-4F); } public void criarPontos() Instância de um objeto da classe Ponto { p1 = new Ponto(); p2 = new Ponto(); } public void rodar() Método principal, que será executado { criarPontos(); inicialmente pela máquina virtual Java. moverPontos(); } public static void main(String[] s) { Aplicacao ap = new Aplicacao(); ap.rodar(); } Criação de um objeto da própria classe 40 Exemplo de uma Aplicação public class Ponto { private float x; Declaração de variáveis do tipo primitivo float como atributos. private float y; public void mover(float novoX, float novoY) { x = novoX; y = novoY; } } 41 Operador new new instancia um novo objeto. new aloca o espaço necessário para armazenar o estado do objeto e uma tabela para indicar o corpo do código necessário para efetuar suas operações. new executa as tarefas de inicialização do objeto conforme o seu Construtor. new ‘retorna’ o identificador do objeto criado e o operador de atribuição é utilizado para copiar este endereço para uma variável, que servirá para futuras referências ao objeto. O compilador e a máquina virtual Java verificam o tipo da variável e o tipo da referência retornada. 42 Garbage Collection Gerenciador de memória para aplicações java. Thread chamada Automatic Garbage Collector. Retorna a memória ocupada por objetos que não estão mais sendo usados. Monitora a criação de objetos através do new. Cria um contador de referência para cada objeto. Libera a memória quando o contador chegar a zero. 43 Referência nula Objetos armazenam uma referência nula até serem inicializados. A referência nula é representada pela palavra reservada null. Pode-se desfazer uma referência para um objeto atribuindo a ela a palavra null. 44 Primitivas e Referências Variáveis de tipos primitivos armazenam um valor Na declaração aloca-se espaço na memória suficiente para o armazenamento da variável. Variáveis de tipos referências identificadores para objetos armazenam Na declaração aloca-se espaço para a referência ao objeto. A alocação do objeto é realizada através do operador new. 45 Construtores Já vimos que podemos criar aplicações que utilizam instâncias de classes definidas pelo usuário ou já existentes. Após criar a instância da classe com a palavra-chave new, usamos métodos para inicializar os campos da instância. Na declaração aloca-se espaço para a referência ao objeto. Por esquecimento, um programador pode criar a instância de uma classe mas não inicializar seus dados. 46 Construtores Construtor é um tipo especial de membro de classe chamado automaticamente quando instâncias são criadas através da palavra chave new. Construtores são úteis para: inicializar os atributos de uma classe; realizar rotinas complexas de inicialização; realizar inicializações segundo parâmetros passados no momento da criação do objeto. 47 Construtores Na declaração de um construtor deve-se considerar que: Construtores devem ter exatamente o mesmo nome da classe; Construtores não possuem tipo de retorno, nem mesmo void; Construtores são, normalmente, públicos. Programador não pode chamar construtores diretamente; 48 Construtores Toda classe possui um construtor. Caso o programador não forneça uma versão explícita do construtor, Java utiliza uma versão de construtor implícita que não recebe nenhum parâmetro. Se o programador fornecer um construtor a uma classe, a linguagem não mais incluirá o construtor padrão implícito. 49 Construtores - Exemplo public class Empregado { String Nome, Endereço, CPF; float Salário; int Idade; public Empregado ( String N, String End, String cpf, int Ida) { Nome = N; Endereço = End; Construtor da classe Empregado. CPF = cpf; Observe que não foi definido um tipo de retorno e possui o mesmo Idade = Ida; nome da classe. } public String InformarCPF( ) { return CPF; } public String ApresentarNome( ) { return Nome; } } 50 Construtores - Exemplo Utilização do Construtor da class CriaEmpregado classe Empregado para { public static void main(String args[]) instanciar um objeto. { Empregado obj = new Empregado(“Maria Silva”, “Rua X nº 246", "403.234.567Nome do Objeto Nome33",58); da classe System.out.println("O nome é = ” +obj.ApresentarNome()); System.out.println("O CPF é = "+ obj.InformarCPF()); System.out.println("A idade é = .DevolveIdade()); } } 51 Saída de Dados Padrão Representada por um atributo estático da classe System System.out.println(...) Tipos primitivos podem ser concatenados a Strings através do operador + Exemplo: class saidaDados { public static void main (String args[]) { System.out.println(“saida de dados”); } } 52 Entrada de Dados Padrão Toda a classe que for se utilizar de entrada de dados via teclado deve utilizar o package Java.io.*. Esse pacote contêm as classes que tratam de entrada de dados. import java.io.* Para obter valores do teclado em uma classe Java é necessário criar um objeto da classe BufferedReader. BufferedReader obj = new BufferedReader(new inputStreamReader(System.in)); Todo a entrada de dados está sujeita a erros, já que fica a mercê da digitação do usuário final. A forma mais simples de se tratar essa exceção é solicitar que a exceção não seja tratada localmente através da linha de comando: throws java.io.IOException 53 Conversão de String para tipos primitivos O Java só permite a entrada de Strings, desta forma, para que possamos informar valores numéricos é necessário fazer uma conversão de String para o tipo numérico desejado, como podemos ver a seguir: A variável line é uma String. Conversão de String para inteiro int i = Integer.valueOf(line).intValue(); Conversão de String para long long l = Long.valueOf(line).longValue(); Conversão de String para float float f = Float.valueOf(line).floatValue(); Conversão de String para double double d = Double.valueOf(line).doubleValue(); 54 Exemplo de Entradas e Saídas de Dados import java.io.*; class soma { public static void main (String args[ ] ) throws java.io.IOException { String aux; int a, b; BufferedReader obj = new BufferedReader(new InputStreamReader (System.in)); System.out.println("Digite o primeiro número: "); aux = obj.readLine(); a = Integer.valueOf(aux).intValue(); System.out.println("Digite o segundo número: "); aux = obj.readLine(); b = Integer.valueOf(aux).intValue(); a = a + b; System.out.println("O resultado é : " + a); } } 55 Operadores Relacionais e Lógicos Operadores Relacionais < (menor) > (maior) <= (menor ou igual) >= (maior ou igual) == (igual) != (diferente) Operadores Aritméticos && (E lógico) || (OU lógico) ! (NÃO lógico) • Operadores relacionais para a classe String equals !equals if (nome.equals(“Maria”) if (!nome.equals(“Maria”) 56 Estrutura de Decisão e Controle - Comandos if – else Estrutura do Comando if (expressão_booleana ) { bloco de comandos do if; } [else] { bloco de comandos do else; } • Observações: • O comando else é opcional. • Na construção de if’s aninhados, o else refere-se sempre ao if mais próximo. Procure usar chaves para delimitar os blocos. • O operador de comparação igual a é representado por == e não por =. • Bloco de comandos pode ser um único comando (terminado por ponto-e-vírgula) ou vários comandos (delimitados por {}). • É indispensável o uso de parênteses ( ) na expressão_booleana. 57 Estrutura de Decisão e Controle - Comandos switch switch(variávelDeControle) { case constante1: bloco1; Estrutura do Comando break; case constante2: bloco2; break; [default: bloco3; break;] } • Observações: • Usual para selecionar alguma ação de um número de alternativas. • A variável de controle só pode ser inteira ou char. • O case define o ponto de entrada da execução. Se você quiser que só um bloco de declarações seja executado use break. 58 • A opção default é opcional. Estruturas de Repetições - Comandos while while (expressão_booleana) { Bloco de comandos; Estrutura do Comando } • Observações: • É indispensável o uso de parênteses ( ) na expressão_booleana. •O laço permanece em execução enquanto a expressão_booleana for verdadeira. • Um erro comum é não atualizar as variáveis de controle do laço, o que acarreta um loop infinito. • Outro erro freqüente é colocar o ponto e vírgula após o while. A fase de atualização das variáveis de controle ficam fora do laço, gerando um loop infinito. • Use sempre chaves para delimitar o Bloco de comandos. 59 Estruturas de Repetições - Comandos do - while do { Bloco de comandos; Estrutura do Comando } while (expressão_booleana); • Observações: • É semelhante ao comando while, sendo que a condição de parada do laço é testada após o bloco de comandos. • Pelo menos uma vez o bloco de comandos será executado. • Observe as mesmas considerações do comando while. 60 Estruturas de Repetições - Comandos for for(inicialiazação; terminação; iteração) { bloco de comandos; } Estrutura do Comando • Observações: • Num loop for é explicita as quatro partes de uma iteração. • Um erro comum é colocar o ponto e vírgula após o for, ficando o bloco de comandos fora do laço. O resultado é um loop que nada realiza. 61 Exemplos das Estruturas de Decisão e Repetição public class exemploCondicaoRepeticao { public static void main (String args[]) { double valor = 1; char letra='A'; int contador; while(valor <= 20) { System.out.println(valor); valor = valor * 2; if (valor >= 20) { System.out.println("Fim da exemplificação do while e if"); } } for (contador=0; contador < 10; contador++) { System.out.println(contador); } System.out.println("Fim da exemplificação do for"); 62 Exemplos das Estruturas de Decisão e Repetição do { switch (letra) { case 'A' : System.out.println(letra + " é uma vogal"); break; case 'E' : System.out.println(letra + " é uma vogal"); break; case 'I' : System.out.println(letra + " é uma vogal"); break; case 'O' : System.out.println(letra + " é uma vogal"); break; case 'U' : System.out.println(letra + " é uma vogal"); break; } letra++; } while (letra != 'Z'); System.out.println("Fim da exemplificação do switch e do-while"); } } 63 Sobrecarga Um método pode ter o mesmo nome que outro método na mesma classe; Isto é usual quando existem duas ou mais formas diferentes de se realizar a mesma tarefa; Neste caso sobrecarregado; diz-se que o método está Java permite a criação de métodos com nome iguais, contanto que as assinaturas sejam diferentes; A assinatura é composta do nome mais os tipos de argumento. O tipo de retorno não faz parte da assinatura; Diferenças do tipos dos parâmetros é que definem assinaturas diferentes. 64 Sobrecarga Java admite também, que se sobrecarregue os construtores de uma classe. As restrições são similares àquelas aplicadas aos métodos sobrecarregados Deve-se se referir de dentro de um construtor sobrecarregado para outro, através do uso da palavra reservada this. 65 Exemplo de Sobrecarga class criaEmpregado { public static void main(String args[]) As chamadas dos métodos sobrecarregados estão apresentadas em negrito. { Empregado emp1 = new Empregado("Maria","123123123", "Rua das flores 245", 25,500); System.out.println("A idade de Maria é = "+ emp1.DevolveIdade()); System.out.println("A idade de Maria daqui a 10 anos e = " + emp1.DevolveIdade(10)); Empregado emp2 = new Empregado("Tadeu",700); System.out.println("O salário de Tadeu é = "+emp2.salario); } } 66 Exemplo de Sobrecarga public class Empregado { String nome, endereco, cpf; float salario; int idade; public Empregado ( String n, String end, String c, int ida, float sal) { this(n, sal); endereco=end; cpf=c; idade=ida; Uso da referência this para chamar o outro construtor. } public Empregado (String n, float sal) { nome = n; salario = sal; } public int DevolveIdade() As sobrecargas estão representadas em negrito. { return idade; } public int DevolveIdade(int numAnos) { return idade+numAnos; } } 67 A referência this Na chamada dos métodos de uma classe, a máquina virtual passa implicitamente como parâmetro uma referência ao objeto ao qual a mensagem foi enviada. Quando se deseja recuperar esta referência de dentro do corpo da classe, usa-se a palavra reservada this. Pode-se ainda utilizar a palavra chave this para se referir a um construtor sobrecarregado, como vimos anteriormente. Entretanto, neste caso, a palavra chave não diz respeito à referência do objeto, visto que este ainda está sendo criado. 68 A referência this Resumindo a referência this é usada para: Referência ao próprio objeto. Acesso dados e métodos na instância de um objeto. Passar o objeto como parâmetro. Classe principal para a exemplificação do uso da referência this public class ExemploThis { public static void main(String args[]) { Funcionario func1 = new Funcionario("Maria",500); Funcionario func2 = new Funcionario("João",700); func1.salario = func1.ajustaSalario(20); func2.salario = func2.ajustaSalario(30); System.out.println("O novo salário de "+ func1.nome +" é = "+func1.salario); System.out.println("O novo salário de "+ func2.nome +" é = "+func2.salario); } } 69 Exemplo do uso da referência this public class Funcionario { String nome; float salario; public Funcionario(String n, float s) { nome = n; Uso do this como parâmetro para salario = s; referenciar o objeto corrente } public float ajustaSalario(float percentual) { float novoSalario; novoSalario = this.salario + calculo(percentual,this); return novoSalario; } Uso do this para acessar um atributo do objeto. private float calculo(float percentual, Funcionario obj) { float valorAcrescido; valorAcrescido = obj.salario * percentual / 100; return valorAcrescido; } } 70 Reutilização de Classes Um dos maior benefício que a Programação Orientada a Objeto nos proporciona é a reutilização de código. A reutilização se caracteriza pelo aproveitamento de classes e seus métodos que já estejam escritos e que já tenham o seu funcionamento testado e comprovado. A Reutilização de código diminui a necessidade de escrever novos métodos e classes gerando economia de tempo e segurança. Existe duas maneiras de conseguir esse reaproveitamento: Através de Composição ou através de Herança. 71 Composição A composição é o conceito mais usual no desenvolvimento de aplicações baseadas em Orientação a Objetos. Parte do pressuposto que uma determinada classe vai instanciar objetos de outras classes, utilizando-se do que esses objetos fazem para compor as funcionalidades da nova classe. Esse conceito pode ser visto em exemplos anteriores (classe criaEmpregado e classe exemploThis), que instanciaram objetos da classe Empregado e funcionário respectivamente. CriaEmpregado Empregado exemploThis Funcionário 72 Herança Herança é a capacidade de uma classe definir o seu comportamento e sua estrutura aproveitando definições de outra classe, normalmente conhecida como classe base ou classe pai. A herança não precisa ser interrompida na derivação de uma camada de classes. A coleção de todas as classes que se estendem de um pai comum chama-se hierarquia de herança. A palavra reservada extends é que define que uma classe está herdando de outra. Empregado Gerente Secretária Analista de Sistemas 73 Herança Através do mecanismo de herança é possível definirmos classes genéricas que agreguem um conjunto de definições comuns a um grande número de objetos (Generalização). A partir destas especificações genéricas podemos construir novas classes, mais específicas, que acrescentem novas características e comportamentos aos já existentes (Especialização). Funcionário Gerente Gerente de Banco Gerente de Empresas • codBanco • codAgência • codSetor • nome • salário Secretária Analista de Sistemas • idiomas • linguagem 74 Herança e a referência super A palavra reservada super, nos possibilita: referência a classe base (pai) do objeto; acesso a variáveis escondidas (shadow), ou seja, variáveis de uma classe que tem o mesmo nome de uma variável definida em uma subclasse; acesso a métodos que foram redefinidos, ou seja, métodos que possuem a mesma assinatura na classe Pai e na classe derivada; utilização pela classe derivada do construtor da classe pai. 75 Exemplo de Herança Classe Pai public class Automovel Declaração de { public static final byte movidoAGasolina = 1; constantes. public static final byte movidoAAlcool = 2; public static final byte movidoADiesel = 3; private static final byte numeroMaximoDePrestacoes = 24; private String modelo; private String cor; private byte combustivel; Atributos Construtor public Automovel(String m, String c, byte comb) { modelo = m; cor = c; combustivel = comb; } public byte quantasPrestacoes() { return numeroMaximoDePrestacoes; } 76 Exemplo de Herança public float quantoCusta() { float preco = 0; switch (combustivel) { case movidoAGasolina: preco = 12000.0f; break; case movidoAAlcool: preco = 10500.0f; break; case movidoADiesel: preco = 11000.0f; break; } return preco; } public String toString() { String resultado; resultado = modelo+" "+cor+"\n"; switch(combustivel) { case movidoAGasolina: resultado += "Gasolina \n"; break; case movidoAAlcool: resultado += "Álcool \n"; break; case movidoADiesel: resultado += "Diesel \n"; break; } return resultado; } } 77 Exemplo de Herança public class AutomovelBasico extends Automovel { private boolean retrovisorDoLadoDoPassageiro; private boolean limpadorDoVidroTraseiro; private boolean radioAMFM; Atributos A palavra extends é que determina que AutomovelBasico herda de Automovel. public AutomovelBasico (String m, String c, byte comb, boolean r, boolean l, boolean af) { super(m,c,comb); A palavra super, indica retrovisorDoLadoDoPassageiro = r; que deve ser usado o limpadorDoVidroTraseiro = l; construtor da classe Pai. radioAMFM = af; } public AutomovelBasico (String m, String c, byte comb) { super(m,c,comb); retrovisorDoLadoDoPassageiro = true; limpadorDoVidroTraseiro = true; radioAMFM = true; } 78 Exemplo de Herança public float quantoCusta() Os dois métodos { float preco = super.quantoCusta(); apresentados nessa if (retrovisorDoLadoDoPassageiro == true) transparência possuem a preco = preco + 280; mesma assinatura da classe if (limpadorDoVidroTraseiro == true) Automovel, o que caracteriza uma redefinição preco = preco + 650; de métodos da classe Pai. if (radioAMFM == true) preco = preco + 190; return preco; A palavra super, indica que deve ser chamado o método } quantoCusta() e toString() da public String toString() classe Pai. { String resultado = super.toString(); if (retrovisorDoLadoDoPassageiro == true) resultado += "Com retrovisor do lado direito \n"; if (limpadorDoVidroTraseiro == true) resultado += "Com limpador traseiro \n"; if (radioAMFM == true) resultado += "Com radio \n"; return resultado; 79 }} Exemplo de Herança Instância de um objeto da classe Automovel. public class DemoAutomovel { public static void main(String arg[]) { Automovel a = new Automovel("Fusca","verde", Automovel.movidoAAlcool); System.out.println(a.toString()); Instância de um objeto da System.out.println(a.quantoCusta()); classe AutomovelBasico. System.out.println(a.quantasPrestacoes()); AutomovelBasico ab = new AutomovelBasico("Corsa","cinza", Automovel.movidoAGasolina,true,true,false); System.out.println(ab.toString()); System.out.println(ab.quantoCusta()); System.out.println(ab.quantasPrestacoes()); } } Observe que o método quantasPrestacoes() está sendo acessado através de um objeto da classe AutomovelBasico. Isso só é possível porque a classe AutomovelBasico herda da classe Automovel, assim todos os atributos e métodos da classe Pai podem ser usados pela classe derivada. 80 Polimorfismo O mecanismo de herança permite a criação de classes a partir de outras já existentes com relação é-um-tipode, de forma que, a partir de uma classe genérica, classes mais especializadas possam ser criadas. A relação é-um-tipo-de entre classes permite a existência de outra característica fundamental de linguagens OO, o polimorfismo. Polimorfismo (“muitas formas”) permite a manipulação de instâncias de classes que herdem de uma mesma classe ancestral de forma unificada. Podemos escrever métodos que recebam instâncias de uma classe C, e os mesmos métodos serão capazes de processar instâncias de qualquer classe que herde de C, já que qualquer classe que herde de C é-um-tipo-de C. 81 Polimorfismo Vantagens do uso do Polimorfismo: Permite o envio de mensagens a um objeto sem a determinação exata do seu tipo; Permite a extensibilidade do sistema com pouco ou nenhum impacto nas classes existentes; Permite a construção de classes genéricas para efetuar tarefas gerais comuns aos softwares, como as estruturas de dados. 82 Exemplo de Polimorfismo public class ConcessionariaDeAutomoveis { public static void main(String args[]) { Automovel a1 = new Automovel("Fiat","bege", Automovel.movidoAAlcool); AutomovelBasico a2 = new AutomovelBasico("Corsa","cinza", Automovel.movidoAGasolina); imprime(a1); O método imprime recebe um objeto da classe Automovel imprime(a2); como parâmetro. Observe que nesse exemplo, chamamos o } método passando a1 e a2, ou seja, objetos de classes diferentes mas da mesma hierarquia de classes, caracterizando dessa forma a utilização de polimorfismo. public static void imprime(Automovel a) { System.out.println(“Dados do automóvel escolhido : "); System.out.println(a.toString()); System.out.println("Valor : "+a.quantoCusta()); System.out.println(a.quantasPrestacoes()+" prestações de "+ (a.quantoCusta()/a.quantasPrestacoes())); } } 83 Classes Abstratas São classes compostas por implementações genéricas e especificações de procedimentos. Como não são totalmente implementadas, não produzem instâncias, ou seja, não podemos criar objetos dessas classes. Elas agrupam características e comportamentos que serão herdados por outras classes e fornecem padrões de comportamento que serão implementados nas subclasses. A classe passa a servir como modelo genérico para as classes que serão dela derivadas. Para se definir classes abstratas usa-se a palavra chave abstract. 84 Classes Abstratas Um método abstrato será apenas o molde de uma implementação a ser provida pelas classes filhas concretas. Cada classe filha poderá prover implementação de uma forma particular. sua Métodos abstratos só podem existir em classes abstratos. Métodos que não são abstratos podem ser usados normalmente pelos objetos das classes que derivam da classe abstrata. As classes que derivarem de um classe abstrata devem obrigatoriamente implementar todos os 85 métodos abstratos definidos na classe Pai. Exemplo de Classes Abstratas abstract class Figura { int x; // coordenada x int y; // coordenada y Definição da classe abstrata, através da palavra abstract. public Figura (int x1, int y1) { x = x1; y = y1; } public abstract void desenha(); public abstract void apaga(); A classe pode ter um construtor, mesmo que não possa instanciar objetos. Declaração dos métodos abstratos. Esses métodos devem obrigatoriamente ser implementados nas classes derivadas. public void move (int x1, int y1) { apaga(); x = x1; y = y1; Declaração de um método desenha(); normal que poderá ser } utilizado pelos objetos de } classes derivadas. 86 Exemplo de Classes Abstratas class Quadrado extends Figura { public Quadrado(int x1, int y1) { super(x1, y1); } Utilização do construtor da classe Pai. Implementação obrigatória dos métodos definidos na classe abstrata. public void desenha() { System.out.println("Desenhando quadrado (" + x + "," + y + ")"); } public void apaga() { System.out.println("Apagando quadrado (" + x + "," + y + ")"); } } class TesteAbstract { public static void main (String args[]) Classe { Quadrado q = new Quadrado(10,10); para testar q.desenha(); o exemplo. q.move(50,50); q.apaga(); } } 87 Interfaces Se uma classe é definida por apenas métodos abstratos então é melhor não usar a palavra-chave abstract. Para estes caso o Java fornece uma técnica chamada de interfaces que pode ser usada para definir um modelo de comportamento. As interfaces diferem dos métodos abstratos no fato de que nenhum método da interface pode ter um corpo. As interfaces são estritamente modelos. As interfaces não podem ser instanciadas. Uma classe pode implementar várias interface mas apenas herda (extends) de uma única classe. As Interfaces são compiladas da mesma forma que uma classe. 88 Interfaces Uma interface é uma coleção de definição de métodos. Uma interface pode também declarar constantes. Java possui a palavra reservada interface para indicar a definição de uma interface. Sintaticamente é equivalente a uma classe completamente abstrata. Todos seus métodos são abstratos; Todas as suas variáveis são public static final; Semanticamente entretanto, as duas diferem, pois uma interface guarda uma idéia de protocolo (compromisso) entre classes. 89 Exemplo de Interfaces class Linha implements FiguraGeometrica { int x, y ; interface FiguraGeometrica { public void desenha(); public void apaga(); public void move (int x1, int y1); } public Linha(int x1, int y1) { x = x1; y=y1; } public void desenha( ) { System.out.println("Desenhando linha (" + x + "," + y + ") "); } public void apaga( ) { System.out.println("Apagando linha (" + x + "," + y + ")" ); } public void move (int x1, int y1) Nesse exemplo a classe { this.apaga(); quadrado implementa a interface figuraGeometrica e x = x1; aceita desenvolver todos os y = y1; métodos definidos pela this.desenha(); interface. } } 90 Pacotes Um package é um agrupamento de classes e interfaces que estão logicamente relacionadas. No Java é um conjunto de classes e interfaces que estão dentro de um mesmo diretório de arquivos. O Java utiliza os packages para: garantir a unicidade do nome da classe, ou seja, não permitir que existam nomes de classes iguais em um mesmo pacote; e para realizar controles de acesso; Membros de uma classe sem a especificação do controle de acesso são considerados membros que podem ser acessados pelas classes do mesmo package. 91 Pacotes Para colocar uma classe em um determinado pacote, deve-se colocar a palavra reservada package na primeira linha de código do arquivo fonte (*.java). package java.lang; Para utilizar classes definidas em outros pacotes deve-se importar as classes através da palavra chave import. Importa apenas a import java.lang.String; ou ainda import java.lang.*; classe String Importa todas as classes do package lang 92 Principais Pacotes da Linguagem Java java.applet Classes para criação de Applets. java.awt Classes para criação de interfaces gráficas. java.io Classes para gerenciamento de Entradas e Saídas. java.lang Classes Básicas da linguagem (incluídas automaticamente, não necessita o uso do import). java.net Classes para trabalho em rede. java.util Classes de utilitários (Data, Dicionário, Pilha, Vetor, Random, etc.) java.sql Classes para manipulação de Banco de Dados 93 Tratamento de Exceções Uma exceção é um evento que ocorre durante a execução do programa, que foge à normalidade do fluxo de instruções. Linguagens que tratam adequadamente as exceções têm a vantagem de separar a lógica da aplicação do tratamento de erros. Exceções são ocorrências desenvolvedor da aplicação. tratáveis pelo Quando uma exceção acontece pode-se: emitir exceção para o método chamador, através do comando throws; capturar e tratar através dos comandos try, catch e finally. 94 Emitindo Exceções Os métodos podem emitir exceções de forma explícita. Um método pode declarar que é capaz de emitir uma exceção, usando para isso a cláusula throws. Ao emitir uma exceção está se considerando que o método chamador irá tratar a exceção. Caso o método chamador não trate a exceção será apresentado um erro no console do computador e a aplicação pode parar de rodar. No próximo exemplo, caso seja digitado uma letra em lugar de um número, a máquina virtual Java emite um erro e para a execução da aplicação. 95 Exemplo de Emissão de Exceções import java.io.*; class RepassandoExcecoes { public static void main(String args[]) throws java.io.IOException { float n=0; String line; BufferedReader in = new BufferedReader(new I nputStreamReader(System.in)); System.out.println("Digite um número: "); line = in.readLine(); n = Float.valueOf(line).floatValue(); System.out.println("O número digitado foi: " + n); } } Caso ocorra uma exceção na digitação do número, a última linha da aplicação não será executada. 96 Capturando Exceções Para capturar exceções coloque o trecho que pode originar a exceção num bloco try. Manipule cada exceção num bloco catch. Podem existir vários catch para um único try, já que num único bloco try podem ocorrer tipos de exceções diferentes. Realize procedimentos obrigatórios e comuns num bloco finally. try{ //origina a //exceção } catch(exception1){ //manipula exc1 } catch(exception2){ //manipula exc2 } finally { //proc. //obrigatórios } 97 Exemplo de Captura de Exceções import java.io.*; class CapturandoExcecoes { public static void main(String args[]) { float n=0; boolean ok = true; BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); No try é colocado o código que poderá gerar exceções. try { System.out.println("Digite um número: "); line = in.readLine(); n = Float.valueOf(line).floatValue(); } 98 Exemplo de Captura de Exceções No catch é colocado o tratamento da exceções caso ocorra. Exception é o identificador de System.out.println("Problema na conversão"); exceção default. Existe um ok = false; específico para cada tipo de No finally é colocado o código que será exceção. executado ocorrendo ou não uma exceção. catch (Exception e) { } finally { System.out.println("Exemplo de captura de exceções"); } if (ok == true) System.out.println("O número digitado foi: " + n); } } 99 Vetores Um vetor (array) é uma seqüência de objetos ou valores de tipos primitivos, todos do mesmo tipo e combinados sob um único identificador. Vetores são estáticos. O seu tamanho é definido no momento da sua criação. Em Java, vetores são objetos. Na prática, eles herdam de Object. Arrays possuem um atributo público que informa o seu tamanho: length. Arrays em Java iniciam na posição (índice) 0. 100 Vetores Declaração: Exemplos: tipo[] identificador; int[] vet; Button[] b; Declaração de um vetor de tipo primitivo. Declaração de vetor de objeto. um Construção: identificador = new tipo[tamanho] Exemplo: vet = new int[12]; b = new Button[10]; Inicialização: Observe que um vetor pode ser declarado, construído e inicializado ao mesmo tempo. int vet = new int { 0,1,2,3,4,5,6,7,8,9,10,11}; 101 Exemplo da utilização de Vetores Esse exemplo mostra os meses e a quantidade de dias que cada mês possui. class DiasDosMeses { public static void main(String[] arg) { int[] maxDiasMes = new int[12]; String[] nomeMes = {"JAN", "FEV", "MAR", "ABR", "MAI", "JUN", "JUL", "AGO","SET", "OUT", "NOV", "DEZ"}; for(int i=0; i < maxDiasMes.length; i++) { if(((i+1 < 8) && ((i+1)%2==1)) || ((i+1 >= 8) && ((i+1)%2==0))) maxDiasMes[i] = 31; else maxDiasMes[i] = 30; } maxDiasMes[1] = 28; for(int i=0;i<12;i++) System.out.println(nomeMes[i]+":"+ maxDiasMes[i]); } } 102 Matrizes Os arrays multidimensionais funcionam de forma análoga aos arrays dimensionais. Cada dimensão é representada por um par de colchetes []. Exemplo de Matrizes class ManipulaMatriz { public static void main(String args[]) Declaração e construção { int Mat[][] = new int[5][2]; de uma matriz. for( int i=0; i < Mat.length; i++) { for( int j=0; j < Mat[0].length; j++) { Mat[i][j]= (i*2)+j; System.out.print(" Mat[ "+ i +" ] " +"[ " + j + " ] = " + Mat[i][j]); } System.out.println(“ "); } } } 103 Contribuições e Referências Bibliográficas Referências Bibliográficas: SANTOS, R. Introdução à Programação Orientada a Objetos Usando Java. 1a Edição: Editora Campus. 2003. DEITEL, H. M. e DEITEL, P. J. Java como Programar. 4a Edição: Editora Bookman. 2003. CORNELL, G. & HORSTMANN, C. S. Core Java. 2 a Edição: Makron Books. 2001. 104