Vamos abordar o exemplo

Slides:



Advertisements
Apresentações semelhantes
Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 5 Criado por Frederick H. Colclough, Colorado Technical University Vetores.
Advertisements

C/C++ para Sistemas Operacionais Professor: André Luis Meneses Silva /msn: Página:
Um programa em C Bibliotecas Variáveis globais
Capítulo 1 – Conceitos Básicos 1 Segunda-feira, 22 de Outubro de 2007 UNIBRATEC – Ensino Superior e Técnico em Informática Aula 15 – Tipos de Dados Avançados.
Programação II Estruturas de Dados
Programação II Estruturas de Dados
List templates Vamos considerar a lista ligada (singly linked list) O objecto da classe slink O objecto da classe slink O objecto da classe slink NULL.
Perspectivas baseadas em procedimentos e orientadas por objectos Conceitos principais: Encapsulamento, Herança, Polimorfismo (Encapsulation, Hierarchy,
1. Classes 2. Membros estáticos 1.1. Palavra chave this
Struct slink { slink* next; slink() { next=0; } slink(slink* p) { next=p; } virtual void print_me() = 0; }; next função virtual pura 1º constructor 2º
Algoritmos e Estrutura de Dados I
Templates Traduzido de:
Linguagem C LPG-I – Variáveis Estruturadas – Vetores
Disciplina: AAM Profa. Ana Watanabe 03/13 vol.2
Ponteiros em C.
Estruturas de Dados II Prof.: Sergio Pacheco Prof.: Sergio Pacheco 1 1.
Universidade Federal do Espírito Santo Programação II Estruturas Professora: Norminda Luiza.
Universidade de Brasília
Vetores, Matrizes e Funções
Estruturas de Dados Homogêneas Unidimensionais – Vetores e Strings
Tratamento de Ficheiros
1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática.
Aula 8 Polimorfismo.
1 Aula 7 Herança. 2003/2004 Programação Orientada para Objectos 2 Conceitos fundamentais: Herança Polimorfismo Ligação dinâmica.
2002/2003 Programação Orientada para Objectos 1 Aula 5 Memória livre e instâncias dinâmicas Criação de instâncias dinâmicas Destruição de instâncias dinâmicas.
2002/2003 Programação Orientada para Objectos 1 Aula 4 Memória, unidade básica de memória e conceito de endereço Ponteiros Relação de ponteiros com matrizes.
2002/2003 Programação Orientada para Objectos 1 Aula 3 Utilização de listas Melhorando a implementação das listas e iteradores Reflexão sobre interfaces.
A linguagem C#.
Apontadores ou Ponteiros
APRESENTAÇÃO: GIANCARLO DE GUSMÃO GONÇALVES CURSO DE C AULA 08: Tipos Estruturados.
Aula prática 9 Alocação Dinâmica Monitoria de Introdução à Programação
Aula prática 9 Alocação Dinâmica Monitoria de Introdução à Programação
Curso de Nivelamento LCG
1 Ponteiros Ponteiros são variáveis que guardam localizações em memória. A declaração de uma variável ponteiro x para um dado tipo type é type *x; Essa.
PROGRAMAÇÃO ESTRUTURADA II
Linguagem de Programação II Parte VII
Definição de Tipos Estruturas e Ponteiros
CADEIA DE CARACTERES (Strings)
Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Linguagem de Programação II
Prof. Ricardo Santos PONTEIROS
Vetor Prof. Guilherme Baião S. Silva Adaptações:
Curso de Aprendizado Industrial Desenvolvedor WEB Disciplina: Programação Orientada a Objetos I Professora: Cheli Mendes Costa This.
Programação orientada a objectos em C++
Estruturas de Dados Aula 2: Estruturas Estáticas 07/04/2014.
Educação Profissional Técnica de Nível Médio Curso Técnico de Informática
Aula prática 14 Orientação a Objetos – C++ Parte 2
Uso de parâmetros na linha de comando. Parâmetros da função main:
Programação Orientada a Objetos - Java
Estruturas de Dados Aula 7: Tipos Estruturados 23/04/2014.
Regras de escopo Escopo: trecho de codificação no qual o identificador possui significado Escopo de função: identificador válido dentro do trecho de uma.
Aula Prática 4 Monitoria IP/CC (~if669).
Aula Prática 3 Funções Monitoria Introdução à Programação.
Aula prática 3 Aprofundando em Funções Parâmetros de uma função Uso do return Execução Variáveis Global, local e estática Monitoria de Introdução à.
Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação Versão: _01.
Aula Prática 3 Funções Monitoria Introdução à Programação.
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação Versão: _01.
Algoritmos e Programação MC102 Prof. Paulo Miranda IC-UNICAMP Aula 15 Ponteiros.
Profa. Maria Augusta Constante Puget
Linguagem de Programação II
Tipos de dados básicos em C++ –Formato geral para declaração de variáveis: ; = ;,,... ; =, = ; –O elemento da declaração indica o tipo de dado usado para.
Estruturas Homogêneas – Vetores e Matrizes
Linguaguem de Programação II
Algoritmo e Estrutura de Dados I Aulas 14 – Linguagem C Matriz Márcia Marra
Programação Orientada a Objetos para Redes de Computadores Prof. Miguel Elias Mitre Campista POO para Redes de Computadores.
Linguagem de Programação
Fundamentos de Programação 1
Aula Prática 6 Ponteiros Monitoria  Quando declaramos uma matriz:  tipo meuArray[tam];  O compilador aloca a matriz em uma região de memória.
Introdução à Orientação a Objetos em Java Prof. Gustavo Wagner (Alterações) Slides originais: Prof. Tiago Massoni Desenvolvimento de Sistemas FATEC-PB.
Transcrição da apresentação:

Vamos abordar o exemplo Assumimos que se pretende declarar uma classe que se chama “pessoa” (de notar que uma classe semelhante foi considerada na aula anterior): class pessoa { unsigned short Idade; char* Nome; public: pessoa(unsigned short Id=0, char* No=""); virtual ~pessoa(); virtual void print_me(); const pessoa& operator =(const pessoa&); }; Este é o construtor Este é o destrutor Esta funçãao será utilizada para a visualização dos dados no monitor Nós precisamos de usar esta função mas ela não é significativa neste contexto e por isso vai ser considerada posteriormente

Vamos assumir que nós criámos uma classe derivada da classe pessoa, por exemplo: class aluno : public pessoa { int grupo; public: void print_me(); aluno(unsigned short, char*, int); virtual ~aluno(); const aluno& operator =(const aluno& pes); }; Este é o número do grupo do aluno Idade Nome Esta função será utilizada para a visualização dos dados no monitor A classe aluno foi derivada da classe pessoa Consideremos o seguinte programa constituído por duas funções main e print_all:

O programa main realiza das seguintes acções: 1. Declara dois objectos, que são p do tipo pessoa e a do tipo aluno; 2. Executa a função p.print_me para o objecto p; 3. Declara array que é composto por ponteiros para objectos da classe pessoa int main(int argc, char* argv[]) { pessoa p(25,"Paulo"); aluno a(21, "Ricardo", 6251); p.print_me(); pessoa* muito[Quanto]; muito[0]=&p; muito[1]=&a; print_all(muito,Quanto); return 0; } 4. O primeiro ponteiro “muito[0]” vai ser preenchido com o valor &p que é o ponteiro para o objecto “p” do tipo pessoa. 5. O segundo ponteiro “muito[1]” vai ser preenchido com o valor &a que é o ponteiro para o objecto “a” do tipo aluno. “Quanto” é uma constante que, por exemplo, pode ser definida da seguinte forma: #define Quanto 3 6. Executa a função print_all que vai ser considerada na próxima página

int main(int argc, char* argv[]) { pessoa p(25,"Paulo"); aluno a(21, "Ricardo", 6251); p.print_me(); pessoa* muito[Quanto]; muito[0]=&p; muito[1]=&a; print_all(muito,Quanto); return 0; }

void print_all(pessoa** ponteiro_para_pessoa, int size) { int i=0; while (i<size) { ponteiro_para_pessoa[i++]->print_me(); } } ** significa Array de ponteiros Podem ser dos objectos derivados da classe pessoa ponteiro_para_pessoa ponteiro0 objecto do tipo pessoa ponteiro1 ponteiro2 etc.

void print_all(pessoa** ponteiro_para_pessoa, int size) { int i=0; while (i<size) { ponteiro_para_pessoa[i++]->print_me(); } } Esta função imprime os dados para todos os objectos que podem ser determinados através dos respectivos ponteiros. Idade, Nome Idade, Nome, grupo Isto pode ser feito com a ajuda da função print_me Já vimos que o ponteiro_para_pessoa pode ser ou um ponteiro para pessoa ou um ponteiro para aluno que é o tipo derivado do tipo pessoa

Vocês devem compreender que: 1. A variável ponteiro_para_pessoa[índice] é um nome que pode possuir valores diferentes. 2. Se ponteiro_para_pessoa[índice] tem um valor do ponteiro para o objecto do tipo pessoa, ele permite aceder a este objecto na memória, por exemplo: memória Nome Idade O objecto do tipo pessoa

3. Se ponteiro_para_pessoa tem um valor do ponteiro para o objecto do tipo aluno (que foi derivado da pessoa), ele permite o acesso a este objecto na memória, por exemplo: Nome Idade grupo O objecto do tipo aluno Memória

void print_all(pessoa** ponteiro_para_pessoa, int size) { int i=0; while (i<size) { ponteiro_para_pessoa[i++]->print_me(); } } Vamos abordar o seguinte código: 1. i=0; 2. ponteiro_para_pessoa[0]; pessoa p(25,"Paulo"); aluno a(21, "Ricardo", 6251); p.print_me(); pessoa* muito[Quanto]; muito[0]=&p; muito[1]=&a; print_all(muito,Quanto); 3. print_me() para pessoa; 4. i=1; 5. ponteiro_para_pessoa[1]; 6. print_me() para aluno; Idade, Nome, grupo Idade, Nome

Agora vamos considerar a função print_me: void pessoa::print_me() { cout << "Nome - " << Nome << "; Idade - " << Idade << endl; } void pessoa::print_me() { cout << "Nome - " << Nome << "; Idade - " << Idade << endl; } Nome = “Paulo” Idade = 25 pessoa p(25,"Paulo"); aluno a(21, "Ricardo", 6251); void aluno::print_me() { pessoa::print_me(); cout << "grupo - " << grupo << endl; } saltar na próxima linha grupo = 6251 Nome - Paulo; Idade - 25 Nome - Ricardo; Idade - 21 grupo - 6251 Nome - Ricardo; Idade - 21

Podemos concluir o seguinte: 1. A função print_all pode ser usada para a visualização no monitor dos dados de qualquer objecto da classe pessoa (ou da classe derivada da classa pessoa, por exemplo da classe aluno). 2. Se declaramos qualquer nova classe derivada da classe pessoa (por exemplo empregado) podemos imprimir os respectivos dados sem redefinição da função print_all. 3. Isto permite expandir as possibilidades do programa sem redefinição do seu código. Por outras palavras, podemos usar o mesmo código mesmo em tarefas novas . 4. Isto é impossível sem a utilização de herança.

pessoa aluno empregado A relação da herança pode ser designada da seguinte forma gráfica: pessoa A classe base A classe derivada A classe derivada aluno empregado Isto significa que a classe aluno é derivada da classe pessoa Podemos usar as mesmas regras para definir a outra classe derivada, por exemplo empregado. O código desta classe pode ser:

class empregado : public pessoa { unsigned long salario; public: empregado(unsigned short, char*, unsigned long); virtual ~empregado(); void print_me(); const empregado& operator =(const empregado& pes); }; void empregado::print_me() { pessoa::print_me(); cout << "salario - " << salario << endl; } Isto significa que a função print_me deve ser chamada para a classe pessoa. Esta notação chama-se full qualified name (qualificador de nome completo)

void print_all(pessoa** ponteiro_para_pessoa, int size) { int i=0; while (i<size) { ponteiro_para_pessoa[i++]->print_me(); } } Vamos abordar o seguinte código: 1. i=0; 2. ponteiro_para_pessoa[0]; pessoa p(25,"Paulo"); aluno a(21, "Ricardo", 6251); p.print_me(); pessoa* muito[Quanto]; muito[0]=&p; muito[1]=&a; empregado e(29, "Nuno", 180000); muito[2]=&e; print_all(muito,Quanto); 3. print_me() para pessoa; 4. i=1; 5. ponteiro_para_pessoa[1]; 6. print_me() para aluno; empregado e(29, "Nuno", 180000); muito[2]=&e; 7. i=2; 8. ponteiro_para_pessoa[2]; 9. print_me() para empregado; Idade, Nome, grupo Idade, Nome, salario Idade, Nome

Agora podemos ver todos os resultados Nome - Paulo; Idade - 25 Nome - Ricardo; Idade - 21 grupo - 6251 pessoa p(25,"Paulo"); aluno a(21, "Ricardo", 6251); Nome - Nuno; Idade - 29 salário - 180000 Nome - Nuno; Idade - 29 salário - 180000 pessoa aluno empregado empregado e(29, "Nuno", 180000);

Isto é Encapsulamento class pessoa { unsigned short Idade; char* Nome; public: pessoa(unsigned short Id=0, char* No=""); ~pessoa(); virtual void print_me(); const pessoa& operator =(const pessoa&); }; unsigned short Idade; char* Nome; public: pessoa(unsigned short Id=0, char* No=""); ~pessoa(); virtual void print_me(); const pessoa& operator =(const pessoa&);

Este é Herança protected: A classe base A classe derivada class pessoa { unsigned short Idade; char* Nome; public: pessoa(unsigned short Id=0, char* No=""); ~pessoa(); virtual void print_me(); const pessoa& operator =(const pessoa&); }; protected: Este é Herança unsigned short Idade; char* Nome; A classe base public: pessoa(unsigned short Id=0, char* No=""); ~pessoa(); virtual void print_me(); const pessoa& operator =(const pessoa&); virtual A classe derivada Esta função pode ser redefinida em classes derivadas e por isso foi declarada como uma função virtual class empregado : public pessoa { unsigned long salario; public: empregado(unsigned short, char*, unsigned long); ~empregado(); void print_me(); const empregado& operator =(const empregado& pes); };

Polimorfismo Polimorfismo representa um conceito na teoria de tipos no qual um único nome (como uma declaração de uma variável) pode denotar objectos de várias classes que se relacionam através de uma superclasse comum. Qualquer objecto que possua esse nome está apto a responder a um conjunto comum de operações. O oposto de polimorfismo é monomorfismo, que se encontra em todas as linguagens que sejam strongly typed e statically bound

Linguagens tipificadas (typed), como o Pascal, são baseadas no conceito de que funções, procedimentos e operandos possuem um único tipo. Estas linguagens dizem-se monomórficas, no sentido de que qualquer valor ou variável pode ser interpretado como tendo um e um só tipo. Linguagens de programação monomórficas podem contrastar com linguagens polimórficas, nas quais alguns valores e variáveis podem ter mais do que um tipo Um símbolo, por exemplo "+", pode ser definido para significar coisas diferentes. Chamamos a este conceito overloading. Em C++ podemos declarar funções com nomes iguais, desde que as suas invocações possam ser distinguidas pelas suas assinaturas, que consistem no número e tipo dos seus argumentos Herança sem polimorfismo é possível, mas certamente que não é muito útil.

Em C++ o polimorfismo é expresso através dos conceitos de 1) funções virtuais e 2) overloading O polimorfismo existe quando as características de herança e ligação dinâmica interagem. É talvez a característica mais poderosa das linguagens de programação orientada por objectos. Polimorfismo e herança são características que distinguem a programação orientada por objectos da programação tradicional com tipos de dados abstractos.

Esta possibilidade vai ser considerada posteriormente com mais detalhe Vamos abordar o exemplo: void print_ref(pessoa &reference_to_pessoa) { reference_to_pessoa.print_me(); } TIPO& o objecto pessoa &reference_to_pessoa ou pessoa& reference_to_pessoa pessoa &referência_to_pessoa A notação o TIPO& o objecto (por exemplo pessoa &reference_to_pessoa ou pessoa& reference_to_pessoa ) significa referência para um valor do tipo TIPO. Uma referência é um nome alternativo para o objecto

Mas a invocação da função print_me depende do valor da void print_ref(pessoa &reference_to_pessoa) { reference_to_pessoa.print_me(); } print_me Mas a invocação da função print_me depende do valor da reference_to_pessoa A função print_ref pode ser usada da seguinte maneira: De notar que a função print_ref chama a mesma função print_me int main(int argc, char* argv[]) { pessoa p(25,"Paulo"); aluno a(21, "Ricardo", 6251); empregado e(29, "Nuno", 180000); print_ref(p); print_ref(a); print_ref(e); } p pessoa p(25,"Paulo"); a aluno a(21, "Ricardo", 6251); Isto é polimorfismo e empregado e(29, "Nuno", 180000); Nome - Paulo; Idade - 25 Nome - Ricardo; Idade - 21 grupo - 6251 Nome - Nuno; Idade - 29 salário ‘ 180000

Sumário void print_ref(pessoa &reference_to_pessoa) { reference_to_pessoa.print_me(); } int main(int argc, char* argv[]) { pessoa p(25,"Paulo"); aluno a(21, "Ricardo", 6251); empregado e(29, "Nuno", 180000); print_ref(p); print_ref(a); print_ref(e); } Sumário void pessoa::print_me() { cout << "Nome - " << Nome << "; Idade - " << Idade << endl; } void aluno::print_me() { pessoa::print_me(); cout << "grupo - " << grupo << endl; } void empregado::print_me() { pessoa::print_me(); cout << "salario - " << salario << endl; }

Vamos considerar as duas seguintes funções que tem a mesmo nome void print_ref(pessoa &reference_to_pessoa) { reference_to_pessoa.print_me(); } void print_ref(int &i) { cout << "i = " << i << endl; } Isto é polimorfismo Mas o argumento da primeira função é do tipo pessoa e o argumento da segunda função é do tipo int e assumimos que temos o seguinte codico int main(int argc, char* argv[]) { pessoa p(25,"Paulo"); int integer=12345; print_ref(p); print_ref(integer); return 0; } Nome - Paulo; Idade - 25 i = 12345

- - Isto é sobrecarga de operações e também polimorfismo Consideremos a seguinte função: int operator-(const pessoa& reference_to_pessoa2) { int temp=Idade - reference_to_pessoa2.Idade; return temp; } esto é e-a Isto é sobrecarga de operações e também polimorfismo Esta função vai ser chamada Vamos considerar o seguinte código: Este é o nome da função int main(int argc, char* argv[]) { aluno a(21, "Ricardo", 6251); empregado e(29, "Nuno", 180000); int integer=12345, integer1=5; cout << "difference in integers === " << integer-integer1 << endl; cout << "difference in age === " << (e-a) << endl; return 0; } - - difference in integers === 12340 difference in age === 8

O que é importante: 1. Perceber o que são paradigmas de programação. 2. Perceber mais detalhes sobre encapsulamento. 3. Perceber o que é herança. 4. Perceber o que é um polimorfismo. 5. Perceber as regras da linguagem C++. 6. Estar apto a construir programas triviais que utilizem encapsulamento, herança e polimorfismo.