[Pesquisar este blog]

terça-feira, 23 de janeiro de 2018

POO::Fundamentos-05-Métodos

POO-F-04-Atributos POO-F-06-Sobrecarga
Sabemos que uma classe é um novo tipo de dados que pode ser definido pelo programador para descrever uma entidade real ou abstrata, ou seja, é um que especifica os objetos de um tipo determinado, por meio de uma descrição genérica de todos os elementos pertencentes ao conjunto que está sendo modelado.

Como ilustrado na figura acima, as classes possuem:
  • atributos, que descrevem as características dos objetos (sua aparência, sua constituição e seu estado); e
  • operações, que descrevem suas ações ou capacidades, realizadas sobre seus próprios atributos.
As classe são, portanto, constituídas por seus atributos (ou campos) e suas operações (ou métodos), os quais são conhecidos como membros da classe [5][6][7][8]. Assim, os atributos são as variáveis-membro e as operações são as funções-membro da classe. Portanto, uma classe incorpora o conceito de tipo abstrato de dados, que define um conjunto de valores que representam este tipo, assim como as operações possíveis sobre tais valores [10]. 

Enquanto os atributos permitem armazenar informações relativas aos objetos, os métodos (operações ou funções-membro) realizam ações sobre estes atributos, permitindo especificar modificações possíveis em um objeto. Isto significa que os métodos conferem um caráter dinâmico aos objetos, pois permitem que exibam um comportamento que, em muitos casos, pode simular ou imitar o comportamento de um objeto real.

Outra forma de entender o que são os métodos é imaginar que os objetos são capazes de enviar e receber mensagens, tais como comandos, de forma programas possam ser construídos com o uso de objetos que interagem entre sim trocando mensagens e  proporcionando o comportamento desejado. A metáfora aqui é que a ação de ligar um aparelho, acionando o controle apropriado, corresponde à mensagem "ligar". Quando realizamos esta ação no mundo real não é necessário que compreendamos os detalhes de funcionamento do aparelho em questão, mas apenas entender (superficialmente) como operá-lo.

Os métodos são funções agregadas em uma classe, ou seja, são blocos de código aos quais se associam um nome, podendo retornar um valor de tipo específico e também receber valores (seus argumentos). Os métodos encapsulam funcionalidades ou capacidades em uma classe, constituindo um repertório de operações disponíveis 'naturalmente' para seus objetos [6].

Tal como na matemática, uma função pode declarar parâmetros formais, que serão supridos pelos argumentos fornecidos no uso da função, que tem o papel de entrada de dados para a função. O valor de retorno é o resultado da função, que tem papel de saída da função. Para qualquer valor válido de entrada (domínio da função) é produzido um valor correspondente (imagem da função).

Os métodos são acionados por meio das instâncias de sua classe, ou seja, os objetos de seu tipo, produzindo resultados ou transformações nos atributos pertencentes ao objeto que os acionou, sem afetar os demais objetos da classe.

Para usarmos um método de uma classe procedemos de forma análoga ao uso de seus atributos, isto é, escolhemos o objeto através de seu identificador e com o operador seletor ('.') indicamos qual método deve ser acionado, suprindo os argumentos necessários tal como para funções, assim a chamada de um método tem a forma [4][7]:

identificadorDoObjeto.nomeDoMétodo(listaDeArgumentos)

Uma classe Caixa pode ser definida, em Java ou C# como segue, caracterizando suas dimensões e seu peso.

class Caixa {
   double altura, largura, profundidade;
   double peso;
}

Desta maneira, objetos do tipo Caixa poderiam apenas representar caixas reais, sem prover qualquer outra facilidade.

Mas seria conveniente que a classe Caixa dispusesse de uma operação para determinar seu volume, pois como esta medida está diretamente associada às dimensões do objeto, que são atributos da classe, é simples seu cálculo, não sendo necessário armazenar tal informação. Para declararmos um método em um classe basta definir uma função dentro do corpo da classe.

class Caixa {
   double altura, largura, profundidade;
   double peso;

   double volume() {
      double res = altura * largura * profundidade;
      return res;
   }
}

Devem ser observados os seguintes aspectos neste método:
  • double volume () { ... }
    representa a declaração do método, como uma função denominada volume, que retorna um resultado do tipo double. Esta função não toma (não recebe) argumentos.
  • return res;
    no código (no corpo) do método, a diretiva return tanto encerra sua execução, retornando ao ponto onde foi acionada, como permite o retorno do resultado da função.
  • double res = altura * largura * profundidade;
    no corpo do método é possível tanto declarar-se variáveis locais, cujo escopo é limitado ao corpo do método, como utilizar os atributos/campos da classe.
O método volume() adiciona uma funcionalidade/capacidade à classe Caixa, que é determinar seu próprio volume, como um serviço. O código do exemplo é simples, constituído de uma expressão algébrica, mas poderia ser bastante mais complexo, utilizando variáveis de tipo primitivo ou outros objetos para determinar seu resultado.

O programa Java que segue mostra a criação e uso de um objeto do tipo Caixa, com sua instanciação, definição de suas dimensões (uso dos atributos) e exibição do seu volume (uso do método) [7].

class TestaCaixa {
   public static void main(String[] arg) {
      // instanciação do objeto tipo Caixa
      Caixa caixa = new Caixa();
      // definição de dimensões (uso dos atributos)
      caixa.altura = 1.0;
      caixa.largura = 2.5;
      caixa.profundidade = 3.0;
      // determinação e exibição do volume (uso do método)
      System.out.println("Volume = " + caixa.volume());
   }
}

Segue o programa equivalente em C# [11]:

class TestaCaixa {
   static void main() {
      // instanciação do objeto tipo Caixa
      Caixa caixa = new Caixa();
      // definição de dimensões (uso dos atributos)
      caixa.altura = 1.0;
      caixa.largura = 2.5;
      caixa.profundidade = 3.0;
      // determinação e exibição do volume (uso do método)
      Console.WriteLine("Volume = " + caixa.volume());
   }
}

Quando executados, estes programas exibem, no console, o resultado:

> Volume = 7.5

Consideremos agora um outro problema, de natureza financeira. É sabido que o valor futuro de um investimento inicial (ou valor presente) é uma função do tempo de aplicação e da taxa de juros, como mostra a relação que segue:

ValorFuturo = ValorPresente * (1 + Juros)^Tempo

Aqui o tempo é número inteiro de períodos de incidência da taxa de juros. Se os juros são diários, o tempo é dado em dias; se os juros são mensais, o tempo é dados em meses; e assim por diante. O valor presente e os juros são valores reais.

Poderia ser modelada uma classe para armazenar o valor presente e a taxa de juros, de maneira que o valor futuro fosse calculado em função do tempo de aplicação. Analise o código Java que segue:

class Investimento {
   double valorPresente;
   double juros;

   double valorFuturo(int tempo) {
      return valorPresente * Math.pow(1 + juros, tempo);
   }
}

Na classe Investimento, o método valorFuturo toma um argumento do tipo int para ser acionado. Tal argumento, denominado tempo, funciona como uma variável local no código do método. Para acionar o método, deve ser fornecido um inteiro, como por exemplo, considerando a existência de um objeto do tipo Investimento denominado investimento:

investimento.valorFuturo(6);

Esta classe poderia ser usada como mostra o fragmento seguinte:

Investimento inv1 = new Investimento();
inv1.valorPresente = 1000.00; // Valor inicial = R$1000.00
inv1.juros = 0.01; // Juros de 1% ao mês
for(int t=1; t<=4; t++) {
    System.out.printf("Mes: %d ValorFuturo=R$%f\n", t, inv1.valorFuturo(t));
}

O resultado deste fragmento é:

Mes: 1 ValorFuturo=R$1010,000000
Mes: 2 ValorFuturo=R$1020,100000
Mes: 3 ValorFuturo=R$1030,301000
Mes: 4 ValorFuturo=R$1040,604010

Conforme a necessidade do modelo programado, podem ser definidos tantos métodos quantos necessários em uma classe, com nenhum, um ou mais argumentos, utilizando qualquer combinação dos campos da classe e, até mesmo, outros métodos da própria classe, além de variáveis locais de qualquer tipo válido.

Isto permite adicionar funcionalidades às classes, o que abre um universo de possibilidades para a programação e uso dos objetos.

POO-F-04-Atributos POO-F-06-Sobrecarga

Referências Bibliográficas

[1] JAMSA, K.; KLANDER, L.. Programando em C/C++: a bíblia. São Paulo: Makron Books, 1999.
[2] PAGE_JONES, M.. Fundamentos do Desenho Orientado a Objeto com UML. São Paulo: Makron Books, 2001.
[3] SOMMERVILLE, I.. Software Engineering. 6th. Ed. Harlow: Pearson, 2001.
[4] DEITEL, H.M.; DEITEL, P.J.. Java: como programar. 6a. Ed. São Paulo: Pearson Prentice-Hall, 2005.
[5] SAVITCH, W.. C++ Absoluto. São Paulo: Pearson Addison-Wesley, 2004.
[6] JANDL JR., P. Introdução ao C++. São Paulo: Futura, 2003.
[7] JANDL JR., P.. Java - guia do programador. 3a. ed. São Paulo: Novatec, 2015.
[8] RUMBAUGH, J.; BLAHA, M.; PREMERLANI, W.; EDDY, F.; LORENSEN, W.. Object-oriented modeling and design. Englewoods Cliffs: Prentice-Hall, 1991.
[9] STROUSTRUP, B.. The C++ Programming Language. 3rd Ed. Reading: Addison-Wesley, 1997.
[10] LANGSAM, Y.; AUGENSTEIN, M. J.; TENENBAUM, A. M.. Data structures using C and C++. 2nd Ed. Upper Saddle River: Prentice-Hall, 1996.
[11] WATSON, K.; NAGEL, C.; PEDERSEN, J.H.; REID, J.D.; SKINNER, M.; WHITE, E.. Beginning Microsft Visual C# 2008. Indianapolis: Wiley Publishing, 2008.

Nenhum comentário: