domingo, 15 de junho de 2008

Abordagem OO Java - Introdução

Recorrentemente temos abordado POO aqui no blog. Nosso foco maior tem sido Delphi e C#, contudo sempre que podemos procuramos ampliar nossos exemplos experimentando outras linguagens. Vamos falar um pouco desse contexto no mundo Java.

Breve revisão sobre Java

Um programa em Java é sempre uma coleção de objetos comunicando-se com outros. Comunicação essa que acontece mediante a chamada de métodos (evocação de métodos) uns dos outros. Nunca esquecendo, de ter sempre em mente que cada objeto é de um determinado tipo, definido por uma classe ou interface. Não desprezado o fato dessa coleção de objetos, a qual mencionei anteriormente, ser quase sempre composta por objetos de uma variedade diferente de tipos. Vejamos as seguintes definições sobre OO (Estou usando como referência para este artigo o livro da Kathy Sierra, certificação Sun (Java 5), primeiro capítulo):


Classe:
Um modelo que descreve os tipos, de estado e de comportamento, que os objetos do seu tipo podem ter.

Permita-me um comentário: Particularmente, eu acho essa definição satisfatória para quem já conhece bem orientação a objetos. Contudo, para quem esta aprendendo programação ou vem de uma cultura de programação estruturada, duvido que o parágrafo anterior agregue algum valor, no que tange o processo cognitivo de quem o está lendo. Em outros artigos eu e o Felipe usamos outras abordagens para este conceito. Sugiro que você complemente o entendimento lendo as demais definições, principalmente se você ainda esta dando os primeiros passos em OO.

Objeto:
No momento da execução do programa, quando a JVM (Java Virtual Machine) encontra a palavra reservada “new” ela cria uma instância da classe, referenciada no trecho de código corrente. A isso chamamos de criar um objeto (em outras palavras: instanciar um objeto). Esse objeto recém criado terá seu próprio estado, bem como um comportamento. O qual será expressado como reflexo de todas as funcionalidades, definidas por métodos na classe, que são dinamicamente acessíveis ao objeto.
Quem são essas classes acessíveis ao objeto??? Isso se refere a herança. Um objeto cujo tipo é, por exemplo, uma classe “X” terá acesso ao comportamento de todos os ancestrais dela. Ou seja, ele poderá se comportar como a classe “X”, a classe “XPai”, bem como a classe “XAvo” e assim sucessivamente até o ancestral mais alto (o qual chamamos de super classe). Falaremos mais sobre herança adiante.

Estado:
Variáveis de instância – Cada objeto (que por sua vez é uma instância de uma classe) terá seu conjunto único de variáveis de instância conforme definido na classe (definidos pelos atributos da classe). Em contra partida, coletivamente os valores atribuídos as variáveis de instância de um objeto, expressam o estado do mesmo. Ou, os valores persistidos pelas propriedades do objeto, expressam o estado do mesmo.
Ou seja, o conjunto de atributos do objeto definirá, a partir dos valores definidos neles, o estado desse objeto. Por exemplo: Suponha que temos um objeto “Lâmpada”, esse objeto é possuidor de um conjunto de atributos: Potência, Voltagem, Cor e etc. Devemos considerar que este objeto, além desses, possua outro atributo que definirá se “Lâmpada” esta acesa ou não. Esse atributo pode se chamar “Ativa”, ele indica se ela está acessa (ou seja, ativa) ou não. Logo, quando todos esses atributos possuírem valor, exemplo: Lâmpada.Cor = Amarela, Lâmpada.Voltagem = 110, Lâmpada.Potência = 100W e Lâmpada.Activa = Verdadeiro. Posso agora então conhecer o estado desse objeto.

Comportamento:
Quando codificamos uma classe, e implementamos os métodos dela, estamos definido a lógica da classe. “É nos métodos que a lógica da classe é armazenada” (Achei essa definição muito apropriada). Através dos métodos, o verdadeiro trabalho da classe é realizado. Ou seja, a razão de ser da classe, onde seu principal objetivo é definido. Neles e por meio deles, algoritmos são executados e os dados são manipulados.

Herança:
Característica da orientação a objetos que permite o reaproveitamento do código de uma classe por outra. Em Java é possível definir uma superclasse “genérica” (mais abstrata) e em seguida estendê-la criando outras classes mais específicas. A superclasse não tem conhecimento algum sobre as classes que descendem dela. Em contra partida, essas classes herdeiras precisam declarar explicitamente a relação de herança. Como efeito disso, uma subclasse que herda de uma superclasse “recebe automaticamente”, digamos assim, as variáveis de instância acessíveis, bem como os métodos definidos na superclasse. Além disso possui autonomia para redefinir os métodos herdados da superclasse, a fim de expressar um comportamento mais específico (este fenômeno chamamos de sobrescrita de método. Ou seja uma subclasse pode sobrescrever os métodos herdados).

Identificando Classes (Análise)
Em concordância com o que mencionei anteriormente, é extremamente importante ser obstinado em alcançar um grau de coesão alto na classe que você está definindo. Isso implica diretamente que toda classe deve ter muito bem definido o conjunto de responsabilidades pertinentes ao conceito do mundo real o qual ela representará para um sistema. Por exemplo, imagine um programa cujo objetivo principal é simular uma orquestra: Certamente encontraremos a representação de instrumentos musicais por algumas classes, bem como músicos, partituras e composição musical por outras tantas. Concluir isso é bastante elementar. Contudo, um erro fatal (e na minha opinião muito freqüente) seria definir, em virtude de um equívoco de análise, o comportamento (ou parte dele) de uma classe em outra, ou vice-versa. Por exemplo: A classe instrumentista possuir um método que retorne o compasso corrente. Creeeeeddddooooo!??!?!?!? Visto que, compasso é um atributo da classe partitura. Um programa em Java é constituído tanto por classes construídas pelo programador, quanto por e outras que não (por exemplo, classes Java API). Em Java as classes são organizadas em pacotes, os quais devemos referenciar mediante a palavra reservada “import” a fim de usarmos suas classes em nossos programas. Dessa forma a linguagem fornece uma forma consistente do desenvolvedor nomear, bem como obter acesso, as classes que necessitar. No exame de certificação Java a avaliação aborda muitos dos conceitos relacionados aos pacotes e acesso a classes. Posteriormente detalharemos mais esses temas.

Interfaces:
É uma espécie de superclasse cem por cento abstrata que define os métodos que uma subclasse deve suportar, mas não define como esse método deve se comportar (ou seja, não define come deve ser implementado). Exemplificando, uma interface "Instrumento Musical" pode declarar que todas as as classes de implementação de "Instrumento Musical" (estendidas dela) possuirão um método "reproduzirSom()". Contudo, a interface "Instrumento Musical" não fornece nenhuma lógica para para este método. Isso implica que a classe que implementar "Instrumento Musical" terá a responsabilidade de definir o comportamento dos métodos definidos na interface. Determinando então, desta forma, como cada instrumento irá se comportar particularmente.
Venho sentindo a necessidade de escrever sobre interface não é de hoje, entretanto ainda não consegui preparar um material que me agrade. Esse assunto esta na fila e considero extremamente pertinente.

Nenhum comentário:

Postar um comentário