A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Programação aplicada de computadores Profa. Andréa Maria Pedrosa Valli www.inf.ufes.br/~avalli 2012/1 – Engenharia Elétrica.

Apresentações semelhantes


Apresentação em tema: "Programação aplicada de computadores Profa. Andréa Maria Pedrosa Valli www.inf.ufes.br/~avalli 2012/1 – Engenharia Elétrica."— Transcrição da apresentação:

1 Programação aplicada de computadores Profa. Andréa Maria Pedrosa Valli 2012/1 – Engenharia Elétrica

2 Objetivo da Disciplina: Proporcionar uma visão geral sobre os conceitos definidos em programação orientada a objetos através do aprendizado da linguagem C++. Conteúdo: Introdução Princípios da Programação Estruturada Classes e Objetos Composição e Herança Polimorfismo Exceções Livro Texto: H.M. Deitel e P.J. Deitel, C++: como Programar, 5 ed., Bookman, 2006.

3 Avaliação : Através de exercícios computacionais (Exerc) e provas escritas (PrEscr). A média parcial final é calculada da seguinte forma: 0.5 * Exerc * Entrevista * PrEscr, onde cada um dos termos corresponde a média aritmética dos exercícios e provas respectivamente. A nota da entrevista varia entre 0 e 1 e Exerc = 0.2 * Lista * Trabalho. A Segunda Chamada é para quem faltou alguma prova e justificou (essa prova pode ser escrita ou aplicada no computador). Homepage da Disciplina:

4 Introdução: Panorâmica da programação orientada a objetos Referência: Antonio Mendes da Silva Filho, Introdução à Programação Orientada a Objetos com C++, Rio de Janeiro: Elsevier, Objetivos: Entender o porquê do surgimento do paradigma de programação orientada a objetos (PPO). Contextualizar as diferenças entre programação orientada a objetos e a programação estruturada. Apresentar as principais características das linguagens de programação orientada a objetos. Discutir as principais diferenças entre as linguagens C e C++. Linguagens: C++,C#, Object Pascal, Java, Python, SmallTalk, Matlab

5 Cada programa consiste em um conjunto organizado de instruções que operam sobre um conjunto de dados, processando-os, a fim de realizar alguma funcionalidade e produzir uma saída. Obs: A medida que os sistemas crescem, cresce a complexidade associada a eles. Antes da POO, o programador era ensinado a raciocinar sobre os problemas em termos de blocos de códicos (funções) ou procedimentos e sobre a forma como esses blocos atuavam sobre os dados (linguagens procedimentais). A POO é uma linguagem de programação que foi criada, baseada no raciocínio de classificação e manipulação do ambiente em que vivemos.

6 Linguagens Procedimentais: Fortran, Pascal, C, Basic Um programa em uma linguagem procedimental é uma lista de instruções organizada em termos de funções e módulos (um agrupamento de várias funções em uma entidade maior). Dividir um programa em funções e módulos é um dos fundamentos da programação estruturada e os dados constituem a essência de um sistema. Questão: O que acontece com os dados no paradigma de programação orientada a procedimentos? Variáveis globais Acessível a qualquer função Variáveis locais Função F1 Acessível apenas à função F1 Variáveis locais Função F2 Acessível apenas à função F2

7 Características das linguagens orientadas a objetos Encapsulamento de dados: Os dados e funções são encapsulados em uma entidade – o objeto. As funções de um objeto em C++ são chamadas funções-membros e oferecem uma única forma de acesso aos dados. Não se pode acessar os dados diretamente (ocultação dos dados). dados Função-membro dados Função-membro dados Função-membro Objeto

8 Vantagens do encapsulamento de dados: Uma grande vantagem do encapsulamento é que toda parte encapsulada pode ser modificada sem que os usuários da classe em questão sejam afetados. Ex: liquidificador O encapsulamento protege o acesso direto (referência) aos atributos (variáveis) de uma instância (molde) fora da classe onde estes foram declarados (use get e set para retornar e modificar o valor do atributo de um objeto).atributosinstânciaclasse Encapsular atributos também auxilia a garantir que o estado e o comportamento de um objeto se mantenha coeso. Ex: semáforo Obs: Em termos intuitivos, uma classe é vista como um "molde" que gera instâncias de um certo tipo, já objeto é algo que existe fisicamente moldado a partir desse molde.

9 Terra Marítimo Aéreo Estrada Ferroviário Navios Submarinos Barcos Aviões Balões Helicópteros Duas Rodas Quatro Rodas Motocicletas Biclicletas Trem Bonde Automóveis Caminhões Ônibus Metrô Passageiros Cargueiros Gerra Pesquisas Pesca Transporte CombateTransporte Raciocínio em termos de objetos: diz-se que os objetos são membros de classes. Ex: um fusca é um objeto da classe Automóveis.

10 Classe: uma classe serve como um padrão, modelo ou template. Ela especifica quais dados e quais funções serão incluídos nos objetos daquela classe. Definir uma classe não cria quaisquer objetos, assim como a simples existência de um tipo de dados int não cria quaisquer variáveis. Uma classe é, portanto, um conjunto de objetos similares. Herança: o princípio de herança considera a divisão de uma classe em subclasses que compartilham características comuns com a classe da qual ela é derivada. classes derivadas A B A B C A B E D classe base Reusabilidade: uma vez que uma classe tenha sido criada, escrita e depurada, ela pode ser usada por outros programadores em seus programas. Mais ainda, o programador pode adicionar novas características a ela, sem modificá-la.

11 Criação de novos tipos de dados: um dos benefícios dos objetos é que eles oferecem ao programador uma forma conveniente de construir novos tipos de dados. Ex: trabalhar com coordenadas x e y e operações aritméticas normais do tipo posicao1 = posicao2 + origem, onde as variáveis posicao1, posicao2 e origem representam coordenadas. Polimorfismo e Overloading (Sobrecarga): podemos definir novas operações para serem usados em novos tipos de dados. No exemplo acima, os operadores = (igual) e + (soma) são definidos pelo programador para a classe Posicao. Usar operadores ou funções de formas diferentes, dependentes do que eles estão operando, é denominado polimorfismo. Quando um operador existente tem a capacidade de ser usado em novos tipos de dados, diz-se que ele está sobrecarregado (overloaded). Overloading é um tipo de polimorfismo e mais um das características de C++. Diferenças entre C e C++: C++ é uma linguagem derivada de C. Portanto, C++ retém a maioria das características da linguagem C e oferece suporte à maior quantidade de estilos de programação, tornando-a mais versátil e flexível. Os elementos mais importantes adicionados ao C para criar o C++ compreendem classes, objetos e a POO. Além disso, inclui uma abordagem melhorada de entrada e saída (E/S) e nova forma para comentários.

12 Introdução: Um passeio por C++ O que é C++ segundo Bjarne Stroustrup (o criador de C++, A Linguagem de Programação C++, 3ed., Bookman): é uma C melhor suporta abstração de dados, suporta programação orientada a objetos e suporta programação genérica. Objetivo desta introdução: Fornecer uma visão geral de C++ e as principais técnicas para usá- la mas omitindo os detalhes da programação. Concentre-se em técnicas de programação e não em recursos de linguagem.

13 1.Paradigmas de programação 2.Programação orientada a procedimentos 3.Programação modular 4.Abstração de dados 5.Programação orientada a objetos 6.Programação genérica Conteúdo

14 1. Paradigmas de programação Programação orientada a objetos é uma técnica de programação - uma paradigma para escrever bons programas para um conjunto de problemas. A linguagem fornece bons mecanismo de suporte ao estilo de programação orientada a objetos. Uma linguagem suporta um estilo de programação se ela fornece facilidades que tornem conveniente (razoavelmente fácil, seguro e eficiente) usar aquele estilo. Uma linguagem não é necessariamente melhor que uma outra porque ela possui um recurso que a outra não tem, mas se os recursos que ela tem são suficientes para suportar os estilos de programação desejados nas áreas de aplicações pretendidas.

15 Princípios (estética e lógica, minimalismo, o que você não sabe não pode feri-lo): 1.Todos os recursos devem ser claros e elegantemente integrados nas linguagem; 2.Deve ser possível usar recursos combinados; 3.Deve haver pouco recursos espúrios e de propósito especial; 4.A implementação de um recurso não deve impor uma significativa sobrecarga a programas que não exigem seu uso; 5.Um usuário necessita saber apenas o subconjunto da linguagem explicitamente usado para escrever um programa. C++ foi projetada para suportar abstração de dados, programação orientada a objetos e programação genérica adicionalmente a técnicas de programação tradicional de C.

16 2. Programação orientada a procedimentos Paradigma: Decida quais procedimentos você quer; use os melhores algoritmos que você puder encontrar. O foco é no procedimento – o algoritmo necessário para executar a computação desejada. A linguagem possui facilidades para passar/retornar argumentos para funções. Recursos para expressar computações: variáveis e aritmética testes e laços ponteiros e arrays

17 #include using namespace std; const double PI = ; // define global constant PI // calculates volume of a sphere inline double sphereVolume( const double radius ) { return 4.0 / 3.0 * PI * pow( radius, 3 ); } // end inline function sphereVolume int main() { double radiusValue; // prompt user for radius cout << "Enter the length of the radius of your sphere: "; cin >> radiusValue; // input radius // use radiusValue to calculate volume of sphere and display result cout << "Volume of sphere with radius " << radiusValue << " is " << sphereVolume( radiusValue ) << endl; return 0; // indicates successful termination } // end main

18 3. Programação modular Com os anos, o enfoque mudou para a organização dos dados. Quando não existem agrupamentos de procedimentos com dados relacionados, a programação orientada a procedimentos é suficiente. Um conjunto de procedimentos relacionados com os dados que eles manipulam é denonimado módulo. Paradigma: Decida quais módulos você quer; particione o programa de modo a esconder os dados dentro dos módulos (o princípio da ocultação de dados). Exemplo de um módulo: uma pilha

19 namespace Pilha { // interface void empilha( char ); -----> arquivo pilha.h char desempilha( ); } # include pilha.h void f( ) { Pilha::empilha(c); if( Pilha::desempilha( ) != c ) error( impossivel ); -----> arquivo usuario.c } #include pilha.h namespace Pilha { // implemetacao const int tamanho_max = 200; ); -----> arquivo pilha.c char v[tamanho_max]; int topo = 0; void empilha( char c ) { /* testa transbordamento e empilha c */} void desempilha( ) { /* testa esvaziamento e desempilha */ } } Na definição da pilha devemos: fornecer uma interface com o usuário para a pilha; assegurar que a representação da pilha possa ser acessada somente através de sua interface com o usuário; assegurar que a pilha seja inicializada antes de ser usada pela primeira vez.

20 Compilação separada: C++ suporta a noção de compilação separada de C, ou seja, pode ser usado para organizar um programa como um conjunto de trechos semi-independentes.

21 Tratamento de exceções: À medida que os programas crescem e bibliotecas são extensivamente usadas, padrões para tratamento de erros (ou, de modo mais geral, circunstâncias especiais) se tornam importantes. namespace Pilha { // interface void empilha ( char ); char desempilha ( ); class Transbordou { }; // tipo representando excecoes de transbordamento } void Pilha::empilhar( char c ) { if ( topo == tamanho_max ) throw Transbordou( ); // empilha c } void f( ) { //... try { // excecoes que sao tratadas pelo tratador definido abaixo while ( true ) Pilha::empilha ( c ); } catch ( Pilha::Transbordou ) { // oops: transbordamento de pilhas; tome a acao apropriada } //... }

22 C++ permite que o usuário defina diretamente tipos que se comportam (aproximadamente) do mesmo modo que os tipos primitivos. Paradigma: Decida quais tipos você quer; providencie um conjunto completo de operações para cada tipo. Podemos ter por exemplo: definição de tipos em módulos- Ex: namespace Pilha com struct tipos definidos pelo usuário- Ex: classe de número complexos tipos concretos - Ex: class Pilha tipos abstratos (a interface isola mais completamente um usuário dos detalhes de implementação) – Ex: class Pilha funções virtuais – tabela de funções virtuais 4. Abstração de dados

23 1. Definição de tipos em módulos Exemplo : definir um gerenciador de pilhas namespace Pilha { struct Rep; // definicao do layout da pilha esta em algum lugar typedef Rep& pilha; pilha cria ( ); // fazer uma nova pilha void destroi ( pilha s ); // destruir s void empilha ( pilha s, char c ); // inserir c em s char desempilha ( pilha s ); // desempilha em s } Uso: struct Error_desempilha{ }; void f ( ) { Pilha::pilha s1 = Pilha::cria ( ); // fazer uma nova pilha Pilha::pilha s2 = Pilha::cria ( ); // fazer uma outra nova pilha Pilha::empilha ( s1, c ); Pilha::empilha ( s2, k ); if ( Pilha::desempilha ( s1 ) != c ) throw Desempilha_mal ( ); if ( Pilha::desempilha ( s2 ) != k ) throw Desempilha_mal ( ); Pilha::destroi ( s1 ); Pilha::destroi ( s2 ); }

24 2. Tipos definidos pelo usuário: números complexos é um exemplo class complex { double re, im; public: complex ( double r, double I ) { re = r; im = I; } // constroi complexo a partir de dois escalares complex ( double r ) { re = r, im = 0; } // constroi complexo a partir de um escalar complex ( ) { re = im = 0; } // constroi default (0,0) friend complex operator+ ( complex, complex ); friend complex operator- ( complex, complex ); // binario friend complex operator- ( complex ); // unario friend complex operator* ( complex, complex ); friend complex operator/ ( complex, complex ); friend bool operator== ( complex, complex ); // igual friend bool operator!= ( complex, complex ); // diferente //... }; complex operator+ ( complex a1, complex a2 ) { return complex ( a1.re + a2.re, a1.im + a2.im ); } void f ( complex z ) { complex a = 2.3; complex b = 1/a; complex c = a + b*complex(1,2.3); // … if ( c!= b ) c = - (b/a) + 2*b; //... }

25 3. Tipos concretos: como exemplo, considere um tipo Pilha definido pelo usuário da seguinte forma: class Pilha { char* v; int topo; int tamanho_max; public: Pilha ( int s ) // construtor ~Pilha ( ) // destruidor class Transbordou { }; // usada como excecao class Esvaziou { }; // usada como excecao class Erro_tamanho { }; // usada como excecao void empilha ( char c ); char desempilha ( ); }; Uso: Pilha s_var1 ( 10 ); // pilha global com 10 elementos void f ( Pilha& s_ref, int i ) { // referencia a Pilha Pilha s_var2 ( i ); // pilha local com i elementos Pilha* s_ptr = new Pilha ( 20 ); // ponteiro para Pilha alocada na memoria livre s_var1.empilha ( a ); s_var2.empilha ( b ); s_ref.empilha ( c ); s_ptr->empilha ( d ); //...

26 4. Tipos abstratos: Ex: uma pilha definida como um tipo abstrato de dados. class Pilha { public: class Transbordou { }; // usada como excecao class Esvaziou { }; // usada como excecao virtual void empilha ( char c ) = 0; virtual char desempilha ( ) = 0; }; Uso: void f( Pilha& s_ref ) { s_ref.empilha ( c ); if ( s_ref.desempilha ( ) != c ) throw Erro_desempilha ( ) ; } A palavra virtual significa em C++ que pode ser redefinida posteriormente em uma classe derivada a partir desta. A classe derivada de Pilha fornece uma implementação para a interface de Pilha e a sintaxe = 0 indica que alguma classe derivada de Pilha deve definir esta função. Desta forma, esta Pilha pode servir como uma interface para qualquer classe que tenha uma implementação das funções empilha() e desempilha(). É um tipo polimórfico, ou seja, fornece a interface para diversas outras classes.

27 Implementações: class Array_pilha : public Pilha { // Array_pilha implementa Pilha char* p; int topo; int tamanho_max; public: Array_pilha ( int s ); ~Array_pilha ( ); void empilha ( char c ) ; char desempilha ( ) ; }; class Lista_pilha : public Pilha { // Lista_pilha implementa Pilha list lc; public: Lista_pilha ( ) { } void empilha ( char c ) { lc.push_front ( c ); } //... Uso: void g ( ) { Array_pilha as( 200 ); f( as ); }; void h ( ) { Lista_pilha ls; f( ls ); };

28 5. Funções virtuais: void f( Pilha& s_ref ) { s_ref.empilha ( c ); if ( s_ref.desempilha ( ) != c ) throw Erro_desempilha ( ) ; } Como pode a chamada s_ref.empilha ( ) ser resolvida em relação à definição da função certa? Quando f() é chamada em g(), Array_pilha::empilha() deve ser chamada. Quando f() é chamada em h(), Lista_pilha::empilha() deve ser chamada. Tabela de funções virtuais (vtbl):

29 5. Programação orientada a objetos Paradigma: Decida quais tipos você quer; providencie um conjunto completo de operações para cada classe; explicite as coisas em comum através do uso de herança. Ex: problemas com tipos concretos class Ponto { /*... */ } class Cor { /*... */ } enum Tipo { circulo, triangulo, quadrado }; class Forma { Tipo k; // campo de tipo Ponto centro; Cor co; //... public: void desenha ( ); void rotacao ( int ); //... };

30 void Forma::desenha ( ) { switch ( k ): case circulo: // desenha um circulo break; case triangulo: // desenha um circulo break; case quadrado: // desenha um circulo break; } Hierarquia de classes class Forma { Ponto centro; Cor co; //... public: Ponto onde ( ) { return centro; } void move ( Ponto to ) { centro = to; /*... */ desenha ( ); } virtual void desenha ( ) = 0; virtual void rotacao ( int angulo ) = 0; //... };

31 Para definir uma forma particular, precisamos dizer que é uma Forma e especificar suas propriedades particulares (incluindo as funções virtuais): class Circulo : public Forma { // classe derivada da classe base Forma int raio; public: void desenha ( ) { /*... */ } void rotacao ( int ) { } // a funcao nula ; }; Diz-se que a classe derivada herda membros de sua classe base, de forma que o uso das classes base e derivadas é habitualmente chamado de herança. Encontrar a quantidade de propriedades em comum entre tipos que possam ser explorados usando-se herança e funções virtuais não é um processo trivial na escrita de um projeto em POO. O projetista experiente aplica diversos paradigmas, de acordo com as necessidades.

32 6. Programação genérica Paradigma: Decida que algoritmos você quer; parametrize-os de forma que eles funcionem para diversos tipos e estruturas de dados desejados. Ex: uma pilha de qualquer coisa, substituindo o tipo específico char por um parâmetro de gabarito: template class Pilha { T* v; int tamanho_max; int topo; public: Pilha ( int s ); // constutor ~Pilha ( ); // destruidor class Esvaziou { }; class Transportou { }; void empilha ( T ); T desempilha ( ); };

33 As funções membro podem ser definidas de forma similar: template void Pilha ::empilha( T c ) { If ( topo == tamanho_max ) throw Transbordou ( ); v[topo] = c; topo = topo + 1; } template T Pilha ::desempilha( ) { If ( topo == 0 ) throw Esvaziou ( ); topo = topo - 1; return v[topo]; } Uso: Pilha sc( 200 ); // pilha de 200 caracteres Pilha scplx ( 30 ); // pilha de 30 numeros complexos Pilha > sli ( 45 ); // pilha de 45 listas de inteiros void f ( ) { sc.empilha ( c ); if ( sc.desempilha ( ) != c ) throw Erro_desempilha ( ); scplx.empilha ( complex ( 1, 2 ) ); If ( scplx.desempilha ( ) != complex( 1, 2 ) ) throw Erro_desempilha ( ); }

34 Similarmente, podemos definir listas, vetores, etc., como gabaritos. Gabaritos são um mecanismo de tempo de compilação, de modo que seu uso não implica em nenhuma sobrecarga em tempo de execução quando comparado com com código escrito a mão. Uma classe contendo uma coleção de elementos de algum tipo é habitualmente chamada de contêiner ou simplemente contêiner. A biblioteca padrão C++ oferece uma variedade de contêineres e os usuários podem escrever seus próprios contêineres. Conselhos dados pelo autor, Bjarne Stroustrup: 1.Não se assuste! Tudo se tornará claro a tempo; 2.Você não precisa conhecer cada detalhe de C++ para escrever bons programas; 3.Concentre-se em técnicas de programação e não em recursos da linguagem.


Carregar ppt "Programação aplicada de computadores Profa. Andréa Maria Pedrosa Valli www.inf.ufes.br/~avalli 2012/1 – Engenharia Elétrica."

Apresentações semelhantes


Anúncios Google