Baixe o app para aproveitar ainda mais
Prévia do material em texto
Capítulo 11 Tipos de Dados Abstratos e Construções de Encapsulamento Conceitos de Linguagens de Programação – Robert W. Sebesta Tópicos do Capítulo 11 O conceito de abstração Introdução à abstração de dados Questões de projeto para tipos de dados abstratos Exemplos de linguagem Tipos de dados abstratos parametrizados Construções de encapsulamento Nomeando encapsulamentos Conceitos de Linguagens de Programação – Robert W. Sebesta O conceito de abstração Uma abstração é uma visão ou representação de uma entidade que inclui apenas os atributos mais significativos O conceito de abstração é fundamental em programação (e ciência da computação) Quase todas as linguagens de programação suportam abstração de processos com subprogramas Quase todas as linguagens de programação projetada a partir dos anos 1980 suportam abstração de dados Conceitos de Linguagens de Programação – Robert W. Sebesta Introdução à abstração de dados Um tipo de dado abstrato é um tipo de dados definido pelo usuário com as seguintes condições: A implementação do tipo e de suas operações pode estar na mesma unidade sintática, ou podem ser fornecidas em uma unidade separada A representação dos objetos do tipo é ocultada das unidades de programa que usam o tipo, então as únicas operações diretas possíveis em tais objetos são aquelas fornecidas na definição do tipo Conceitos de Linguagens de Programação – Robert W. Sebesta Vantagens da abstração de dados Vantagem da primeira condição Organização do programa, facilidade para mudanças (tudo associado à estrutura de dados está junto) e compilação separada Vantagem da segunda condição A vantagem de fazer com que a interface não dependa da representação ou da implementação das operações é que isso permite que a representação e/ou a implementação sejam modificadas sem requerer mudanças aos clientes do tipo Conceitos de Linguagens de Programação – Robert W. Sebesta Requisitos de linguagem para tipos de dados abstratos Uma unidade sintática para encapsular a definição do tipo Um método de fazer os nomes de tipo e subprograma cabeçalhos visíveis para os clientes, enquanto esconde as definições reais Algumas operações primitivas devem ser incorporadas no processador de linguagem Conceitos de Linguagens de Programação – Robert W. Sebesta Questões de projeto Qual é a forma do contêiner para a interface do tipo? Tipos de dados abstratos podem ser parametrizados? Quais controles de acessos são fornecidos e como são especificados? Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplos de linguagem: Ada As construções de encapsulamento são chamadas de pacotes Pacote de especificação (a interface) Pacote de corpo (implementação da maioria das entidades nomeadas no pacote de especificação associado) Ocultamento de informação O pacote de especificação tem duas partes: pública e privada O nome do tipo abstrato aparece na parte pública. A representação de um tipo abstrato aparece na parte privada Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplos de linguagem: Ada (continuação) Razões para os pacotes de especificação públicos ou privados: O compilador deve poder ver a representação depois de ver apenas o pacote de especificação (não pode ver a parte privada) Clientes devem poder ver o nome do tipo, mas não a representação (também não podem ver a parte privada) Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplos de linguagem: Ada (continuação) É de certa forma problemático que o pacote de especificação forneça parte dos detalhes de implementação (a definição dos dados), enquanto que os detalhes de implementação restantes (a definição das operações) estão no pacote de corpo Uma solução: tornar os tipos de dados abstratos ponteiros Problemas com isso: Dificuldades em lidar com os ponteiros Comparações entre objetos O controle da alocação do objeto é perdido Conceitos de Linguagens de Programação – Robert W. Sebesta Um exemplo em Ada package Stack_Pack is type stack_type is limited private; max_size: constant := 100; function empty(stk: in stack_type) return Boolean; procedure push(stk: in out stack_type; elem:in Integer); procedure pop(stk: in out stack_type); function top(stk: in stack_type) return Integer; private -- hidden from clients type list_type is array (1..max_size) of Integer; type stack_type is record list: list_type; topsub: Integer range 0..max_size) := 0; end record; end Stack_Pack Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplos de linguagem: C++ Baseado no tipo struct de C e classes de Simula 67 A classe é o mecanismo de encapsulamento Todas as instâncias da classe de uma classe compartilham uma única cópia das funções de membro Cada instância de uma classe tem sua própria cópia dos membros de dados de classe Instâncias podem ser estáticas, dinâmicas da pilha ou dinâmicas do monte Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplos de linguagem: C++ (continuação) Ocultamento de informação Cláusula private para entidades que devem ser ocultas Cláusula public entidades visíveis, ou públicas Cláusula protected discutida no contexto de herança no Capítulo 12 Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplos de linguagem: C++ (continuação) Construtores: Funções para inicializar os membros de dados de novos objetos sendo criados Também pode alocar os dados dinâmicos do monte que são referenciados pelos membros ponteiros do novo objeto Pode incluir parâmetros para parametrização de objetos Implicitamente chamado quando um objeto do tipo da classe é criado Pode ser chamado explicitamente O nome é o mesmo que o da classe Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplos de linguagem: C++ (continuação) Destrutores Implicitamente chamado quando o tempo de vida de uma instância da classe termina Pode ser chamado explicitamente O nome de um destrutor é o nome da classe, precedido por til (~) Conceitos de Linguagens de Programação – Robert W. Sebesta Um exemplo em C++ class Stack { private: int *stackPtr, maxLen, topPtr; public: Stack() { // a constructor stackPtr = new int [100]; maxLen = 99; topPtr = -1; }; ~Stack () {delete [] stackPtr;}; void push (int num) {…}; void pop () {…}; int top () {…}; int empty () {…}; } Conceitos de Linguagens de Programação – Robert W. Sebesta Classe Stack // Stack.h - the header file for the Stack class #include <iostream.h> class Stack { private: //** These members are visible only to other //** members and friends (see Section 11.6.4) int *stackPtr; int maxLen; int topPtr; public: //** These members are visible to clients Stack(); //** A constructor ~Stack(); //** A destructor void push(int); void pop(); int top(); int empty(); } Conceitos de Linguagens de Programação – Robert W. Sebesta O código para Stack // Stack.cpp - the implementation file for the Stack class #include <iostream.h> #include "Stack.h" using std::cout; Stack::Stack() { //** A constructor stackPtr = new int [100]; maxLen = 99; topPtr = -1; } Stack::~Stack() {delete [] stackPtr;}; //** A destructor void Stack::push(int number) { if (topPtr == maxLen) cerr << "Error in push--stack is full\n"; else stackPtr[++topPtr] = number; } ... Conceitos de Linguagens de Programação – Robert W. Sebesta Avaliação de tipos abstratos em C++ e Ada O suporte de C++ para tipos de dados abstratos, por meio de sua construção de classes, é similar ao poder de expressão do suporte de Ada, por seus pacotes Ambos fornecem mecanismos efetivos para o encapsulamento e o ocultamento de informação de tipos de dados abstratos A diferença primária é que classes são tipos, enquanto que os pacotes de Ada são encapsulamentos mais gerais Conceitos de Linguagens de Programação– Robert W. Sebesta Exemplos de linguagens: C++ (continução) Funções amigas ou classes – para fornecer acesso a membros privados para unidades ou funções não relacionadas Necessárias em C++ Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplos de linguagem: Java Similar a C++, exceto que: Todos os tipos de dados definidos pelo usuário em Java são classes Todos os objetos são alocados do monte e acessados por meio de variáveis de referência Entidades individuais em classes têm modificadores de controle de acesso (público ou privado), em vez de cláusulas Java tem um segundo mecanismo de escopo, o escopo do pacote, que pode ser usado no lugar das amigas Conceitos de Linguagens de Programação – Robert W. Sebesta Um exemplo em Java class StackClass { private: private int [] *stackRef; private int [] maxLen, topIndex; public StackClass() { // a constructor stackRef = new int [100]; maxLen = 99; topPtr = -1; }; public void push (int num) {…}; public void pop () {…}; public int top () {…}; public boolean empty () {…}; } Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplos de linguagens: C# Baseado em C++ e Java Acrescenta dois modificadores de acesso internal e protected internal Todas as instâncias de classe são dinâmicas do monte Construtores padrão são pré-definidos para todas as classes Coleção de lixo é usada para a maioria de seus objetos do monte, e os destrutores são raramente usados Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplos de linguagens: C# (continuação) A solução comum é fornecer métodos de acesso, leitores e escritores (getters e setters), que permitem que os clientes acessem indiretamente os dados chamados ocultos C# fornece propriedades, que são herdadas do Delphi, como uma maneira de implementar leitores e escritores sem requerer chamadas a métodos explícitas Conceitos de Linguagens de Programação – Robert W. Sebesta Exemplo de propriedade de C# public class Weather { public int DegreeDays { //** DegreeDays é uma propriedade get {return degreeDays;} set { if(value < 0 || value > 30) Console.WriteLine( "Value is out of range: {0}", value); else degreeDays = value;} } private int degreeDays; ... } ... Weather w = new Weather(); int degreeDaysToday, oldDegreeDays; ... w.DegreeDays = degreeDaysToday; ... oldDegreeDays = w.DegreeDays; Conceitos de Linguagens de Programação – Robert W. Sebesta Tipos de dados abstratos em Ruby A construção de encapsulamento é a classe Variáveis locais têm nomes “normais” Nomes de variáveis de instância começam com o sinal de arroba (@) Nomes de variáveis de classe começam com dois arrobas (@@) Métodos de instância têm a sintaxe de funções Ruby (def … end) Construtores são nomeados initialize (apenas um por classe) — implicitamente chamado quando new é chamado Membros de classe podem ser marcados como públicos ou privados Classes são dinâmicas Conceitos de Linguagens de Programação – Robert W. Sebesta Tipos de dados em Ruby (continuação) class StackClass { def initialize @stackRef = Array.new @maxLen = 100 @topIndex = -1 end def push(number) … end def pop … end def top … end def empty … end end Conceitos de Linguagens de Programação – Robert W. Sebesta Tipos de dados abstratos parametrizados É conveniente ser capaz de parametrizar tipos de dados abstratos, como projetar um tipo de dados abstrato pilha que possa armazenar quaisquer tipos escalares. É apenas uma questão para linguagens estaticamente tipadas Também conhecidos como classes genéricas C++, Ada, Java 5.0 e C# 2005 fornecem suporte para tipos de dados abstratos parametrizados Conceitos de Linguagens de Programação – Robert W. Sebesta Tipos de dados abstratos parametrizados em Ada Pacotes genéricos Faz o tipo de dados abstrato pilha mais flexível ao fazer o elemento do tipo e o tamanho da pilha genéricos generic Max_Size: Positive; type Elem_Type is private; package Generic_Stack is Type Stack_Type is limited private; function Top(Stk: in out StackType) return Elem_type; … end Generic_Stack; Package Integer_Stack is new Generic_Stack(100,Integer); Package Float_Stack is new Generic_Stack(100,Float); Conceitos de Linguagens de Programação – Robert W. Sebesta Tipos de dados abstratos parametrizados em C++ Classes podem se tornar genéricas ao modificar as funções construtoras class Stack { … Stack (int size) { stk_ptr = new int [size]; max_len = size - 1; top = -1; }; … } Stack stk(100); Conceitos de Linguagens de Programação – Robert W. Sebesta Tipos de dados abstratos parametrizados em C++ (continuação) O tipo de elemento da pilha pode ser parametrizado por tornar a classe uma classe de modelo template <class Type> class Stack { private: Type *stackPtr; const int maxLen; int topPtr; public: Stack() { stackPtr = new Type[100]; maxLen = 99; topPtr = -1; } … } Conceitos de Linguagens de Programação – Robert W. Sebesta Classes parametrizadas em Java 5.0 Parâmetros genéricos devem ser classes Os tipos genéricos mais comuns são os tipos de coleção, como LinkedList e ArrayList Elimina a necessidade de converter um objeto sendo removido da coleção Elimina o problema de ter múltiplos tipos em uma estrutura Conceitos de Linguagens de Programação – Robert W. Sebesta Classes parametrizadas em C# 2005 Similar às de Java 5.0 Elementos de estruturas parametrizadas podem ser acessados por meio de índices Conceitos de Linguagens de Programação – Robert W. Sebesta Construções de encapsulamento Programas grandes têm duas necessidades adicionais: Outros meios de organização, que não apenas divisão em subprogramas Meios de compilação parcial (compilação de unidades menores do que o programa inteiro) Solução óbvia: organizar os programas em coleções de códigos e dados logicamente relacionados, cada uma das quais pode ser compilada sem a recompilação do resto do programa Essa coleção é chamada de encapsulamento Conceitos de Linguagens de Programação – Robert W. Sebesta Subprogramas aninhados Os programas podem ser organizados por definições de subprogramas aninhados dentro de subprogramas logicamente maiores que os usam Isso pode ser feito em Ada, Fortran 95, Python e Ruby Conceitos de Linguagens de Programação – Robert W. Sebesta Encapsulamento em C Arquivos que contêm um ou mais subprogramas podem ser compilados independentemente A interface é colocada em um arquivo chamado de arquivo de cabeçalho Problema: o vinculador não verifica os tipos entre um cabeçalho e implementação associados Especificação de pré-processador #include – usado para incluir arquivos de cabeçalho Conceitos de Linguagens de Programação – Robert W. Sebesta Encapsulamento em C++ Pode definir arquivos de cabeçalho e arquivos de código, como em C Classes também podem ser usadas para encapsulamento Funções amigas (friends) dão acesso às entidades privadas da classe onde elas são declaradas como amigas Conceitos de Linguagens de Programação – Robert W. Sebesta Pacotes em Ada Pacotes de especificação em Ada podem incluir qualquer número de declarações de dados ou de subprogramas em suas seções pública e privada Pacotes Ada podem ser compilados separadamente As duas partes do pacote, especificação e corpo, também podem ser compiladas separadamente se o pacote de especificação for compilado primeiro Conceitos de Linguagens de Programação – Robert W. Sebesta Montagens em C# Uma coleção de um ou mais arquivos que aparecem para os programas aplicativos como uma única biblioteca de ligação dinâmica ou executável Cada arquivo define um módulo, que pode ser desenvolvido separadamente Uma biblioteca de ligação dinâmica (DLL) é uma coleção declasses e métodos individualmente ligados a um programa que está executando C# tem um modificador de acesso, chamado internal; um membro internal de uma classe é visível para todas as classes na montagem na qual ele aparece Conceitos de Linguagens de Programação – Robert W. Sebesta Nomeando encapsulamentos Um grande programa pode ser escrito por muitos desenvolvedores, trabalhando de maneira independente, o que requer que as unidades lógicas sejam independentes Encapsulamentos de nomeação definem escopos de nome que ajudam a evitar esses conflitos Espaços de nome em C++ Pode colocar cada biblioteca em seu próprio espaço de nome e qualificar os nomes utilizados fora do espaço C# também inclui espaços de nome Conceitos de Linguagens de Programação – Robert W. Sebesta Nomeando encapsulamentos (continuação) Pacotes em Java Pacotes podem conter mais de uma definição de classe, e as classes em um pacote são amigas parciais umas das outras Os clientes de um pacote podem referenciar nomes definidos no pacote usando nomes completamente qualificados Pacotes em Ada Pacotes são definidos em hierarquias, que correspondem às hierarquias de arquivos, nas quais eles são armazenados A visibilidade a um pacote a partir de uma unidade de programa é obtida com a cláusula with Conceitos de Linguagens de Programação – Robert W. Sebesta Nomeando encapsulamentos (continuação) Classes Ruby são encapsulamentos de nomeação, mas Ruby tem também módulos Módulos normalmente definem coleções de métodos e constantes Módulos são diferentes das classes de forma que eles não podem ser instanciados ou estendidos por herança e nem definem variáveis Os módulos são discutidos mais detalhadamente no Capítulo 12 Conceitos de Linguagens de Programação – Robert W. Sebesta Resumo O conceito de tipos de dados abstratos, e seu uso em projeto de programas, foi um marco no desenvolvimento da programação como uma disciplina de engenharia Seus dois recursos principais são o empacotamento de objetos de dados com suas operações associadas e o ocultamento de informações Ada fornece encapsulamentos chamados pacotes que simulam tipos de dados abstratos A abstração de dados em C++ é fornecida pelas classes Em Java, são similares às de C++ Ada, C++, Java 5.0 e C# 2005 permitem que seus tipos de dados abstratos sejam parametrizados C++, C#, Java, Ada e Ruby fornecem encapsulamentos de nomeação *
Compartilhar