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!