abstraÇÃo
Post on 16-Mar-2016
32 Views
Preview:
DESCRIPTION
TRANSCRIPT
ABSTRAÇÃO • processo de representar um grupo de
entidades através de seus atributos comuns• feita a abstração, cada entidade particular
(instância) do grupo é considerada somente pelos seus atributos particulares
• os atributos comuns às entidades do grupo são desconsiderados (ficam "ocultos" ou "abstraídos")
ABSTRAÇÃO DE PROCESSOS • o conceito de abstração de processos é um
dos mais antigos no projeto de linguagens• absolutamente crucial para a programação• historicamente anterior à abstração de dados• todos os subprogramas são abstrações de
processo• exemplo: chamadas sort(array1, len1),
sort(array2, len2), ...
MÓDULOS• módulos são "containers" sintáticos contendo
subprogramas e grupos de dados relacionados logicamente
• modularização: processo de projetar os módulos de um programa
• a compreensão do programa pelos mantenedores seria impossível sem organização modularizada
• além disso, há um ponto crítico: quando o projeto de um programa estende-se por milhares de linhas, recompilá-lo totalmente a cada atualização do código é absolutamente inviável - daí a necessidade de modularizá-lo
ENCAPSULAMENTO• um agrupamento de subprogramas+dados que é
compilado separada/independentemente chama-se uma unidade de compilação ou um encapsulamento
• um encapsulamento é portanto um sistema abstraído • muitas vezes os encapsulamentos são colocados em
bibliotecas • exemplo: encapsulamentos C (não são seguros porque
não há verificação de tipos de dados em diferentes arquivos de encapsulamento)
OBJETOS• um tipo abstrato de dados é um encapsulamento que
inclui somente um tipo específico de dado e os subprogramas que fornecem as operações para este tipo
• detalhes de implementação do tipo ficam ocultos das unidades fora do encapsulamento que o contém
• um objeto é uma variável (instância) de um tipo abstrato de dados, declarada por alguma unidade
• programação orientada a objetos consiste no uso de objetos no desenvolvimento do software
EXEMPLO: O PONTO-FLUTUANTE COMO TIPO ABSTRATO DE DADOS
• embora o tipo ponto-flutuante esteja presente desde o início da programação, raramente nos referimos a ele como tipo abstrato de dados
• praticamente todas as linguagens permitem que se criem "objetos" do tipo ponto-flutuante
• observe que existe um conjunto de operações que são válidas para o tipo ponto-flutuante, exatamente como os “métodos” definidos para uma “classe”
• além disso, a ocultação da informação está presente: o formato real dos dados é inacessível ao programador - isto é exatamente o que se espera de uma abstração
• isto é o que permite a portabilidade de um programa entre as implementações da linguagem para plataformas particulares
TIPOS DE DADOS ABSTRATOS DEFINIDOS PELO USUÁRIO
• a definição do tipo e as operações sobre objetos do tipo estão contidas numa única unidade sintática
• outras unidades de programa podem ter permissão para criar variáveis do tipo definido
• a implementação do tipo não é visível pelas unidades de programa que usam o tipo
• as únicas operações possíveis sobre objetos do tipo são aquelas oferecidas na definição do tipo
CLIENTES• unidades de programa que utilizam um tipo
abstrato chamam-se clientes daquele tipo • a ocultação da representação do tipo abstrato é
vantajoso para seus clientes: o código no cliente não depende desta representação, e mudanças na representação não exigem mudanças nos clientes (mas se o protocolo de alguma operação for modificado, então é claro que os clientes precisam ser alterados)
• a ocultação aumenta a confiabilidade: nenhum cliente pode interferir intencional ou acidentalmente na representação
EXEMPLO: UMA PILHA E SUAS OPERAÇÕES ABSTRATAS
• create(stack)• destroy(stack)• empty(stack)• push(stack, elem)• pop(stack)• top(stack) • create(STK1); % STK1 é um objeto ou uma
instância do tipo stack• create(STK2); % outra instância do tipo stack
TIPOS DE DADOS ABSTRATOS EM C++
• os tipos abstratos de dados em C++ são as chamadas classes
• as variáveis são declaradas como instâncias de classes
• classes do C++ são baseadas nas da SIMULA67 e no struct do C
• os dados definidos numa classe são os membros de dados
FUNÇÕES-MEMBRO• as funções definidas em uma classe são as
funções-membro• as funções-membro são compartilhadas por
todas as instâncias de classe • mas: cada instância tem seu próprio conjunto de
membros de dados • uma função membro pode ter sua definição
completa dentro da classe ("inlined") ou apenas seu cabeçalho
TEMPO DE VIDA DAS CLASSES
• as instâncias de classe podem ser estáticas, stack-dinâmicas ou heap-dinâmicas, exatamente como variáveis do C
• as classes podem incluir membros de dados heap-dinâmicos, não obstante elas próprias não serem heap-dinâmicas
OCULTAÇÃO DA INFORMAÇÃO EM C++
• cláusula private: para entidades ocultas na classe
• cláusula public: para as entidades visíveis aos clientes. Descreve a interface com objetos da classe
• cláusula protected: relacionada com herança
Construtores• Funções-membro usadas para inicializar os
membros de dados de um objeto recém-criado
• Também alocam membros de dados heap-dinâmicos
• Têm o mesmo nome da classe • Pode-se sobrecarregar construtores • Não têm tipo de retorno, não usam return
Destrutores• Implicitamente chamados quando se
encerra o tempo de vida de um objeto• Se um objeto é heap-dinâmico, será
explicitamente desalocado com delete• O destrutor pode conter chamadas delete
para desalocar membros de dados heap-dinâmicos
• Nome do destrutor: ~ <nome_da_classe>• Não têm tipo de retorno, não usam return
Exemplo#include <iostream.h>class pilha {
private:int *ptr_pilha;int tam_max;int top_ptr ;public:pilha( ){ //** um construtorptr_pilha = new int [100];tam_max = 99;top_ptr = -1;}
Exemplo (continuação)... ~pilha( ){ //** um destrutor
delete [ ] ptr_pilha;}void push ( int elem) { if (top_ptr = = tam_max)cout << “Erro - pilha cheia\n”;else ptr_pilha[ + + top_ptr ] = elem;} void pop ( ) { if (top_ptr = = -1)cout << “Erro - pilha vazia\n”;else top_ptr -- ;}
Exemplo (continuação)... int top { return ( ptr_pilha[top_ptr] ); }
int empty { return ( top_ptr = = -1 ); } } \\** fim da classe pilha
Código no cliente: void main ( ) {
int top_one;pilha stk; stk.push(42);stk.push(17);top_one = stk.top( );stk.pop( ); ... }
Avaliação das classes C++• As classes são tipos• Não há construções de encapsulamento
generalizadas • Exemplo: temos uma classe “matriz” e uma
classe “vetor”, e precisamos multiplicar um objeto “matriz” por um objeto “vetor”.
• Em qual classe essa operação deve ser definida?
Solução para “matriz vetor” class Matriz {
friend Vetor mult(const Matriz&, const Vetor&); ...}
class Vetor { friend Vetor mult(const Matriz&, const Vetor&);
...}
Vetor mult(const Matriz& m1, const Vetor& v1){..}
Se Matriz e Vetor pudessem ser definidas num único pacote, evitaríamos esta construção pouco natural.
Java• Suporte para tipos abstratos similar a C++ • Todos os tipos de dados definidos pelo
usuário são classes • Todos os objetos são heap-dinâmicos e
acessados por variáveis de referência• Todos os subprogramas (métodos) em Java
somente podem ser definidos em classes • public e private são modificadores anexados
às definições de métodos/variáveis
Java• Suporte para tipos abstratos similar a C++ • Todos os tipos de dados definidos pelo
usuário são classes • Todos os objetos são heap-dinâmicos e
acessados por variáveis de referência• Todos os subprogramas (métodos) em Java
somente podem ser definidos em classes • public e private são modificadores anexados
às definições de métodos/variáveis
Pacotes Java• Em C++ as classes são a única construção de
encapsulamento• Java inclui uma construção adicional: os pacotes• Pacotes podem conter mais de uma classe• public e private são os chamados modificadores • Os membros sem modificador (e os membros
public) de uma classe são visíveis a todas as classes do mesmo pacote (escopo de pacote)
• Não há, portanto, necessidade de declarações friend explícitas em Java
Exemplo
import java.io.*
class Pilha {private int [ ] ref_pilha;private int tam_max, top_index ;public Pilha( ){ // um construtor
ref_pilha = new int [100];tam_max = 99;top_index = -1;
}
Exemplo (continuação)... public void push ( int elem) {
if (top_index = = tam_max)System.out.println(“Erro”);else ref_pilha[ + + top_index ] = elem;} public void pop ( ) { if (top_index = = -1)System.out.println(“Erro”);else --top_index ;} public int top { return ( ref_pilha[top_index] ); } public boolean empty { return ( top_index = = -1 ); }
} \\** fim da classe Pilha
Exemplo (continuação) - uso da classe Pilha public class Testa_Pilha {
public static void main (String [ ] args) { Pilha p1 = new Pilha( ); p1.push(42);p1.push(29);p1.pop( );p1.pop( ); p1.pop( ); // Produz msg de erro... }
• Não há destrutor (eliminado pela coleta de lixo implícita em Java)
• Observe o uso de variável de referência em vez de ponteiro
Classes parametrizadas em C++Exemplo: suponha que o método construtor para a
classe pilha fosse: pilha (int size ){
ptr_pilha = new int [size];tam_max = size-1;top_ptr = -1;
}No cliente: ... pilha(150) p1;
Classes genéricas em C++ #include <iostream.h>template < class TIPO >class pilha {
private:TIPO *ptr_pilha;int tam_max;int top_ptr ;
public:pilha( ){ //** um construtor
ptr_pilha = new TIPO [100];tam_max = 99;top_ptr = -1;
}
Classes genéricas em C++ (continuação)
pilha (int size ){ // outro construtor sobrecarregadoptr_pilha = new TIPO [size];tam_max = size-1;top_ptr = -1;}~pilha( ){ delete ptr_pilha; }void push ( TIPO elem) { if (top_ptr = = tam_max)cout << “Erro - pilha cheia\n”;else ptr_pilha[ + + top_ptr ] = elem;} void pop ( ) {...}
top related