Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 Professores: Dante Corbucci Filho Alexandre Plastino Aula 14 Conteúdo: - Construção e Uso de Bibliotecas - Introdução a Orientação a Objetos 2 Construção e Uso de Bibliotecas Em Pascal, podemos reutilizar código previamente implementado e compilado. Como visto na aula 3, podemos acessar códigos de bibliotecas através da seção de declaração Uses. Assim, por exemplo, para acessarmos a operação que limpa o conteúdo da tela, basta declararmos Uses Crt e chamarmos o procedimento clrscr no programa principal ou subprograma. Da mesma forma que podemos utilizar bibliotecas padrão como a Crt do Pascal, também podemos criar nossas próprias bibliotecas, chamadas unidades ("Units"). 3 Construindo uma Unidade (Unit) Uma unidade é um arquivo pascal que pode conter declarações de: constantes, tipos, variáveis, procedimentos e funções. Unit Nome; Interface ... {O quê: declarações a serem visíveis externamente} Implementation ... {Como: Implementações das operações oferecidas} Begin ... {Inicializações de variáveis ou outros "efeitos colaterais" } End. 4 Exemplo de Unidade Unidade para manipulação de vetores, de qualquer tamanho, de números reais: com operações de leitura, escrita e ordenação pelo método da seleção. {Arquivo fonte Ops_Vetor.Pas} Unit Ops_Vetor; Interface procedure ler_vetor(Var V{s}: Array of real); procedure escrever_vetor(V{e}: Array of real); procedure ordenar_por_selecao(Var V{e/s}: Array of real); Implementation ... {Como: Implementações das operações oferecidas} Begin ... {Pode ser suprimida neste exemplo - Inclusive o Begin} End. 5 Exemplo de Unidade Implementation procedure ler_vetor(Var V{s}: Array of real); begin end; procedure escrever_vetor(V{e}: Array of real); begin end; procedure ordenar_por_selecao(Var V{e/s}: Array of real); begin end; End. 6 Exemplo de Unidade ... Implementation ... procedure escrever_vetor(V{e}: Array of real); var ind: integer; begin for ind:=low(V) to high(V) do write(output, V[ind]:5:1); writeln(output); end; ... End. 7 Exemplo de Unidade ... Implementation procedure ler_vetor(Var V{s}: Array of real); var ind: integer; begin for ind:=low(V) to high(V) do begin write(output, ’Célula[’, ind, ’]= ’); readln(input, V[ind]); end; end; ... End. 8 procedure ordenar_por_selecao(Var V{e/s}: Array of real); procedure Trocar(Var A {e/s}, B{e/s}: real); begin end; procedure Selecionar(Vet{e}: Array of real; P{e}: Integer; Var Onde{s}: integer); begin end; var Inicio, Posicao: integer; begin for Inicio:= low(V) to high(V)-1 do begin Selecionar(V, Inicio, Posicao); Trocar(V[inicio], V[Posicao]); end; end; 9 procedure ordenar_por_selecao(Var V{e/s}: Array of real); procedure Trocar(Var A {e/s}, B{e/s}: real); Var Temp: real; begin Temp:= A; A:= B; B:= Temp; end; procedure Selecionar(Vet{e}: Array of real; P{e}: Integer; Var Onde{s}: integer); Var Indice: Integer; begin Onde:= P; For Indice:= P+1 to high(Vet) do if Vet[Indice]<Vet[Onde] then Onde:= Indice; end; begin ... end; 10 Compilando uma Unidade Uma unidade pode ser apenas compilada e não executada. O nome do arquivo fonte que contém uma unidade Nova deve se chamar Nova.pas. Este arquivo quando compilado gera o arquivo chamado Nova.ppu, que será acessado pelo Carregado/Ligador para fazer a montagem do código final de um programa (ou unidade) que utiliza uma (outra) unidade. No nosso exemplo, a unidade Ops_Vetor está no arquivo Ops_Vetor.pas que, quando compilado, gera o arquivo Ops_Vetor.ppu, a ser utilizado a seguir. 11 Acesso à Biblioteca (exemplo visto na aula 6) Program Classico(input{teclado}, output{vídeo}); Uses Ops_Vetor; Const Tam = 10; Type T_Dominio = 1..Tam; T_Vetor = Array[T_Dominio] of real; Var A: T_Vetor; Begin ler_vetor(A); ordenar_por_selecao(A); escrever_vetor(A); End. 12 Algumas das Unidades Pré-definidas Graph: que oferece recursos para utilizar o vídeo no modo gráfico. Algumas Operações Oferecidas: GraphResult, InitGraph(C,M,Dir), CloseGraph, Moveto(X,Y), Lineto(X,Y), setcolor(C), etc. DOS: que oferece operações associadas ao sistema operacional. Alguns Procedimentos: GetDate/SetDate(A,M,D,S), GetTime/SetTime(H,M,S,C), etc CRT: que oferece recursos para utilizar o vídeo no modo texto, o teclado e o som do computador. Constantes Oferecidas: Black, Blue, Green, Cyan, Red, Magenta, Brown, LightGray, DarkGray, LightBlue, LightGreen, LightCyan, LightRed, LightMagenta, Yellow, White. Funções Oferecidas: Keypressed, Readkey, WhereX, WhereY. Alguns Procedimentos Oferecidos: Clrscr, Delay(N), Gotoxy(X,Y), TextColor(C), TextBackground(C), Sound(F), Window(X1,Y1,X2,Y2), etc. 13 Exemplo com Modo Gráfico program grafico(input{teclado}, output{vídeo}); uses graph, crt; var Controlador, Modo: integer; begin Controlador:= 0; InitGraph(Controlador, Modo, ’’); if GraphResult<>0 then writeln(output, ’erro na inicialização do modo gráfico’) else begin randomize; moveto(random(800),random(600)); repeat delay(1000); setcolor(random(65000)); lineto(random(800), random(600)); until random(50)=13; CloseGraph; end; end. Código Fonte Como Executar 14 Exemplo com uso da DOS Program Periodo(input{teclado}, output{vídeo}); uses dos; var h,m,s,c: word; begin gettime(h,m,s,c); writeln(output, ’Comecei a rodar às ’, h,’:’, m,’:’,s,’:’,c); write(output, ’Tecle enter para terminar’); readln(input); gettime(h,m,s,c); writeln(output, ’Terminou às :’, h,’:’, m,’:’,s,’:’,c); end. Executável Código Fonte 15 Introdução a Orientação a Objetos Os mecanismos presentes numa linguagem orientada a objetos são: Encapsulamento de Dados, Herança e Polimorfismo. Todos estes mecanismos estão presentes na linguagem Pascal. Herança: é o mecanismo que permite o uso de objetos (classes) previamente implementados de forma a compor um novo objeto (classe), adicionando ou modificando operações bem como adicionando novos campos. Polimorfismo: é a capacidade de uma linguagem permitir a definição de comportamento da operação a ser executada a partir dos parâmetros que a operação recebe durante a execução do programa. No Pascal, esta capacidade é declarada em um objeto através dos subprogramas vituais, permitindoa conexão tardia ("late binding"). Nesta introdução, nosso foco será apenas sobre o Encapsulamento de Dados, enquanto que os mecanismos de herança e polimorfismo serão abordados em outras disciplinas do curso. 16 Introdução a Orientação a Objetos Voltando a equação do Wirth: Programa = Algoritmo + Estrutura de Dados Até aqui, há uma separação entre dado e seu processamento. No entanto, veremos agora como embutir uma camada de software sobre a estrutura de dados primitiva. Desta forma, nossos registros (records) terão, além dos campos de dados, operações associadas (procedimentos e funções). Esta combinação de dados e operações é chamada de Tipo Abstrato de Dado (TAD). A terminologia Pascal denominou Object este novo estruturador de dado com operações, que pode ser visto como uma generalização do Record, previamente visto. 17 Objetos e Unidades Em Pascal, para garantir a proteção do acesso aos dados, todo objeto deve estar contido em uma unidade. Unit TAD_Exemplo; Interface uses ...; Type T_Exemplo = Object private {campos e cabeçalhos das operações privadas} public {campos e cabeçalhos das operações públicas} End; Implementation ... {todas as operações devem ser implementadas aqui} end. 18 Objetos e Unidades: Encapsulamento do Dado Parte Privada Dados Protegidos Op3 Op1 Op4 Op2 Parte Pública Usuário Usuário 19 Exemplo: O Tipo Abstrato de Dado Pilha Pilha é um tipo abstrato de dado linear e recursivo que possui a política LIFO ("Last In First Out" - Último a Entrar Primeiro a Sair") de acesso a seus dados. As operações sobre uma pilha são: • Inicializar: que estabelece um estado inicial na estrutura de dado; • Empilhar: que insere um elemento no topo da pilha; • Desempilhar: que remove um elemento do topo da pilha; • Topo: que permite o acesso ao elemento que está sobre a pilha; • Vazia: função que informa se o estado da pilha é análogo ao inicial; • Cheia: função que informa se a pilha ainda admite a inserção de novo elemento; • Tamanho: função que informa o número de elementos que estão na pilha. A ? B A 20 Exemplo: O Tipo Abstrato de Dado Pilha Pilha é um tipo abstrato de dado linear e recursivo que possui a política LIFO ("Last In First Out" - Último a Entrar Primeiro a Sair") de acesso a seus dados. A estrutura de dado concreta, isto é, o dado sem proteção, poderia ser implementado estaticamente como vetor ou dinamicamente como arquivo ou como ponteiro. Veremos duas destas três possibilidades de implementação: por ponteiro e por vetor (array). Independente de qual implementação adotemos, a interface será sempre a mesma, mostrando a abstração oferecida a um usuário de tal objeto. Desta forma, o usuário do tipo abstrato de dado pilha não se preocupa como ele foi implementado, mas como se comporta. O acesso aos dados sempre será via operações, ou seja, por procedimentos ou por funções. 21 unit tad_pilha; interface uses basica; type T_Pilha = Object private Nucleo: T_Concreto; public procedure inicializa; function vazia: boolean; function cheia: boolean; function tamanho: longint; procedure topo(Var X{s}: T_Info; Var OK{s}: boolean); procedure empilha(X{e}: T_Info; Var OK{s}: boolean); procedure desempilha(Var OK{s}: boolean); end; Implementation End. Núcleo desempilha empilha inicializa vazia cheia topo tamanho 22 O Tipo Concreto por Ponteiro: unit basica; interface type T_Pont = ^T_no; T_Info = real; T_no = record info: T_Info; prox: T_Pont; end; T_Concreto = record Total: LongInt; Superior: T_Pont; end; implementation end. 23 O Tipo Concreto por Array: unit basica; Interface const Max = 100; type T_Dominio = 1..Max; T_Info = real; T_Vetor = array[T_Dominio] of T_Info; T_Concreto = record Total: LongInt; Superior: T_Vetor; end; implementation end. 24 Os "stubs" do tipo abstrato de dado T_Pilha: implementation procedure T_Pilha.inicializa; begin end; function T_Pilha.vazia: boolean; begin end; function T_Pilha.cheia: boolean; begin end; function T_Pilha.tamanho: Longint; begin end; procedure T_Pilha.topo(Var X{s}: T_Info; Var OK{s}: boolean); begin end; procedure T_Pilha.empilha(X{e}: T_Info; Var OK{s}: boolean); begin end; procedure T_Pilha.desempilha(Var OK{s}: boolean); begin end; end. 25 procedure T_Pilha.inicializa; begin Nucleo.total:=0; Nucleo.Superior:= nil; end; function T_Pilha.vazia: boolean; begin vazia:= (Nucleo.total=0); end; function T_Pilha.cheia: boolean; begin cheia:= (maxavail<sizeof(T_No)); end; function T_Pilha.tamanho: Longint; begin tamanho:= Nucleo.total; end; Por Ponteiro 26 procedure T_Pilha.topo(Var X{s}: T_Info; Var OK{s}: boolean); begin ok:= not vazia; if ok then X:= Nucleo.Superior^.Info end; procedure T_Pilha.empilha(X{e}: T_Info; Var OK{s}: boolean); var nasceu: T_Pont; begin ok:= not cheia; if ok then begin new(nasceu); nasceu^.info:= X; nasceu^.prox:= Nucleo.Superior; Nucleo.Superior:= nasceu; inc(Nucleo.total); end; end; Por Ponteiro 27 Implementação por Ponteiro: procedure T_Pilha.desempilha(Var OK{s}: boolean); var morrera: T_Pont; begin ok:= not vazia; if ok then begin morrera:= Nucleo.Superior; Nucleo.Superior:= morrera^.prox; dec(Nucleo.total); dispose(morrera); end; end; 28 Implementação por Array: procedure T_Pilha.inicializa; begin Nucleo.total:=0; end; function T_Pilha.vazia: boolean; begin vazia:= (Nucleo.total=0); end; function T_Pilha.cheia: boolean; begin cheia:= (Nucleo.total=Max); end; function T_Pilha.tamanho: Longint; begin tamanho:= Nucleo.total; end; 29 procedure T_Pilha.topo(Var X{s}: T_Info; Var OK{s}: boolean); begin ok:= not vazia; if ok then X:= Nucleo.Superior[Nucleo.total] end; procedure T_Pilha.empilha(X{e}: T_Info; Var OK{s}: boolean); begin ok:= notcheia; if ok then begin inc(Nucleo.total); Nucleo.Superior[Nucleo.total]:= X end; end; procedure T_Pilha.desempilha(Var ok{s}: boolean); begin ok:= not vazia; if ok then dec(Nucleo.total); end; Por Array 30 program utiliza_pilhas(input{teclado}, output{vídeo}); uses tad_pilha; var pa, pb: T_Pilha; item: real; ok: boolean; quantos: integer; begin randomize; pa.inicializa; pb.inicializa; write(output, ’Diga quantos são os elementos: ’); readln(input, Quantos); repeat pa.empilha(random(1000), ok); until pa.tamanho = Quantos; writeln(output, ’--------------------------------------------’); while not pa.vazia do begin pa.topo(item, ok); writeln(output, item:3:0); pa.desempilha(ok); pb.empilha(item, ok); end; writeln(output, ’--------------------------------------------’); while not pb.vazia do begin pb.topo(item, ok); writeln(output, item:3:0); pb.desempilha(ok); end; end. 31 Utilizando Objetos: Vantagens Como exemplificado no programa utiliza_tad, um usuário de um tipo abstrato de dado, como o T_Pilha, não se importa como ele foi implementado, mas sim, o que acontece quando chamamos cada operação daquele objeto. Esta abstração de detalhes leva a uma produtividade maior do código sendo implementado, dado que o programa fica menor e mais intuitivo. A cada objeto implementado (ou utilizado de outros programadores) vai se enriquecendo sua biblioteca de componentes de software, que a cada uso se mostra mais confiável. 32 Tópicos Abordados: 1. Construção e Uso de Bibliotecas • Construímos a unidade Ops_Vetor; • Utilizamos a unidade Ops_Vetor no programa Classico; • Vimos operações de unidades Pré-definidas: Crt, Dos e Graph; • Implementamos programas utilizando Crt, Dos e Graph. 2. Introdução a Orientação a Objetos • Mecanismos: Herança, Polimorfismo e Encapsulamento; • Record -> Object • Objetos e unidades; • Exemplo T_Pilha na TAD_Pilha: Implementações por ponteiro e por array; • Utilizamos instâncias do objeto T_Pilha no programa utiliza_pilhas; • Vantagens. 33 Professores: Dante Corbucci Filho Alexandre Plastino Aula 14 Conteúdo: - Construção e Uso de Bibliotecas - Introdução a Orientação a Objetos
Compartilhar