Vamos abordar o exemplo Assumimos que se pretende declarar uma classe que se chama pessoa (de notar...

26
Vamos abordar o exemplo Assumimos que se pretende declarar uma classe e chama “pessoa” (de notar que uma classe semelhant 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&); }; ãao será utilizada para a visualização dos dados n cisamos de usar esta função mas ela não é significa neste contexto e por isso vai ser considerada posteriormente Este é o construtor Este é o destrutor

Transcript of Vamos abordar o exemplo Assumimos que se pretende declarar uma classe que se chama pessoa (de notar...

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

Vamos abordar o exemplo

Assumimos que se pretende declarar uma classeque 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&);

};

Esta funçãao será utilizada para a visualização dos dados no monitorNós precisamos de usar esta função mas ela não é significativa

neste contexto e por isso vai ser consideradaposteriormente

Este é o construtor

Este é o destrutor

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

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

Esta função será utilizada para a visualização dos dados no monitor

IdadeNome

A classe aluno foi derivada da classe pessoa

Consideremos o seguinte programa constituído por duas funçõesmain e print_all:

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

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;

}

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 objectosda classe pessoa

“Quanto” é umaconstante que, por exemplo,pode ser definida da seguinte forma:#define Quanto 3

4. O primeiro ponteiro “muito[0]” vai ser preenchido como 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.

6. Executa a função print_all que vai ser consideradana próxima página

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

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;

}

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

void print_all(pessoa** ponteiro_para_pessoa, int size){ int i=0;

while (i<size) { ponteiro_para_pessoa[i++]->print_me(); }}

** significa

ponteiro_para_pessoa

Array de ponteiros

ponteiro0

ponteiro1

ponteiro2

etc.

objecto do tipo pessoa

objecto do tipo pessoa

objecto do tipo pessoa

objecto do tipo pessoa

Podem ser dosobjectos derivados

da classe pessoa

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

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 podemser 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 ouum ponteiro para pessoa ou um ponteiro para aluno que é o tipo

derivado do tipo pessoa

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

Vocês devem compreender que:

1. A variável ponteiro_para_pessoa[índice] é um nome que podepossuir valores diferentes.

2. Se ponteiro_para_pessoa[índice] tem um valor do ponteiro para oobjecto do tipo pessoa, ele permite aceder a este objecto na memória,por exemplo:

memória

O objectodo tipo pessoa

NomeIdade

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

3. Se ponteiro_para_pessoa tem um valor do ponteiro para o objectodo tipo aluno (que foi derivado da pessoa), ele permite o acessoa este objecto na memória, por exemplo:

NomeIdadegrupo

Memória

O objectodo tipo aluno

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

void print_all(pessoa** ponteiro_para_pessoa, int size){ int i=0;

while (i<size) { ponteiro_para_pessoa[i++]->print_me(); }}

Idade,Nome

Idade,Nome,grupo

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

Vamos abordar o seguinte código: 1. i=0; 2. ponteiro_para_pessoa[0];

3. print_me() para pessoa;

5. ponteiro_para_pessoa[1];

4. i=1;

6. print_me() para aluno;

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

Agora vamos considerar a função print_me:

void pessoa::print_me(){ cout << "Nome - " << Nome << "; Idade - " << Idade << endl;}

void aluno::print_me(){ pessoa::print_me(); cout << "grupo - " << grupo << endl;}

Nome - Paulo; Idade - 25Nome - Ricardo; Idade - 21grupo - 6251

Nome = “Paulo”

Idade = 25

saltar na próxima linha

void pessoa::print_me(){ cout << "Nome - " << Nome << "; Idade - " << Idade << endl;}

grupo = 6251

Nome - Ricardo; Idade - 21

pessoa p(25,"Paulo");aluno a(21, "Ricardo", 6251);

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

Podemos concluir o seguinte:

1. A função print_all pode ser usada para a visualização nomonitor dos dados de qualquer objecto da classe pessoa (ouda classe derivada da classa pessoa, por exemplo da classe aluno).

2. Se declaramos qualquer nova classe derivada da classepessoa (por exemplo empregado) podemos imprimir os respectivosdados sem redefinição da função print_all.

3. Isto permite expandir as possibilidades do programa semredefinição do seu código. Por outras palavras, podemos usaro mesmo código mesmo em tarefas novas .

4. Isto é impossível sem a utilização de herança.

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

A relação da herança pode ser designada da seguinte formagráfica:

pessoa

aluno empregado

Isto significa que a classe aluno é derivada da classe pessoa

A classe base

A classe derivada A classe derivada

Podemos usar as mesmas regras para definir a outra classe derivada,por exemplo empregado.

O código desta classe pode ser:

Page 13: 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 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 classepessoa. Esta notação chama-se full qualified name

(qualificador de nome completo)

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

void print_all(pessoa** ponteiro_para_pessoa, int size){ int i=0;

while (i<size) { ponteiro_para_pessoa[i++]->print_me(); }}

Idade,Nome

Idade,Nome,grupo

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

Vamos abordar o seguinte código: 1. i=0; 2. ponteiro_para_pessoa[0];

3. print_me() para pessoa;

5. ponteiro_para_pessoa[1];

4. i=1;

6. print_me() para aluno;

Idade,Nome,salario

empregado e(29, "Nuno", 180000); muito[2]=&e;

7. i=2; 8. ponteiro_para_pessoa[2];

9. print_me() paraempregado;

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

Nome - Paulo; Idade - 25Nome - Ricardo; Idade - 21grupo - 6251

Nome - Nuno; Idade - 29salário - 180000Nome - Nuno; Idade - 29salário - 180000

pessoa p(25,"Paulo");

aluno a(21, "Ricardo", 6251);

empregado e(29, "Nuno", 180000);pessoa

aluno empregado

Page 16: 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="");~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&);

Page 17: 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 empregado : public pessoa { unsigned long salario;public:

empregado(unsigned short, char*, unsigned long);~empregado();void print_me();const empregado& operator =(const empregado& pes);

};

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

A classebase

A classe derivadaEsta função pode ser redefinida em classes derivadas e por issofoi declarada como uma função virtual

virtual

protected:

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

Polimorfismo representa um conceito na teoria de tipos no qualum único nome (como uma declaração de uma variável) pode

denotar objectos de várias classes que se relacionamatravé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 emtodas as linguagens que sejam strongly typed e statically bound

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

Linguagens tipificadas (typed), como o Pascal, são baseadas noconceito de que funções, procedimentos e operandos possuem umúnico tipo. Estas linguagens dizem-se monomórficas, no sentidode que qualquer valor ou variável pode ser interpretado como

tendo um e um só tipo. Linguagens de programação monomórficaspodem 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 significarcoisas diferentes. Chamamos a este conceito overloading. Em C++

podemos declarar funções com nomes iguais, desde que as suasinvocaçõ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.

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

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 eligaçã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 distinguema programação orientada por objectos

da programação tradicional com tipos de dados abstractos.

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

Vamos abordar o exemplo:

void print_ref(pessoa &reference_to_pessoa){

reference_to_pessoa.print_me();}

A notação o TIPO& o objecto(por exemplo

pessoa &reference_to_pessoa oupessoa& reference_to_pessoa

)significa referência para um valor do tipo TIPO.

TIPO& o objecto

pessoa &reference_to_pessoa oupessoa& reference_to_pessoa

pessoa &referência_to_pessoa

Uma referência é um nome alternativo para o objecto

Esta possibilidade vai ser considerada posteriormentecom mais detalhe

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

void print_ref(pessoa &reference_to_pessoa){

reference_to_pessoa.print_me();}

A função print_ref pode ser usada da seguinte maneira:

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); }Nome - Paulo; Idade - 25

Nome - Nuno; Idade - 29salário ‘ 180000

Nome - Ricardo; Idade - 21grupo - 6251

p

pessoa p(25,"Paulo");

a

aluno a(21, "Ricardo", 6251);

e

empregado e(29, "Nuno", 180000);

De notar que a função print_refchama a mesma função print_me

print_me

Mas a invocação da função print_me depende do valor dareference_to_pessoa

Isto é polimorfismo

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

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

void print_ref(pessoa &reference_to_pessoa){ reference_to_pessoa.print_me(); }

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

Sumário

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

void print_ref(pessoa &reference_to_pessoa){ reference_to_pessoa.print_me(); }

void print_ref(int &i){ cout << "i = " << i << endl; }

Vamos considerar as duas seguintes funções que tem a mesmo nome

Mas o argumento da primeira função é do tipo pessoa eo 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 é polimorfismo

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

Consideremos a seguinte função:

int operator-(const pessoa& reference_to_pessoa2){ int temp=Idade - reference_to_pessoa2.Idade;

return temp;}

Este é o nome da funçãoVamos considerar o seguinte código: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 === 12340difference in age === 8

Esta função vaiser chamada

--esto é e-a

Isto é sobrecarga deoperações e também

polimorfismo

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

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.