PROGRAMAÇÃO ORIENTADA
A PROCEDIMENTOS
Paradigma de software mais popular na
década de 70
 Concentra-se em subprogramas e
bibliotecas de subprogramas
 Computações: os dados são enviados
aos subprogramas
 Exemplo: um array é passado como
parâmetro a um subprograma de
classificação

PROGRAMAÇÃO ORIENTADA
A DADOS (OBJETOS)
"Linguagens baseadas em dados"
 Raízes: Simula67
 Smalltalk80 - considerada a única
linguagem puramente OO




Tipos de dados abstratos
Herança
Polimorfismo
PROGRAMAÇÃO ORIENTADA
A DADOS (OBJETOS) II
Computações realizam-se do seguinte
modo: sobre um objeto-dados é
invocado um método associado a este
objeto-dados
 Exemplo: o processo de classificação de
um array é ativado invocando-se este
método no objeto específico

HERANÇA
É o centro da programação orientada a
objetos
 Na década de 80 tornou-se patente aos
desenvolvedores que a melhor forma de
aumentar a produtividade era a
reutilização do software
 Os tipos abstratos de dados eram as
unidades a serem reutilizadas

HERANÇA II

A reutilização origina duas questões:



Quase sempre, os recursos do tipo já
existente não são adequados ao novo
emprego, e o modificador precisaria
entender todo o código existente e
alterar os clientes
Como definidos até aqui, os tipos de
dados abstratos são independentes e
estão no mesmo nível, o que torna
impossível estruturar um problema
A herança fornece solução para as duas
questões acima
HERANÇA - solução para o
problema da modificação




Um novo tipo de dados abstrato pode herdar
dados e funcionalidades de um tipo existente
Também é permitido modificar algumas
entidades e adicionar novas
Exemplo: suponhamos que o tipo array, além
de ter um método de classificação, necessite
agora de método para computar sua mediana
Em vez de modificar a implementação do tipo
existente, pode-se definir uma subclasse que
retém a classificação e adiciona a si a
computação da mediana
NOMENCLATURA






Uma classe definida pela herança de outra é
chamada classe derivada ou subclasse
A classe da qual a nova é derivada chama-se classepai ou superclasse ou classe-raiz
As chamadas a métodos frequentemente são
chamadas de mensagens
A coleção de métodos de um objeto é o protocolo de
mensagem ou interface de mensagem do objeto
Toda mensagem tem duas partes: o objeto específico
ao qual ela está sendo enviada e o nome de um
método que define a ação solicitada no objeto
Computações podem ser vistas como mensagens
AS CLASSES DERIVADAS
COMO CLIENTES
O acesso a um membro de uma classe
pode ser "concedido" ou "reusado"
 Uma terceira categoria de acesso, com
frequência chamada protected, é usada
para fornecer concessão a uma classe
derivada

SOBREPOSIÇÃO DE MÉTODOS




Um método modificado numa classe derivada
tem o mesmo nome e muitas vezes o mesmo
protocolo do método original
O novo método fica sobreposto ao original
Objetivo da sobreposição: fornecer operação
específica a objetos da classe derivada, que
não é apropriada para objetos da classe-pai
Exemplo: classe raiz French_Gothic com
método draw, classes derivadas Reims, Amien
e Chartres com métodos draw herdados e
sobrepostos ao da classe raiz
HERANÇA SIMPLES E
HERANÇA MÚLTIPLA





Se a classe derivada possui uma única classepai, o processo chama-se herança simples
Caso contrário (duas ou mais classes-pai),
chama-se herança múltipla
"Hierarquia de classes" = conjunto de
heranças em sua totalidade
Hierarquia de heranças simples gera uma
árvore de derivação
Hierarquia de heranças múltiplas gera um
grafo (direcionado) de dependências
HERANÇA SIMPLES E
HERANÇA MÚLTIPLA II
Exemplo: um applet do Java com
animação
 os applets são suportados pela classe
Applet
 a concorrência (necessária para a
animação) é suportada pela classe
Thread
 é necessário que um applet herde de
ambas as classes

HERANÇA SIMPLES E
HERANÇA MÚLTIPLA III
Desvantagem da hierarquia:
dependência entre as classes (os tipos
de dados abstratos perdem sua
independência...)
 Porém: é impossível reusar tipos sem
criar dependências entre alguns deles

HERANÇA SIMPLES E
HERANÇA MÚLTIPLA IV



Problema da colisão de nomes: se a
subclasse C herdar tanto de A como de B, e
ambas incluem a variável hereditária sum,
como C poderá referir-se às duas sum
diferentes?
Problema da herança diamante: suponha
também que A e B sejam subclasses de Z
Não está claro ainda se os benefícios da
herança múltipla valem o esforço adicional de
gerenciar o intrincado complexo de
dependências...
HERANÇA EM C++: Exemplo
class classe_base{
private:
int a; float x;
protected:
int b; float y;
public:
int c; float z;
};
class subclasse_1: public classe_base{...}
class subclasse_2: private classe_base{...}
DISCUSSÃO DO EXEMPLO
ANTERIOR






Observe a existência de um modo de acesso na
definição das subclasses
É claro que a,x não são visíveis em qualquer
descendente de classe_base
subclasse_1 mantém b,y como protegidos e c,z como
públicos
Em subclasse_2 b,y,c,z são todos membros privados
Nenhuma classe derivada de subclasse_2 pode ter
acesso a qualquer membro de dados de classe_base
Isto é, uma subclasse private X interrompe o acesso
de suas descendentes aos membros de dados dos
ancestrais de X
HERANÇA EM C++: outro exemplo
class lista_encadeada{
class no{
friend class lista_encadeada;
private:
int info;
no *prox;
}
private:
no *inicio;
public:
lista_encadeada ( ) {inicio=0};
void insere_inicio(int);
void insere_final(int);
int remove_inicio( );
int vazia( );
};
HERANÇA EM C++: outro exemplo II
class pilha : public lista_encadeada{
public:
pilha( ) { }
void push (int elem){
lista_encadeada::insere_inicio(int elem);
}
void pop ( ) {
return lista_encadeada::remove_inicio( );
}
};
HERANÇA EM C++: outro exemplo
III
class fila : public lista_encadeada{
public:
fila( ) { }
void enqueue (int elem){
lista_encadeada::insere_final(int elem);
}
int dequeue ( ) {
return lista_encadeada::remove_inicio( );
}
};
HERANÇA MÚLTIPLA EM C++
class A {...}
class B {...}
class C: public A, public B {...}
:: -> operador de resolução de escopo
(solução C++ para o conflito de nomes em
herança múltipla )
REEXPORTAÇÃO
class subclasse_3 : private classe_base{
classe_base :: c; // c passa a ser visível em
// descendentes de
//subclasse_3
...}
:: -> operador de resolução de escopo
POLIMORFISMO E
VINCULAÇÃO DINÂMICA





Variáveis polimórficas: são do tipo da classe-pai e
também podem referenciar objetos de qualquer uma
das subclasses da mesma
Variáveis polimórficas são ponteiros ou referências
Considere um método M sobreposto nas subclasses
Quando M é invocado por uma variável polimórfica,
esta chamada é vinculada dinamicamente ao método
da classe apropriada
Isto permite a extensão e a manutenção de sistemas
com muito mais facilidade
POLIMORFISMO E
VINCULAÇÃO DINÂMICA II
Exemplo: variável polimórfica cathedral
do tipo French_Gothic pode referenciar
os métodos draw de Reims, Amien e
Chartres.
 Quando cathedraw for usada para
chamar draw, esta chamada será
vinculada dinamicamente à versão
correta de draw

O MESMO EXEMPLO EM C...




Se o exemplo das catedrais fosse escrito em C, os
três tipos de catedrais poderiam estar um struct
Haveria uma única função draw que usaria uma
instrução switch, do seguinte modo: um parâmetro
por valor seria enviado a draw para especificar qual
item do switch contém as diretivas de desenho
corretas
Se adicionarmos uma nova catedral do tipo Paris,
temos que modificar o switch e repensar o protocolo
de draw
Com orientação a objetos, basta criar uma nova
subclasse com seu método sobreposto. Não há
necessidade de alterar o código existente
QUANDO A HIERARQUIA
CRESCE...






Às vezes a classe-raiz está tão alta e tão distante na
hierarquia que nem faz sentido instanciá-la num
objeto particular
Exemplo: suponha que Building seja classe-pai de
French_Gothic. Building é um tipo "edifício genérico"
Talvez não faça sentido um método draw em Building
Mas como todas as suas classes descendentes tem
este método implementado, o protocolo (mas não o
corpo) deste método é incluído em Building
Este método abstrato é chamado método virtual
A classe Building é chamada classe virtual - não pode
ser instanciada, porque nem todos os seus métodos
POLIMORFISMO EM C++
class Building {
// classe "abstrata" (virtual)
public:
virtual void draw( ) = 0; // função virtual "pura"
...}
class French_Gothic : public Building {
public:
virtual void draw( ) {...} // método sobreposto
...}
class German_Gothic : public Building {
public:
virtual void draw( ) {...} // método sobreposto
...}
POLIMORFISMO EM C++ II
French_Gothic x;
German_Gothic y;
Building &ref_build = x; // ref_build é polimórfica
// e faz referência a uma
// catedral francesa
ref_build.draw( );
y.draw( );

// vinculado dinamicamente ao draw
// para catedral francesa
// vinculado estaticamente ao draw
// para catedral alemã
É claro que a vinculação estática, apesar de menos
flexível, é mais eficiente que a dinâmica
POLIMORFISMO E
VERIFICAÇÃO DE TIPOS


Quando o método sobreposto chamado é vinculado
ao método correto, deve-se checar se:
 os tipos dos parâmetros reais na mensagem
coincidem com os parâmetros formais do
método correto
 o tipo do valor de retorno do método correto é
o tipo esperado da mensagem
Se a vinculação for dinâmica, a verificação deverá ser
retardada até o ponto da execução em que a
mensagem é enviada
MODELO DE COMPUTAÇÃO
PURAMENTE OO



É uma técnica uniforme: enviar uma
mensagem a um objeto para invocar um de
seus métodos
A resposta à mensagem é um objeto que
retorna o valor da computação do método
Os objetos podem ser vistos como uma
coleção de computadores que se comunicam
entre si pelas mensagens (modelo abstrato
de computação distribuída)
MODELO DE COMPUTAÇÃO
PURAMENTE OO II
Cada objeto é a abstração de um
computador com seus dados (sua
memória local) e sua capacidade de
processamento (seus métodos)
 Podemos então simular o problema real
identificando os objetos do mundo real,
seus processos e as comunicações
necessárias entre eles

MODELO DE COMPUTAÇÃO
PURAMENTE OO III
Tudo é objeto - desde o menor número
inteiro até um sistema complexo de
dados e processos
 Todos os tipos são classes
 Toda a computação é a invocação de
um método. Exemplo: 21 + 2
 Não há distinção entre classes
predefinidas e classes definidas pelo
usuário - todas são tratadas da mesma
maneira

MODELO DE COMPUTAÇÃO
PURAMENTE OO IV
A vantagem é a uniformidade, a
elegância, a maleabilidade do uso
 Desvantagem: tudo deve ser feito pelo
processo de passagem de mensagens,
o que torna as operações mais lentas
em relação às suas similares
imperativas
 Smalltalk: chega a ser comercialmente
inviável pela sua baixíssima eficiência

ALTERNATIVAS À COMPUTAÇÃO
PURAMENTE OO

Alternativa I: manter um modelo
completo de tipificação imperativo e
simplesmente adicionar o modelo OO


Porém: a estrutura de tipos fica extremamente
confusa (C++...)
Alternativa II: manter o modelo
imperativo apenas para tipos primitivos
escalares

Necessidade das classes wrapper (envoltórias)
sobre tipos não-objeto (Java...)
SUBCLASSES SÃO SUBTIPOS?
Exemplo: Ada
subtype SMALL_INT is INTEGER range -100..100



Para todos os efeitos, SMALL_INT é uma
variável INTEGER
Usa as mesmas operações e pode aparecer
no lugar de qualquer variável INTEGER
Uma classe é chamada subtipo se guardar as
mesmas características acima com sua classepai
SUBCLASSES SÃO SUBTIPOS? II
Para ser subtipo, a subclasse deve:
 herdar "tudo"
 adicionar/sobrepor métodos de modo
"compatível" (sem causar erros de tipo)
 a sobreposição segura pode ser garantida
usando exatamente o mesmo protocolo
 mas há restrições menos severas...
OCULTAÇÃO DA INFORMAÇÃO
ÀS SUBCLASSES
A implementação da classe fica oculta
aos clientes
 E com relação às subclasses?
 Herança de interface = apenas a
interface da classe pai é visível à
subclasse
 Herança de implementação = os
detalhes da implementação também
são visíveis na subclasse

OCULTAÇÃO DA INFORMAÇÃO
ÀS SUBCLASSES II

Exemplo: subclasse da classe pilha que deve ter um
método para retornar o elemento logo abaixo do topo
 com herança de implementação, basta verificar
ptr_pilha [top_ptr-1]
 com herança de interface:
int segundo( ){ ...
int temp = top( );
pop( );
int result_temp = top( );
push(temp);
return result_temp;
}
COMENTÁRIOS GERAIS AO
C++
Compatibilidade quase completa com C
(questão de projeto)
 Híbrido no sentido de que possui tanto
os tipos das linguagens imperativas
tradicionais como a estrutura de classes
da OO
 Suporta tanto programação orientada a
procedimentos como a objetos

COMENTÁRIOS GERAIS AO
C++ II





Objetos podem ser alocados nos mesmos
lugares onde se aloca variáveis no C
Objetos dinâmicos devem ser explicitamente
desalocados com delete
Não há reivindicação de armazenamento
implícita
C++ não está imune ao problema das
referências oscilantes e do vazamento de
memória...
Com a desvantagem de que os ponteiros
agora são para objetos!
COMENTÁRIOS GERAIS AO
C++ III
Todas as classes incluem pelo menos
um método construtor, utilizado para
inicializar os membros de dados
 Métodos construtores são chamados
implicitamente na criação do objeto
 Se nenhum construtor é incluído na
definição da classe, o compilador
incluirá um método construtor trivial

COMENTÁRIOS GERAIS AO
C++ IV





O destrutor é implicitamente chamado quando o
objeto deixa de existir
Desalocação de membros de dados dinâmicos devem
estar presentes no destrutor!
Herança do C++ é confusa em relação ao Smalltalk
em termos de controle de acesso
Levando também em consideração as declarações
friend, o programador C++ tem um controle
altamente detalhado (e complicado!) do acesso aos
membros
Questiona-se se isto é produtivo...
COMENTÁRIOS GERAIS AO
C++ V



Em C++ o programador pode especificar
vinculação estática ou dinâmica
A vinculação dinâmica em C++, apesar de
mais lenta que a estática, tem um acréscimo
de custo fixo, mesmo que a mensagem seja
vinculada a um método distante na
hierarquia.
Em Smalltalk, as mensagens são sempre
vinculadas dinamicamente a métodos e o
custo da vinculação depende da distância na
hierarquia
COMENTÁRIOS GERAIS AO
C++ VI
A possibilidade de verificação estática
de tipos em C++ é vantajosa
 As classes genéricas possibilitam
verificação estática
 Em Smalltalk, toda verificação é
dinâmica. Pode-se até chamar métodos
não existentes, e isto só será notado na
execução

COMENTÁRIOS GERAIS AO
C++ VII
Smalltalk é totalmente dedicada ao
paradigma OO, ignorando imposições
de bases guerreiras de usuários
 Smalltalk é uma linguagem pequena,
elegante, altamente simples e ortogonal
 C++ é uma linguagem grande,
complexa e sem filosofia particular
como base, exceto a de incluir usuários
de C

COMENTÁRIOS GERAIS AO
C++ VIII





Alguns acham que os recursos de C++ nem
sempre se encaixam bem sobre o C
Testes revelam que Smalltalk compila a 10%
da velocidade de um compilador C otimizado
C++ compila exigindo somente um pouco
mais de tempo que os compiladores C
Dada a grande distância de eficiência entre
C++ e Smalltalk, é fácil explicar a diferença
de sucesso comercial entre as duas
Além disso, há a "compatibilidade" de C++
com a base usuária C
Download

programação orientada a procedimentos