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

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

Vamos abordar o exemplo

Apresentações semelhantes


Apresentação em tema: "Vamos abordar o exemplo"— Transcrição da apresentação:

1 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

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

3 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

4 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; }

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

6 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

7 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

8 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

9 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

10 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 Nome - Ricardo; Idade - 21

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

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

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

14 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", ); 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", ); muito[2]=&e; 7. i=2; 8. ponteiro_para_pessoa[2]; 9. print_me() para empregado; Idade, Nome, grupo Idade, Nome, salario Idade, Nome

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

16 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&);

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

18 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

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

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

21 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

22 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", ); 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", ); Nome - Paulo; Idade - 25 Nome - Ricardo; Idade - 21 grupo Nome - Nuno; Idade - 29 salário ‘

23 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", ); 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; }

24 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

25 - - 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", ); 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

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


Carregar ppt "Vamos abordar o exemplo"

Apresentações semelhantes


Anúncios Google