Entendendo Orientação a Objetos – Parte 2

Continuando nossa jornada no mundo da POO, vamos agora detalhar mais o conceito de classe, demonstrar exemplos específicos e iniciar a teoria sobre herança. Espero que, a partir da leitura da segunda parte deste artigo todos estejam capazes de implementar sua própria classe, então vamos ao trabalho!

Primeiramente vamos entender a estrutura de uma classe, a seguir temos um exemplo (em java) simples de uma classe Relogio que é capaz de imprimir um determinado horário.

/**  * Declaração da classe Relogio
     * @author paulocanedo */
public class Relogio {
 /** * Atributo privado do  tipo inteiro que guarda o valor do atributo hora  */
 private int hora;
 
 /** * Atributo privado do tipo inteiro que guarda o valor do atributo minuto */
 private int minuto;
 
 /** * Construtor da classe Relogio */
 public Relogio() { }
 
 /** * Método que retorna a hora e o minuto em uma String formatada no estilo hora:min
 * @return Hora e Minuto numa String formatada */
 public String getHoraMinuto() {
  return (String.format("%d:%d", hora, minuto));
 }
}

O método Relogio() tem o mesmo nome da classe por ser o método construtor, ou seja, quando uma classe é instanciada, imediatamente este método é chamado. Uma classe pode ter mais de um construtor, veremos isto um pouco mais tarde.

Os atributos hora e minuto estão com o modificador private, ou seja, estes atributos estarão visíveis apenas dentro do escopo da classe Relogio enquanto que o método getHoraMinuto(), possui o modificador public que indica que este método pode ser acessado por qualque classe. Mas… se os atributos hora e minuto possuem o modificador private e a função do método getHoraMinuto() (com modificador public) é de retornar uma string formatada contendo os atributos hora e minuto então pode haver um problema ao acessar este método? A resposta é não, isto ocorre porque o método getHoraMinuto() está na mesma classe que os atributos hora e minuto, em fim, o método getHoraMinuto() coleta as informações dos atributos e entrega para qualquer classe, agindo como uma espécie de intermediador.

Uma boa prática de programação é deixar todos os atributos de uma classe com o modificador private para dar segurança ao código. É uma forma de protegê-lo contra outros mal intencionados e até mesmo de protegê-lo contra você mesmo, sim isto é verdade, um programador destrói seu próprio código caso não tenha cuidado. Esta prática de esconder as coisas dentro da classe chama-se encapsulamento.
OK, mas uma hora eu vou precisar acessar um atributo através de outra classe, então para isso vamos utilizar os métodos chamados de get (pega o valor de um atributo) e set (define o valor de um atributo). Abaixo está um exemplo onde é mostrado a necessidade de trabalhar-se com get e set:

/**  * Declaração da classe Relogio  *
* @author paulocanedo */
public class Relogio {
 
 /** * Atributo privado do tipo inteiro que guarda o valor do atributo hora */
 private int hora;
 
 /** * Construtor da classe Relogio.
 * Atribue valor -1 ao atributo hora (indica que o valor é inválido).*/
 public Relogio() {
 this.hora = -1;
 }
 
 /** * Coleta as informações do atributo hora
  * @return Caso a hora seja válida retorna a hora contida no objeto caso contrário retorna -1 indicando valor inválido da hora.
  */
  public int getHora() {
   if(hora >= 0 && hora < = 24) {
    return hora;
   } else {
    return -1;
   }
  }
 
 /** * Define o valor da hora caso esta seja válida, caso contrário define valor -1 correspondente ao valor inválido
   * @param hora Valor inteiro correspondente a hora
   */
  public void setHora(int hora) {
   if(hora >= 0 && hora < = 24) {
    this.hora = hora;
  }
 }
}

Na declaração do método setHora(int), podemos notar a presença da palavra chave this. Esta palavra serve para explicitar que o acesso está sendo na própria classe a qual está trabalhando (e não a um escopo local). Na linha this.hora = hora indica que o atributo de classe hora está recebendo o valor da variável hora (recebida pela passagem de parâmetro). Generalizando o this obriga que o acesso seja no escopo de classe.

Outro problema que a POO veio resolver sobre a programação estruturada foi o conceito de reutilização de código. Uma das formas encontradas para sanar este problema é o uso de herança. Basicamente herança, computacionalmente falando, é a propriedade de uma classe herdar informações (ex.: atributos e métodos) de uma outra.

Mas onde usar herança? Só a experiência consegue ensinar um programador a descubrir quando usar herança, mas uma forcinha com exemplos ajuda bastante quando se está começando. Vamos supor que tenhamos que implementar uma classe para um quadrado e um retângulo. Sabemos que tanto o quadrado quanto o retângulo possuem as características de um quadrilátero, ou seja, eles herdam as características de um quadrilátero. Assim podemos ter a classe Quadrilatero sendo a classe pai e as classes Quadrado e Retangulo como suas classes filhas que herdam todas as propriedades de sua classe pai.

Para entender melhor o conceito de herança, tente pensar em coisas na natureza que sigam o conceito de herança, tente identificar as propriedades que podem ser herdadas de uma coisa para outra. Na próxima parte deste artigo, vou trazer um maior detalhamento sobre herança múltipla, modificadores static, final e protected, além de exemplos práticos para melhor compreensão. Obrigado a todos os leitores!

Entendendo orientação a objetos, parte 1

Hoje venho iniciar uma série para demonstrar o conceito de orientação a objetos dentro do mundo da programação. A POO (Programação Orientada a Objetos) foi implementanda a fim de suprir algumas deficiências do principal modelo anterior, a programação estruturada. Atualmente temos as linguagens C++ e Java como sendo as mais conhecidas no mundo da POO, entre outras que estão ganhando cada vez mais força, como python, ruby e scala, por exemplo, neste artigo teremos uma pequena direcionalização ao Java, porém todos os conceitos aqui apresentados podem ser facilmente adaptados a qualquer linguagem de programação que utilize POO.

Para começarmos com o conceito de POO vamos fazer uma pequena analogia entre programação estruturada e POO, na programação estruturada criamos nossos algoritmos no estilo “passos para executar uma receita de bolo”, você descreve passo a passo todas as operações que devem ser realizadas até que o bolo esteja pronto, já no estilo POO nós temos um paradigma um pouco mais completo, ainda considerando o exemplo do bolo, na POO teríamos um conjunto de objetos que podem ou não ter uma capacidade de executar tarefas, e com a reunião de todos os objetos conseguiríamos preparar o bolo.

A primeira coisa a qual precisa ser desmistificada na POO é o conceito de classe. Explicando da forma mais simples possível uma classe é um conjunto de atributos e métodos, mas o que são atributos e métodos? Os atributos de uma classe são as características que esta pode assumir, suas personificações. Os métodos são semelhantes às funções comuns que estamos acostumados na programação estruturada, com a diferença que os métodos são funções particulares de cada classe, ou seja, um método é uma operação que determinada classe é capaz de executar.

Vamos pensar em exemplos para facilitar o compreendimento do que é uma classe. Podemos assumir no mundo da POO que uma pessoa é uma classe, se uma pessoa é uma classe e que esta classe tem alguma utilidade então esta deve possuir pelo menos um atributo ou um método, vamos analisar o que pode ser atributo e o que pode ser método na classe pessoa. Vamos pensar, quais são as caraterísticas de uma pessoa? Tente descrever as características de você mesmo: meio alto, magro, cabelos pretos, inteligente, rápido, todas estas características são consideradas atributos de uma pessoa, então temos, neste caso, que pessoa é uma classe, e se esta pessoa possui as características descritas anteriormente podemos assumir que estas características são os atributos da classe pessoa. E o que seria os métodos de uma classe? Um método seria a capacidade que esta classe tem de interagir com o seu ambiente. Voltamos a classe pessoa, quais seriam as capacidades de uma pessoa interagir com o seu ambiente? Falar, andar, pular, gesticular, etc.

OBS.: Em geral, os métodos são as ações de uma classe, ou seja, métodos no mundo da gramática são os verbos, por exemplo: conversar, andar, pular, tocar, etc. Os atributos poderiam ser considerados os adjetivos, por exemplo: feio, fraco, chato, lerdo, etc.

É muito importante conseguir identificiar o que pode ser uma classe e conseqüentemente seus atributos e seus métodos. Um exercício muito indicado é procurar “coisas” na natureza e fazê-las como classe, a partir daí identificar seus atributos, exemplo: Caixa de som, animal, carro, árvore, computador, etc.