1. Introdução à Programação Orientada a objetos
Programadores habituados a desenvolver de forma estrutural geralmente
sentem uma certa dificuldade em assimilar os conceitos da programação orientada a
objetos. Uma das melhores maneiras de se entender esses conceitos é através do
entendimento de exemplos práticos. Esse é o objetivo desse material.
Existem alguns conceitos e nomenclaturas que fazem parte do mundo da
orientação a objetos, entre eles podemos destacar os conceitos de: Classe, Classe
pai(mãe), Classe filha, Classe abstrata, encapsulamento, operações, métodos,
polimorfismo entre outros. Desses conceitos, o mais importante sem dúvidas é o
conceito de classe. Então vamos ao que interessa.
Classe
Para esclarecer o que vem a ser Classes e outros conceitos em OOP(Object-
Oriented Programming ) é comum recorrer a algumas analogias, e é isso o que vamos
fazer ao longo desse material.
Imagine um padeiro que faz biscoitos de formato redondo. Pense também
que ele tem que fazer centenas desses biscoitos por dia. E mais ainda, ele tem que
fazer todos do mesmo tamanho e peso. Para isso o padeiro poderia tentar fazer todos
esses biscoitos moldando-os um a um, ou ele poderia usar forminhas que tem o
formato do biscoito desejado. Certamente ele usará as forminhas, pois além de
garantir a qualidade ele irá ganhar agilidade. Mas o que essa estória de padeiro e
biscoitos tem a ver com orientação a objetos? A resposta é: tudo.
Na estória contada acima podemos dizer que a forma usada pelo padeiro é
uma classe e que os biscoitos são os objetos. Isto é, precisamos construir uma forma
uma única vez e depois reaproveitá-las várias outras vezes.
Para entender melhor vamos analisar a próxima estória e a partir dela
1
2. vamos modelar uma classe.
Aninha tem dois cachorros, bart e totó, bart é um husky siberiano de cor
branca que late de forma estranha, além disso ele corre muito e morde o pé da
mesa. Já totó é um pastor alemão de cor preta que late de forma intimidadora, ele
atende aos comandos de: finja-se de morto e dê a pata.
No trecho acima podemos considerar os cachorros como sendo objetos.
Para modelar a classe que é a “forma” desses cachorros precisamos definir os seus
atributos e os suas operações(o que eles fazem). Para isso é útil identificar o que é
substantivo(atributo) e verbos(operações) no texto.
Atributos:
Nome,
Raça,
Cor.
Operações:
Latir,
Correr,
Fingir de Morto,
Dar a pata.
Uma forma mais profissional de representar esses atributos e operações é
através de diagramas UML.
2
3. A implementação da classe cachorro com seus atributos e operações em
Java ficaria assim:
3
4. O ato de criar objetos é conhecido como “instanciar o objeto”. O código
seguinte mostra como fazer a instanciação do objeto bart. O objeto toto fica como
exercício.
Por hora não precisamos nos importar com o “public” que aparece em
algumas linhas, isso será discutido mais a frente quando falarmos de encapsulamento.
Entendido o que é classe vamos fazer outros exemplos de classe. Abaixo
mostraremos alguns diagramas UML e suas respectivas Classes:
4
5. Note no exemplo seguinte(PecaXadrez) que a classe é muito “Genérica”,
pois qualquer peça do jogo de xadrez pode ter esses atributos e essa operação.
Veremos como melhorar isso mais adiante, quando falarmos sobre herança.
5
6. Nos exemplos de animal e peça de xadrez podemos perceber que não são
muito uteis quando precisamos de uma objeto bem definido. Cachorro, gato, galinha
e boi são animais. Torre, cavalo, bispo, rainha, rei e peão são peças do jogo de xadrez.
6
7. E agora? Perdemos todo o trabalho feito e recomeçamos do zero? A resposta é: não.
Vamos usar a partir de agora outro recurso das linguagens orientadas a objetos, esse
recurso é o que chamamos de herança.
Herança
Em poucas palavras, herança é o que nos permite reutilizar código e
economizar trabalho em um projeto orientado a objetos. Vamos ver o exemplo e
depois comentá-lo.
Neste diagrama podemos perceber que está faltando alguns atributos à
classe cachorro, como: nome e cor. Também notamos que a operação latir() não está
presente.
Na verdade, tanto os atributos quanto as operações estão presentes nesta
classe, isto se dá pelo fato dela herdar os atributos nome e cor da classe Animal. O
7
8. mesmo acontece com a operação emitirSom() que no caso do objeto cachorro
equivale a operação latir().
A classe Animal é chamada de classe pai e a classe Cachorro é chamada de
classe filha.
Obs.: Particularmente prefiro disser “Classe Mãe”, pois na natureza quem
gera o filho é a mãe e não o pai.
8
9. O que devemos observar no código é o uso da palavra reservada extends.
Intuitivamente percebemos que ela quer dizer que a classe cachorro vai ter tudo o que
tem na classe animal. Além da palavra extends, note que a operação emitirSom() vai
funcionar diferente da operação emitirSom() da classe mãe. O que fizemos aqui foi
implementar um método diferente para a operação emitirSom(). Isso em OOP é
chamado de sobrecarga.
Vejamos mais um exemplo:
9
11. Se compilarmos e executar esse programa temos a seguinte saída:
11
12. Eu ando na horizontal e na vertical
Eu ando de atravessado, ou melhor, eu ando na diagonal
Eu sou o cara, mas só consigo andar uma casa de cada vez
Note que apesar de todos os objetos usarem a operação movimento cada um
tem um comportamento diferente. Em programação orientada a objetos isso se chama
Polimorfismo. Mais a frente será dada uma definição informal para esse termo.
Bem, agora já sabemos o que é classe, classe mãe, classe filha e herança.
Necessitamos, neste momento, refinar esses conceitos. No último exemplo podemos
reparar que se já temos as classes: Torre, Bispo e Rei e sabemos como implementar as
demais, como o cavalo, peão e a rainha não faz mais sentido instanciar um objeto da
classe PecaXadrez. Porém essa classe é útil para nós, pois ela é a base para as outras
peças.
A planta de uma casa é a base para um pedreiro construir essa casa, porém
não é possível morar em cima desse papel onde está impresso a planta, pois isso é
uma abstração do que vai ser a casa. No nosso exemplo a classe PecaXadrez também
é uma abstração para as peças Torre, Cavalo, Bispo, Rei, Rainha e peões. Por isso
vamos marcar essa classe como sendo abstrata, isto é, ela não poderá ser instanciada.
12
13. Se tentarmos instanciar, agora, um objeto da classe PecaXadrez, assim
como no código abaixo, o compilador retornará uma mensagem de erro. Essa
mensagem já é esperada pois agora ela não é mais uma classe palpável mas sim uma
classe abstrata.
Toda classe, a principio, pode ter filhos que derivem dela. Uma classe pode
ter um filho que tem outro filho que tem outro e outro , e assim por diante. Porém
existem situações que é útil dar um basta nisso. O exemplo das peças de xadrez é um
exemplo desses. Não faz sentido a Classe Torre, por exemplo, ter classes filhas.
Precisamos dizer ao compilador que a Classe Torre é uma classe final, isto é, ela não
poderá ter filhos. Para isso usaremos a palavra reservada final no início da classe.
Feito isso o compilador não permitirá que sejam criadas novas classes a
partir desta.
13
14. Polimorfismo
Como já foi dito antes, não vamos dar uma definição formal, mas sim
exemplos informais que ajudaram entender o que é polimorfismo de maneira simples.
Imagine o objeto eddyVanHalen e o objeto chimbinha. Se executarmos a
operação tocarGuitarra() em ambos, apesar das operações terem o mesmo nome elas
tem métodos diferentes para executar essa ação. As operações tem nomes iguais, mas
dependendo a qual objeto ela pertence, a mesma operação assume formas diferentes,
isto é, poli(várias, muitas) formas.
Outro exemplo é o da classe Animal e seus filhos. A operação emitirSom()
do cachorro é diferente da operação emitirSom() do gato que é diferente da galinha,
do boi e assim por adiante.
Encapsulamento
Até agora fizemos os exemplos de classe sem nos preocuparmos com o
encapsulamento, o que no modelo de orientação a objetos é inaceitável. Mas o que é
encapsulamento?
14
15. Veja o exemplo da classe Torre. Se instanciarmos um objeto da classe torre,
por exemplo o objeto “t”, podemos atribuir ao atributo cor do objeto “t” qualquer cor
que desejarmos. Porém isso não é interessante, imagine um jogo de xadrez onde
temos peças brancas, pretas, verdes, amarelas, azuis. Quando trabalhamos sem
encapsulamento temos que contar com o bom senso de quem irá usar nossa classe.
Porém, encapsulando nossos atributos, temos como obrigar o usuário de nossa classe
a atribuir valores que fazem sentido ao escopo do problema.
Pense em um programa simples que pede para inserir a altura e o peso de
uma pessoa. Sem encapsulamento facilmente podemos atribuir a altura 3metros e
peso -10Kg no programa.
Precisamos então tornar os atributos de uma classe privados a ela, isto é, só
ela pode manipular esses atributos. Para inserir valores a esses atributos teremos que
criar operações publicas(qualquer um pode usar) que fazem esse trabalho.
No próximo diagrama o sinal de “ - ” na frente do atributo significa que
esse atributo é privado. Existe também o sinal “ # ” que quer dizer que esse atributo é
protegido, porém esse tipo de encapsulamento não será abordado nesse texto.
A seguir temos a implementação da classe e após, a sua instanciação. Na
15
16. instanciação não é mais possível fazer, por exemplo, p.nome = “Helio” agora
precisamos obrigatoriamente usar o método setNome() , o ideal é tentar executar o
programa com valores que não fazem sentido, por exemplo, p.setAltura(5.59). Fica
como sugestão de exercício tentar executar o programa com atribuição de valores
através do operador “ = ” e tentar atribuir valores fora das “faixas” permitidas para
altura e peso com o uso do setAltura() e do setPeso().
Obs.: A palavra reservada this que precede os nomes das variáveis indicam
que essa variável pertence à classe. Por exemplo, na operação setNome(String nome)
temos nome, como parâmetro da operação, como diferenciar o nome que está
entrando como parâmetro do nome que pertence à classe? Talvez se não usarmos o
this o compilador até reconheça o que estamos querendo, mas por via das dúvidas é
melhor usá-lo.
16
17. Resultado desse programa:
Helio tem 68.0 quilos e tem 1.72 de altura
Seria interessante que no momento de instanciar um objeto já atribuir todos
os valores de necessários ao seus atributos. Isso é possível com o uso de construtores.
Construtores
O uso de construtores permite que façamos todas, ou apenas algumas,
atribuições aos atributos de um objeto. Para isso declaramos uma operação com o
mesmo nome da classe. Essa operação especial, que é o nosso construtor, pode ter
zero ou mais parâmetros. Faremos novamente o exemplo anterior, porem dessa vez
usando construtores.
17
19. Helio tem 68.0 quilos e tem 1.72 de altura
Jorge tem 77.5 quilos e tem 1.79 de altura
Troll tem 777.5 quilos e tem 5.79 de altura
Poderíamos ter usado, normalmente, uma verificação para evitar valores
bizarros ao escopo do problema, assim seria evitado a instanciação do objeto p3 por
exemplo. Aqui não foi usado por se tratar de um exemplo com fins didáticos.
O construtor não é um substituto para as operações set. Uma classe, pode, e
geralmente tem ambos. Além disso, uma classe pode ter mais que um construtor.
Além do Construtor existe também o Destrutor, porém esse não será
abordado nesse material, até mesmo porquê este geralmente é mais usado em
linguagens como C e C++.
Conclusão
A pretensão desse material não é esgotar tudo o que se sabe sobre
orientação a objetos, mas sim, como o próprio titulo diz, ser uma introdução ao
“mundo” da orientação ao objetos.
Este material foi redigido por Helio Albano de Oliveira como parte do
trabalho da disciplina de Empreendedorismo do Curso de Ciência da Computação da
Universidade Estadual de Londrina.
19