Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 FACULDADE DE COMPUTAÇÃO E INFORMÁTICA BACHARELADOS EM CIÊNCIA DA COMPUTAÇÃO E SISTEMAS DE INFORMAÇÃO E TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS Linguagem de Programação I – SEMANA 04 TEORIA: OBJETOS E CLASSES Nossos objetivos nesta aula são: Formalizar o conceito de objeto em sob o ponto de vista de programação Aprender o processo de construção de objetos em Java Aprender o mecanismo de referência a objetos e o processo de garbage collection em Java Aprender o conceito de estado de um objeto e sua alteração através da invocação de métodos Aprender a diferença entre métodos de acesso e métodos modificadores. Conhecer e implementar a estrutura geral de uma classe em Java (atributos, construtores e métodos) A referência para esta aula é o Capítulo 2 (Utilizando Objetos) e o Capítulo 3 (Implementando Classes) do nosso livro-texto: Horstmann, C. Conceitos de Computação com Java. 5.ed. Porto Alegre: Bookman, 2009. Não deixem de estudar este capítulo antes e após a aula de hoje! Para acessar a versão eletrônica deste livro: Acesse o link da Biblioteca Virtual MINHA BIBLIOTECA (https://www3.mackenzie.com.br/biblioteca_virtual/index.php?tipoBiblio=minhabiblioteca&flashObg=n) Faça o login conforme as instruções apresentadas na tela. Faça a busca fornecendo os dados do livro. OBJETOS E MÉTODOS Um objeto é uma entidade que você pode manipular no seu programa. Normalmente, não sabemos como um objeto é organizado internamente, mas ele tem um comportamento bem-definido e é isto que importa quando o utilizamos. Abaixo, temos a representação de dois objetos construídos a partir da classe String: 2 Os objetos foram construídos conforme trecho de código abaixo: String greeting = “Hello, World!”; int n = greeting.length(); // tamanho da string String river= “Mississippi”; String bigRiver = river.toUpperCase(); // converte os caracteres para maiúsculos A manipulação de objetos é feita através da invocação de seus métodos. Um método é uma sequência de instruções que pode acessar os dados internos de um objeto. No exemplo acima, temos dois métodos que podem ser invocados: length() e toUpperCase(). Podemos invocar esses métodos porque eles pertencem à interface pública da classe String. A interface pública de uma classe especifica o que você pode fazer com os objetos dela. Objetos são construídos a partir de classes. No exemplo anterior, dizemos que greeting é um objeto da classe String. Uma classe define os métodos que você pode aplicar aos objetos dela, podemos invocar os métodos length() e toUpperCase() porque eles pertencem à interface pública da classe String. A interface pública de uma classe especifica o que você pode fazer com os objetos dela. EXERCÍCIO TUTORIADO Identifique, no trecho de código abaixo, os objetos, as classes e os dois métodos que estão sendo invocados: String greeting = “Hello, World!”; System.out.println (greeting); int n = greeting.length(); System.out.print (n); 3 PARÂMETROS DE MÉTODOS E VALORES DE RETORNO Os métodos que podemos utilizar em um objeto podem ter parâmetros e retornos. Um parâmetro funciona como uma entrada para um método, enquanto que o retorno é a saída do método, ou seja, é o resultado que o método calculou para uso no código que o invocou. Podemos saber quais são os parâmetros e os retornos de um método observando a sua definição dentro da classe. Por exemplo, a classe String define o método length() como: public int length() que não possui nenhum parâmetro de entrada, mas tem um retorno do tipo int. Por exemplo, na chamada System.out.println(“Hello, World”); temos a string “Hello World” funcionando com um parâmetro para o método println do objeto System.out. A string “Hello, World” é um parâmetro explícito do método println. O objeto em que você invoca o método também é considerado um parâmetro da chamada do método e, é denominado parâmetro implícito. Assim, System.out é o parâmetro implícito da chamada do método println. Portanto, o parâmetro implícito de uma chamada de método é o objeto em que o método é invocado. Já, na invocação int n=greeting.length(); da página anterior, não temos parâmetro explícito na invocação, mas temos um valor de retorno (int) e o parâmetro implícito greeting. O retorno de invocação de um método pode ser utilizado como parâmetro para invocação de um outro método, como no exemplo System.out.println(greeting.length()); 4 EXERCÍCIO TUTORIADO Quais são os parâmetros implícitos, os parâmetros explícitos e os valores de retorno na chamada do método river.length() e como o método toUpperCase é definido na classe String? CONSTRUÇÃO DE OBJETOS O processo de criação de um objeto a partir de sua classe é chamado instanciação. Assim, é comum dizermos que um objeto é uma instância de uma classe. No processo de instanciação, alocamos espaço em memória para o objeto com o operador new e inicializamos este espaço de memória com os parâmetros passados ao processo de instanciação. A sintaxe do processo de instanciação em Java é mostrada abaixo: NomeDaClasse objeto = new NomeDaClasse(parâmetros); Exemplos: String s = new String (“Maria”) ; // ou, abreviadamente, String s=”Maria”; Observe, em particular, que pode haver mais de uma maneira de se construir um objeto. É importante observar, também, que o operador new não aparece sozinho. Ele necessita de um método especial especificado pela classe chamado construtor. O construtor, em Java e em várias outras linguagens orientadas a objetos, deve sempre ter o mesmo nome da classe. Uma mesma classe pode definir vários construtores diferentes, por exemplo da classe String: 5 String () Constrói uma string vazia, isto é, sem caracteres. String (byte[] bytes) Constrói uma string a partir de um vetor de bytes. String (char[] value) Constrói uma string a partir de um vetor de caracteres. String (String original) Constrói uma string a partir outra string. String (StringBuffer buffer) Constrói uma string a partir de um StringBuffer. String (StringBuilder builder) Constrói uma string a partir de um StringBuilder. EXERCÍCIO COM DISCUSSÃO EM DUPLAS As classes e métodos da biblioteca de classes da linguagem Java estão definidos na documentação da API (Application Programming Interface) Java. A documentação da API da versão 8 da linguagem Java pode ser encontrada em: http://docs.oracle.com/javase/8/docs/api/ Desta documentação, vamos considerar a classe Rectangle mostrada parcialmente abaixo: 6 É muito importante que você entenda essa distinção. No computador, um objeto Rectangle é um bloco de memória que armazena quatro números, por exemplo, x = 5, y = 10, largura = 20, altura = 30. Na imaginação do programador que usa um objeto Rectangle, esse objeto descreve uma figura geométrica. A partir desta documentação, construa um retângulo chamado box que tenha canto superior esquerdo na coordenada (5,10), comprimento 20 e altura 30. Agora, com base na documentação do método translate() da classe Rectangle, faça uma translação do retângulo criado no exercício anterior de 15 pixels para a direita no eixo X e 25 pixels para baixo no eixo Y. Diga também quais são os parâmetros implícitos e explícitos do método bem como o valor de retorno. 7 MÉTODOS DE ACESSO E MODIFICADORES Um método que acessa um objeto e retorna algumas informaçõessobre ele, sem alterá-lo, é chamado de método de acesso. Já um método cujo propósito é modificar o estado de um objeto é chamado de método modificador. Por exemplo, o método length() da classe String é um método de acesso, ele retorna informações sobre uma String, a saber, o seu comprimento, mas ele não modifica a String ao contar os caracteres. Outro exemplo, a classe Rectangle tem alguns métodos de acesso, getX(), getY(), getWidth() e getHeight(). O método translate() da classe Rectangle é um método modificador porque altera o objeto parâmetro implícito. REFERÊNCIAS A OBJETOS E GARBAGE COLLECTOR Em Java, uma variável cujo tipo é uma classe, na verdade não contém um objeto. Ela contém meramente a posição de um objeto na memória. O objeto em si é armazenado em uma outra parte. No nosso último Exercício Tutoriado, criamos um objeto da classe Retângulo com o seguinte código: Rectangle box = new Rectangle(5,10,20,30); Eis o que acontece em detalhe: o O operador new cria um objeto Rectangle. o Usa os parâmetros (nesse caso,5,10,20 e 30)para inicializar os dados do objeto. o Retorna o objeto. Mais profundamente, o operador new retorna o endereço de memória, chamado referência, dentro da JVM (Java Virtual Machine) onde foi alocado o objeto. Este endereço é armazenado dentro da variável que nomeamos o objeto. No exemplo acima, box. Assim, o acesso ao objeto criado é feito de forma indireta via o endereço (referência) armazenado na variável que nomeia o objeto. Isto é também conhecido, em outras linguagens, como ponteiro (ou pointer). Ponteiros são alocados dentro uma região especial 8 de memória chamada HEAP e o processo de alocação de memória nesta região é chamada alocação dinâmica. Se apenas definirmos o objeto, mas não o alocarmos, o valor da referência é null. Por exemplo, na declaração Rectangle r; r terá valor inicial igual a null; Um mesmo objeto criado por ser referenciado por mais de uma variável. Por exemplo: Rectangle box = new Rectangle(5,10,20,30); Rectangle box2 = box; Neste caso, inicialmente criamos um objeto e o referenciamos com a variável box. Em seguida, indicamos que box2 (que também é um Rectangle) possui a mesma referência que box, ou seja, as duas variáveis “apontam” para o mesmo endereço de memória. Para que um objeto continue alocado na memória, ele precisa ter, pelo menos, uma variável que o referencie. Objetos que não possuem referência são considerados lixo (garbage) de memória e, de tempos em tempos, são desalocados de memória em Java pelo coletor de lixo (Garbage Collector). Este processo é automático. Agora, como o Garbage Collector sabe quais espaços ele pode desalocar de memória ? Por exemplo, vamos considerar a seguinte sequência de criação de objetos da classe Rectangle: Rectangle box = new Rectangle(5,10,20,30); Neste instante, temos a seguinte configuração de memória: 9 Se, em seguida, criarmos um novo objeto da classe Rectangle box = new Rectangle(17,20,60,80); teremos uma nova configuração de memória e sem mais nenhuma referência para o primeiro objeto criado. Objetos que não possuem nenhuma referência são àqueles candidatos a serem desalocados de memória pelo Garbage Collector. ESTRUTURA GERAL DE UMA CLASSE Uma classe descreve um conjunto de objetos que têm os mesmos atributos e comportamentos. Toda classe precisa ter um nome, um conjunto de atributos (ou campos), construtores e métodos. Em Java, todos estes elementos são organizados da seguinte forma: EspecificadorDeAcesso class NomeDaClasse { atributos; //definição de construtores... EspecificadorDeAcesso NomeDaClasse( tipoDeParâmetro nomeDoParâmetro, . . . .) { corpo do construtor } // métodos... EspecificadorDeAcesso tipoDeRetorno nomeDoMétodo( T ipoDeParâmetro nomeDoParâmetro, . . . .) { corpo do método } //outros métodos e construtores ..... } 10 Com esta estrutura, dizemos que os atributos, construtores e métodos estão encapsulados em uma só estrutura chamada classe. Por convenção, em Java, escrevemos os nomes de classe sempre capitalizados (com a primeira letra sempre em maiúsculas) e atributos, construtores e métodos sempre iniciando com letras minúsculas. EXERCÍCIO TUTORIADO Suponha que teremos que desenvolver um sistema de computação gráfica e queremos começar modelando uma coordenada (x,y) , ou seja um ponto na tela. Considerando isso temos as seguintes questões: Como representar um ponto em sistema orientados a objetos? Que informações precisamos armazenar? Como testar nossa implementação? Como estamos desenvolvendo o sistema orientado a objetos, os pontos do sistema de computação gráfica devem ser representados por uma classe, basicamente as informações que a classe precisa armazenar são coordenadas x e y de um “ponto” na tela, ou seja, x e y são atributos da classe Ponto Durante a instanciação dos objetos pontos é importante que os atributos sejam inicializados. Esse processo deve ser realizado pelo construtor da classe. Um construtor em Java deve ser implementado com o mesmo nome da classe. Assim a classe Ponto ficaria conforme abaixo: public class Ponto { int x; int y; public Ponto( int x, int y ){ this.x = x; this.y = y; } public int getX(){ return x; } public int getY(){ return y; } } Lembrando que: Um construtor NÃO é um método. Algumas pessoas o chamam de um método especial, mas definitivamente não é, já que não possui retorno e só é chamado durante a construção do objeto, assim teríamos a seguinte classe Ponto. 11 Para diferenciar, dentro do construtor, as variáveis parâmetro x e y do atributo da classe x e y usamos o apontador de auto-referência this para indicar explicitamente o atributo da classe. Agora Implemente a função igual() (método estático) mostrada abaixo, que receba dois pontos como parâmetros e devolva true se os pontos são iguais ou false caso contrário. Note que implementamos a classe testaPonto para testar a função igual() public class testaPonto1 { public static void main( String args[] ){ Ponto ponto1 = new Ponto(10, 10); Ponto ponto2 = new Ponto(10, -10); System.out.println(igual(ponto1, ponto2));// saida esperada false } public static boolean igual(Ponto p1, Ponto p2){ } } Reescreva a classe Ponto para que função igual() se torne um método da classe Ponto. public boolean igual(Ponto p){ } public class testaPonto2 { public static void main( String args[] ){ } 12 Considerando a classe implemente também o método distancia() que calcula e retorna a distância entre dois objetos do tipo Ponto e o método transladar() que translada um objeto ponto. Para cada um dos métodos implemente uma classe para uma classe para testar a implementação do seu método. public double distancia( Ponto p ){ .... } public class testaPonto3 { public static void main( String args[] ){ public void transladar( int dx, int dy ){ .... } public class testaPonto4{ public static void main( String args[] ){ 13 ATIVIDADE DE LABORATÓRIO Gerenciamento do saldo de uma conta bancária Desenvolva um programa em Java para gerenciar o saldo de uma conta bancária. Neste exercício, considere somente a parte inteira dosaldo, sem o número de centavos. Os seus métodos ainda são estáticos. Ao executar o programa, o valor do saldo deverá ser inicializado com o valor zero (R$ 0) e o seu programa deverá apresentar o seguinte menu inicial: MENU INICIAL: (1) Consultar o saldo (2) Sacar (3) Depositar (4) Sair Escolha uma opção: _ Se o usuário escolher as opções de 1 a 3, o programa deverá executar a operação solicitada e voltar a apresentar o menu inicial. O programa deverá ser finalizado somente se o usuário escolher a opção 4. Se o usuário digitar uma opção diferente das opções oferecidas, o programa deverá apresentar a mensagem: Opção inválida! e voltar a apresentar o menu inicial. Consultar o saldo Se o usuário escolher a opção 1, o seu programa deverá informar o saldo imprimindo na tela uma mensagem no seguinte formato: Saldo atual: R$ <xxx> onde <xxx> é o valor do saldo. Sacar Se o usuário escolher a opção 2, o seu programa deverá solicitar o valor do saque: Digite o valor a ser sacado (em R$): _ 14 Caso o usuário digite um valor que exceda o saldo, o programa deverá apresentar na tela a mensagem: Valor de saque inválido! O seu saldo atual é de R$ <xxx>. e voltar a solicitar o valor do saque. Quando o usuário digitar um valor de saque válido, seu programa deverá debitar este valor do saldo e apresentar a mensagem: Saque de R$ <yyy> efetuado com sucesso! onde <yyy> é o valor do saque. Depositar Se o usuário escolher a opção 3, o seu programa deverá solicitar o valor do depósito: Digite o valor a ser depositado (em R$): _ Após o usuário digitar o valor do depósito, seu programa deverá acrescente este valor ao saldo e apresentar a mensagem: Depósito de R$ <zzz> efetuado com sucesso! onde <zzz> é o valor do saque. Sair Se o usuário escolher a opção 4, o seu programa deverá apresentar a mensagem: Fim do programa! e finalizar a execução. Pense sobre transformar esse programa em que trabalhe com objetos e métodos NÃO estáticos, responda: 1. Sugira o nome de uma classe que poderíamos desenvolver para gerar uma versão orientada a objetos deste programa. 2. Qual seria o atributo desta classe? 3. Quais seriam os nomes, parâmetros e tipos de retorno dos métodos desta classe? 4. Reescreva o programa anterior em uma versão orientada a objetos. 15 EXERCÍCIOS EXTRA-CLASSE 1. Explique a diferença entre um objeto e uma referência a objeto. 2. Explique a diferença entre um objeto e uma variável de objeto. 3. Explique a diferença entre um objeto e uma classe. 4. Forneça o código Java para construir os seguintes objetos: a. Um retângulo de centro (100,100) e todos os comprimentos de lado iguais a 50; b. Uma string “Hello, Alunos!” Crie objetos e não variáveis de objetos. 5. Encontre os erros nos trechos de código abaixo: a. Rectangle r = (5,10,15,20); b. double width = Rectangle(5,10,15,20).getWidht(); c. Rectangle r; r.translate(10,20); d. r=new Rectangle(); r.translate(“Muito longe”); 6. Explique a diferença entre um construtor e um método. 7. Explique a diferença entre new Rectangle (5,10,15,20); e Rectangle r = new Rectangle (5,10,15,20); 8. Como você constrói um quadrado com centro (100, 100) e comprimento de lado 20? 9. O que a instrução seguinte imprime? System.out.println(new Rectangle().getWidth()); 10. Suponha que agora precisamos representar um retângulo em POO, ou seja, um polígono cujos lados formam ângulos retos entre si e que, com os seus conhecimentos em geometria e POO, defina os seguintes itens abaixo. 1. Defina uma classe para representar o retângulo, quais informações são importantes armazenar na classe, e como poderia ser o construtor dessa classe. 2. Implemente métodos para calcular o perímetro e a área do retângulo. 3. Escreva um método para verificar se dado dois retângulos há uma intersecção entre eles. Caso haja é retornado true, ou false caso contrário. Importante: Para cada um dos itens implemente classes de testes para verificar se sua implementação está funcionando corretamente. 16 DESAFIO (PROBLEMA DE MARATONA DE PROGRAMAÇÃO) A FCC (Fábrica de Cilindros de Carbono) fabrica vários tipos de cilindros de carbono. A FCC está instalada no décimo andar de um prédio, e utiliza os vários elevadores do prédio para transportar os cilindros. Por questão de segurança, os cilindros devem ser transportados na posição vertical; como são pesados, no máximo dois cilindros podem ser transportados em uma única viagem de elevador. Os elevadores têm formato de paralelepípedo e sempre têm altura maior que a altura dos cilindros. Para minimizar o número de viagens de elevador para transportar os cilindros, a FCC quer, sempre que possível, colocar dois cilindros no elevador. A figura abaixo ilustra, esquematicamente (vista superior), um caso em que isto é possível (a), e um caso em que isto não é possível (b): Como existe uma quantidade muito grande de elevadores e de tipos de cilindros, a FCC quer que você escreva um programa que, dadas as dimensões do elevador e dos dois cilindros, determine se é possível colocar os dois cilindros no elevador. Entrada A entrada contém vários casos de teste. A primeira e única linha de cada caso de teste contém quatro números inteiros L, C, R1 e R2, separados por espaços em branco, indicando respectivamente a largura do elevador (1 ≤ L ≤ 100), o comprimento do elevador (1 ≤ C ≤ 100), e os raios dos cilindros (1 ≤ R1, R2 ≤ 100). O último caso de teste é seguido por uma linha que contém quatro zeros separados por espaços em branco. Saída Para cada caso de teste, o seu programa deve imprimir uma única linha com um único caractere: ‘S’ se for possível colocar os dois cilindros no elevador e ‘N’ caso contrário. Exemplo Entrada: 11 9 2 3 7 8 3 2 10 15 3 7 8 9 3 2 0 0 0 0 Saída: S N N S
Compartilhar