programação aplicada de computadores

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

Upload: molimo

Post on 16-Jan-2016

38 views

Category:

Documents


0 download

DESCRIPTION

Programação aplicada de computadores. Profa . Andréa Maria Pedrosa Valli www.inf.ufes.br/~avalli 2012/1 – Engenharia Elétrica. 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++.  - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Programação aplicada de computadores

Programação aplicada de computadores

Profa. Andréa Maria Pedrosa Valliwww.inf.ufes.br/~avalli

2012/1 – Engenharia Elétrica

Page 2: Programação aplicada de computadores

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.

Page 3: Programação aplicada de computadores

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 + 0.5 * 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 + 0.8 * Trabalho.

A Segunda Chamada é para quem faltou alguma prova e justificou (essa prova pode ser escrita ou aplicada no computador).

Homepage da Disciplina:www.inf.ufes.br/~avalli/programacao/paginas/prog_eletrica012.html

Page 4: Programação aplicada de computadores

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, 2010.

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

Page 5: Programação aplicada de computadores

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.

Page 6: Programação aplicada de computadores

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 globaisAcessí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

Page 7: Programação aplicada de computadores

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

Função-membro

dados

Função-membro

Função-membro

dados

Função-membro

Função-membro

ObjetoObjeto

Objeto

Page 8: Programação aplicada de computadores

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).

• 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.

Page 9: Programação aplicada de computadores

Terra

Marítimo

Aéreo

Estrada

Ferroviário

Navios

Submarinos

Barcos

Aviões

BalõesHelicópteros

Duas Rodas

Quatro Rodas Motocicletas

Biclicletas

Trem

Bonde

Automóveis

Caminhões

ÔnibusMetrô

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.

Page 10: Programação aplicada de computadores

• 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

BE

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.

Page 11: Programação aplicada de computadores

• 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.

Page 12: Programação aplicada de computadores

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.

Page 13: Programação aplicada de computadores

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

Page 14: Programação aplicada de computadores

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.

Page 15: Programação aplicada de computadores

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.

Page 16: Programação aplicada de computadores

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

Page 17: Programação aplicada de computadores

#include <iostream>#include <cmath>

using namespace std; const double PI = 3.14159; // define global constant PI // calculates volume of a sphereinline 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 

Page 18: Programação aplicada de computadores

3. Programação modularCom 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

Page 19: Programação aplicada de computadores

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.

Page 20: Programação aplicada de computadores

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.

Page 21: Programação aplicada de computadores

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 } // . . .}

Page 22: Programação aplicada de computadores

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

Page 23: Programação aplicada de computadores

1. Definição de tipos em módulos

Exemplo: definir um gerenciador de pilhasnamespace Pilha { struct Rep; // definicao do layout da pilha est’a 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 );}

Page 24: Programação aplicada de computadores

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; // . . .}

Page 25: Programação aplicada de computadores

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 elementosvoid 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’ ); // . . .

Page 26: Programação aplicada de computadores

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.

Page 27: Programação aplicada de computadores

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<char> 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 ); };

Page 28: Programação aplicada de computadores

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):

Page 29: Programação aplicada de computadores

5. Programação orientada a objetosParadigma: 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 tipoPonto centro;Cor co;// . . .

public:void desenha ( );void rotacao ( int );// . . .

};

Page 30: Programação aplicada de computadores

void Forma::desenha ( ) {switch ( k ):case circulo:

// desenha um circulobreak;

case triangulo:// desenha um circulobreak;

case quadrado:// desenha um circulobreak;

}}

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;// . . .

};

Page 31: Programação aplicada de computadores

• 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 Formaint 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.

Page 32: Programação aplicada de computadores

6. Programação genéricaParadigma: 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 T> 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 ( );

};

Page 33: Programação aplicada de computadores

As funções membro podem ser definidas de forma similar:template<class T> void Pilha<T>::empilha( T c ) {

If ( topo == tamanho_max ) throw Transbordou ( );v[topo] = c;topo = topo + 1;

}

template<class T> T Pilha<T>::desempilha( ) {

If ( topo == 0 ) throw Esvaziou ( );topo = topo - 1;return v[topo];

}

Uso:

Pilha<char> sc( 200 ); // pilha de 200 caracteresPilha<complex> scplx ( 30 ); // pilha de 30 numeros complexosPilha< list<int> > 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 ( );

}

Page 34: Programação aplicada de computadores

• 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.