Linguagem de
Programação II
Carlos Oberdan Rolim
Ciência da Computação
Sistemas de Informação
Classes
Prog. Procedural x Orientação Objeto
Linguagem procedural: dois conceitos – dados e algoritmo
Dados + algoritmo = programa
Orientação a objetos
Enfatiza dados
Preocupação centrada nos objetos a serem manipulados e
não na lógica necessária para manipulá-los
Prog. Procedural x Orientação Objeto
Primeiro passo – identificar os objetos que se quer manipular
e como eles se relacionam uns com os outros
Generalizar como uma classe de objetos e define o tipo de
dado que ela conterá e as sequencias lógicas para manipulálos (são os métodos)
Objeto é o que será executado no computador
Conceitos mais importantes: abstração, encapsulamento,
polimorfirsmo, herança
Abstração
Exemplo do banco de dados de alunos que contém dados
importantes dos alunos relacionados a sua vida escolar e
não dados pessoais como cor do cabelo ou olhos
Consiste em desprezar características de alguma coisa para
reduzi-las a um conjunto de características essenciais
Abstração
Nesta fase tenta-se retirar elementos e requisitos que irão
ajudar na resolução de um problema;
É o processo de retirar do domínio do problema os detalhes
relevantes e representá-los não mais em uma linguagem do
domínio e sim na linguagem da solução.
O sucesso de um Programa Orientado a Objeto está
condicionado a uma boa abstração do problema
Abstração
No paradigma da Programação Estruturada identifica-se as
funções como sendo "operações abstratas que resolvem um
problema de programação", ou seja, ocorre a abstração de
procedimentos.
No paradigma da Orientação a Objetos, tem-se a Abstração
de Dados, onde uma estrutura de dados deve incluir as
operações que ocorrem com ela.
Abstração
Primeiramente procura-se dividir o problema por assuntos ou
pequenas partes que compõem o todo;
Dentro de cada assunto pode-se observar alguns elementos
tais como :
categorias;
Ações;
informações de estado;
Operações;
Categoria
Por exemplo, se tentarmos resolver um problema ligado a
esportes de modo geral, ao abstrair a categoria bola, que é
utilizada em esportes tais como: futebol, basquete, golfe, etc.
Esta instância concreta, representando todas as bolas,
poderia ser descrita pelas propriedades :
Peso;
Cor;
Diâmetro
Outro exemplo: um automóvel descrito com as propriedades:
Potência;
Cilindradas;
Número de passageiros;
Ações
Podemos observar uma bola vazia e queremos transforma-la
em uma bola cheia. Para isto precisamos de aplicar uma
ação de encher a bola, para transformar ‘dados de entrada’
em ‘dados de saída’.
No caso do automóvel poderíamos ter a ação de abastecer,
que teremos uma quantidade de combustível para achar o
consumo em KM/L.
Informações de estado
A partir da observação de uma bola, pode-se encontrar os
valores 30 e branca, este valores seriam valores
encontrados para um atributo de uma determinada bola, que
seriam as propriedades diâmetro (em cm) e cor.
Para o automóvel teríamos valores como:
Cilindradas = 1600
Potência = 95cv
Número de passageiros = 5
Classe
Classes e objetos são os elementos básicos da programação
orientada a objetos
Classes são os meios que traduzem a abstração de dados
em um tipo
Na orientação a objetos
Cria-se estruturas
Na orientação a objetos
Cria-se classes
Classe
No mundo real freqüentemente percebemos vários objetos
de um mesmo tipo. Por exemplo: seu carro é um dos muitos
carros existentes no mundo.
Usando a terminologia OO, dizemos que um carro em
particular é uma instância da classe de objetos conhecida
como carros.
Os carros, em geral, possuem estado (cor, potência do
motor, combutível) e comportamento (ligar, acelerar, brecar,
mudar marcha) em comum.
Classe
O estado de cada carro é independente e pode ser diferente
do estado dos outros carros. Cada carro pode ter uma cor
diferentes, por exemplo.
A partir dessas semelhanças, os fabricantes de veículos
tiram vantagem disso para padronizar a construção de carros
de um mesmo tipo, definindo um modelo único com
características iguais para todos os carros a serem
produzidos.
Classe
Na Orientação a Objetos também é possível ter vários objetos do
mesmo tipo, que compartilham caracteríscas em comum.
Tirando vantagem dessa semelhança entre alguns objetos, também
é possível criar modelos para esses objetos. Esse modelo é
chamado de CLASSE. As classes são tipos que podem ser criados.
Por definição: Uma classe é um modelo (protótipo) que define as
variáveis (estado) e os métodos (comportamento) comuns a todos
os objetos do mesmo tipo.
Classe
Na classe são definidas as variáveis e implementados os métodos.
Os objetos são criados a partir de suas classes.
A cada objeto criado o sistema aloca memória para o novo objeto e
suas variáveis.
Comumente fazem confusão entre classes e objetos. Lembre-se que
classe define as características comuns e os objetos são instâncias
dessas classes, com estado próprio.
Atributos e métodos
Atributo representa alguma propriedade do que está sendo
modelado - identifica as características próprias da classe
Descreve os dados contidos nas instâncias de uma classe
Um método é a implementação de uma operação para uma
classe.
Ver visibilidade na aula de UML
+publico
#protegido
-privado
Objeto
Objeto é uma instância de uma classe
Reflete a capacidade do sistema de guardar informações
sobre o elemento abstraído, interagir com este, ou ambos.
Um objeto de software mantém seu estado em uma ou mais
de suas variáveis (atributos). Ele implementa seu
comportamento através de seus métodos. Esses métodos e
atributos são exclusivos do objeto  Encapsulamento
Método é o mesmo que função ou procedimento.
Por definição: Um objeto é um pedaço de software que
possui variáveis(estado) e métodos (comportamento)
Objeto
Objeto
Um sistema pode conter um ou inúmeros objetos ativos.
Cada objeto ativo no sistema em particular também é
chamado de instância. As diferentes instâncias possuem seu
próprio estado.
O exemplo abaixo mostra várias intâncias de pessoas
Objetos e classes
Na classe são definidas as variáveis e implementados os
métodos.
Os objetos são criados a partir de suas classes.
A cada objeto criado o sistema aloca memória para o novo
objeto e suas variáveis.
Comumente fazem confusão entre classes e objetos.
Lembre-se que classe define as características comuns e os
objetos são instâncias dessas classes, com estado próprio.
Instância - Classe & Objeto
Instância é um sinônimo para o termo Objeto, também
encontrado na literatura, é Instância de Uma Classe, ou
simplesmente Instância.
Por exemplo : o objeto “Vectra" é uma instância da classe "Automóvel".
Usa-se o termo Classe & Objeto para se referenciar uma
Classe e os Objetos que a ela pertencem.
Mensagem
Um objeto por si só não significa muito em um sistema. Para ter
algum sentido e valor esses objetos precisam interagir e comunicarse entre si.
Os objetos se comunicam por meio de mensagens.
Quando um objeto A quer se comunicar com um objeto B é enviada
uma mensagem de A para B.
Mensagem
Enviar uma mensagem significa executar um método.
Então, se A envia uma mensagem para B, podemos entender
como o objeto A executando um método do objeto B.
As mensagens são compostas por três partes:
Objeto a quem a mensagem é endereçada
Nome do método a ser chamado
Parâmetros que o método
recebe
Mensagens
É uma forma de relacionamento entre objetos;
É através delas que os objetos interagem (se comunicam)
em um programa.
Tratam-se de pedidos enviados a um objeto, a fim de que
este modifique seu estado ou retorne algum valor.
Em um programa orientado a objeto, nenhuma outra parte do
programa pode acessar diretamente os dados de um objeto.
Toda a comunicação entre os objetos ocorre única e
exclusivamente através de mensagens.
Mensagens
A interação entre os objetos é feita através da troca de
mensagens;
São representados na UML através dos diagramas de
iteração e de colaboração.
Encapsulamento / Ocultação de dados
Usuários precisam conhecer apenas os detalhes essenciais
de como acessar e utilizar tal componente
Usuários não precisam conhecer os detalhes da
implementação do componente
Trata-se de uma das principais vantagens da Programação
Orientada a Objetos sobre a Programação Estruturada,
principalmente na reutilização de códigos.
Encapsulamento / Ocultação de dados
Pode-se entender intuitivamente o significado de
encapsulamento quando se observa o mundo real. Nos
objetos do mundo real, atributos e ações são inerentes ao
próprio objeto.
Exemplo :
A um automóvel estão associados tanto atributos (modelo,
kilometragem, cilindradas, capacidade do tanque de combustível, etc),
quanto suas potencialidades (velocidade média, consumo de
combustível, etc) porém para o usuário não importa em saber detalhes
para poder dirigi-lo.
Encapsulamento
Na OO, encapsulamento é o mecanismo utilizado para
disponibilizar métodos que operam sobre os dados e
que protegem o acesso direto indevido aos atributos de
uma instância fora da classe onde estes foram
declarados.
Esta proteção consiste em se usar modificadores de acesso
mais restritivos sobre os atributos definidos na classe e
fornecendo métodos que alteram os valores destes atributos
de alguma forma.
O encapsulamento ajuda a prevenir o problema de
interferência externa indevida sobre os dados de um objeto,
como objetos que possam alterar os dados de outros
objetos indevidamente.
Encapsulamento / Ocultação de dados
Código
...
...
Dado
Código
...
...
Dado
Programação estruturada
Código
...
...
Dado
Dado
Código
Código
Código
Dado
Dado
Dado
...
...
Orientação a Objetos
...
...
...
...
Polimorfismo
O significado da palavra, originada do grego, é o de "possuir
várias formas".
Na POO é usado para indicar a propriedade de se utilizar o
mesmo nome para métodos diferentes.
Uma vantagem do polimorfismo é a relativa facilidade de
manutenção e extensão dos programas.
A idéia de polimorfismo está ligada com a indicação de que
os atributos só devem ter seus valores alterados por
métodos da classe.
Polimorfismo
Uma das estratégias adotadas na Programação Orientada a
Objeto é a de implementar os métodos o mais alto possível
na hierarquia de classes. As variações necessárias nos
métodos são feitas a medida em que se desça a árvore
hierárquica.
O conceito de Polimorfismo é relevante pelo caráter sintético
que dá aos programas.
Polimorfismo
O Polimorfismo não consiste simplesmente na existência de
funções com o mesmo nome, que pode ser uma sobrecarga
de função.
A diferença entre sobrecarga de funções e polimorfismo vem
de 2 fatos :
O polimorfismo só existe em hierarquia de classes (herança) e deve ser
feito em tempo de execução (Run time).
A sobrecarga não exige herança e o processo de associação com um
objeto se dá em tempo de compilação.
Polimorfismo
ClasseBase
Mostrar()
ClasseD1
Mostrar()
ClasseD2
Mostrar()
ClasseD3
Mostrar()
objGeral.mostrar();
Polimorfismo
ClasseBase
Mostrar()
ClasseD1
Mostrar()
ClasseD2
Mostrar()
ClasseD3
Mostrar()
objGeral.mostrar();
Polimorfismo
ClasseBase
Mostrar()
ClasseD1
Mostrar()
ClasseD2
Mostrar()
ClasseD3
Mostrar()
objGeral.mostrar();
Polimorfismo
ClasseBase
Mostrar()
ClasseD1
Mostrar()
ClasseD2
Mostrar()
ClasseD3
Mostrar()
objGeral.mostrar();
Polimorfismo
ClasseBase
Mostrar()
ClasseD1
Mostrar()
ClasseD2
Mostrar()
ClasseD3
Mostrar()
objGeral.mostrar();
Herança
É um mecanismo de hierarquia entre classes, onde uma
classe mais especializada (filho) herda as propriedades da
classe mais geral (pai).
Este recurso não está disponível em sistemas procedurais,
caracterizando-se em uma das principais diferenças entre a
Análise Orientada a Objetos e a Análise Estruturada.
A classe mais geral é denominada superclasse e a classe
mais especializada é chamada subclasse.
Herança
Herança é uma relação entre uma superclasse e suas
subclasses;
A subclasse está subordinada a superclasse na hierarquia
de classes.
Há duas formas de se descobrir heranças:
Generalização
Especialização
Herança sempre ocorrem de classe para classe;
Herança representa um relacionamento "É um tipo de".
Assim, a partir da estrutura de Especialização, diz-se que
esta "é um tipo da" estrutura de Generalização.
Herança
Atributos comuns, operações, relações e/ou, são mostradas
no nível aplicável mais alto da hierarquia
Ao se definir a hierarquia, deve-se ter em mente a premissa
básica de que as categorias inferiores sempre satisfazem
todos os atributos e serviços das categorias às quais elas
representam especializações.
Uma classe filha deve ter, no mínimo, uma propriedade de
distinção em relação à classe pai.
Herança: Exemplo
Funcionário
Nome
Endereço
Salário
Faltas
CalcularSalario(
Mostrar()
Cliente
Nome
Endereço
Compra
TipoPagamento
GerarRecibo()
Mostrar()
Nome
Endereço
Salário
Faltas
CalcularSalario()
Mostrar()
Compra
TipoPagamento
GerarRecibo()
Mostrar()
Herança: Exemplo
Pessoa
Nome
Endereço
Mostrar()
Funcionário
Salário
Faltas
CalcularSalario()
Mostrar()
Cliente
Compra
TipoPagamento
GerarRecibo()
Mostrar()
Herança
veiculo
chapa:char[8]
cor:integer
chassis:char[30]
carga
peso_max:integer
alt_max:integer
comp_max:integer
passageiros
pass_max:integer
Herança Múltipla
Vimos o conceito de Herança como sendo quando uma
classe especializada (filho) herda as propriedades de uma
classe genérica (pai). E pelo exemplo percebemos que ‘um
pai pode ter vários filhos’.
E o filho ter vários pais ?
O fato de uma classe especializada herdar propriedades de
várias classes genéricas é o que chamamos de herança
múltipla.
Ex : Um telefone - secretária eletrônica, que herda as
propriedades dos 2 aparelhos para formar um único
Herança Múltipla - Exemplo
O dono da loja dá um incentivo especial para alguns
funcionários, isto é, um desconto para que eles comprem na
própria loja. Além disto, as compras serão debitadas do
salário. Os descontos serão diferenciados a critério do
proprietário.
Por causa disto surge a necessidade de se ter objetos para
cadastrar os funcionários que possam ser clientes especiais,
ou seja, uma classe Funcionário_Cliente que herde as
características de Funcionário e também as de Cliente. Para
que o salário destes, possam ser refeito com debito das
compras (c/ desconto).
Pessoa
Herança
múltipla
Nome
Endereço
Mostrar()
Funcionário
Salário
Faltas
CalcularSalario()
Mostrar()
Cliente
Compra
TipoPagamento
GerarRecibo()
Mostrar()
Funcionário_Cliente
Desconto
CalcularSalario()
Mostrar()
Declarando classes e criando objetos
class nome_da_classe {
public:
// secao publica
variavel;
variavel;
metodo;
metodo;
private:
variavel;
variavel;
metodo;
}
// secao privada
Declarando classes e criando objetos
class carro {
public:
char marca [12];
char modelo [7];
int anofab;
void exibe() {
cout << “Marca” << marca << endl;
cout << “Modelo” << modelo << endl;
cout << "Ano " << anofab << endl;
}
private:
char placa[9];
}
Exemplo classe carro
Declarando classes e criando objetos
carro carro1;
strcpy(carro1.marca, "Volks");
strcpy(carro1.modelo, "Gol");
carro1.anofab = 2003;
Saída:
Objeto carro1
Marca Volks
cout << "Objeto carro1" << endl;
carro1.exibe();
Modelo Gol
Ano 2003
Declarando classes e criando objetos
Por que deu o seguinte erro ?
carro carro1;
`char main()::carro::placa[9]' is private
strcpy(carro1.marca, "Volks");
strcpy(carro1.modelo, "Gol");
strcpy(carro1.placa, "IDC-1234");
carro1.anofab = 2003;
cout << "Objeto carro1" << endl;
carro1.exibe();
#include <iostream>
#include <cstring>
#include <conio.h>
carro carro1;
using namespace std;
strcpy(carro1.marca, "Volks");
strcpy(carro1.modelo, "Gol");
int main() {
//strcpy(carro1.placa, "IDC-1234");
class carro {
public:
char marca [12];
char modelo [7];
int anofab;
carro1.anofab = 2003;
cout << "Objeto carro1" << endl;
void exibe() {
cout << "Marca " << marca << endl;
cout << "Modelo " << modelo << endl;
cout << "Ano " << anofab << endl;
carro1.exibe();
getch();
}
private:
char placa[9];
};
return 0;
}
Seções de uma classe
Seção publica
Membros podem ser acessados por quaisquer objetos da classe
Qualquer programa que utilize um objeto de uma determina classe pode
acessar seus membros públicos diretamente
Palavra chave public
Seção privada
Membros dessa seção podem ser acessados somente pelos métodos
da classe ou pelas funções friends.
Palavra chave private
Quando não declaramos a que seção pertence um método ou
atributo automaticamente são privados
Definição dos métodos e métodos inline
Os métodos de uma classe podem ser declarados e
codificados dentro de uma classe ou fora dela
Quando codificados fora dela usar o operador de resolução de escopo ::
para dizer a que classe pertence
Bastante comum e uma boa prática
class carro {
…..
void exibe(); // declaracao dentro da classe
};
void carro :: exibe() {
cout << "Marca " << marca << endl;
cout << "Modelo " << modelo << endl;
cout << "Ano " << anofab << endl;
}
Definição dos métodos e métodos inline
Quando um método é codificado dentro da própria classe
torna-se automaticamente um método inline
É comum implementarmos métodos inline para métodos que
possuem poucas linhas de código
class carro {
Codificado dentro da própria classe
…..
void exibe() {
cout << "Marca " << marca << endl;
cout << "Modelo " << modelo << endl;
cout << "Ano " << anofab << endl;
}
Se o programador quiser fazer um método externo a sua
classe se tornar inline basta usar a palavra chave inline
antes do tipo de valor de retorno
inline void carro :: exibe() {
….
}
Setters e Getters
Motivação: Respeitar o principio do encapsulamento
Usar atributos privados
Usar métodos para definir e obter o valor dessas variáveis
Esses métodos são conhecidos como
setters (para “setar” o valor a um atributo)
getters (para “obter” o valor de um atributo)
Setters e Getters
Exemplo
class pessoa {
string nome;
public:
string getNome(){
// Retorna o valor do atributo
return nome;
}
void setNome(string n){ // Define o valor do atributo
nome = n;
}
};
Construtores
São métodos que são executados no momento em que um
objeto da classe é instânciado
Possuem o mesmo nome da classe
O protótipo do construtor deve estar declarado na seção
public da classe
Pode receber argumentos mas não pode retornar um valor
#include <iostream>
#include <cstring>
#include <conio.h>
int main() {
// Instancia objeto chamando construtor
using namespace std;
carro carro1(“Volks”, “Gol”, 123);
class carro {
string marca;
string modelo;
int anofab;
public:
carro (string m1, string m2, int a);
…..
};
carro :: carro(string m1, string m2, int a){
marca = m1;
modelo = m2;
anofab = a;
}
…..
getch();
return 0;
}
Formas de inicialização de um objeto
O construtor pode ser invocado de duas formas
Implicitamente
carro carro1(“Volks”, “Gol”, 123);
Explicitamente
carro carro1 = carro(“Volks”, “Gol”, 123);
Construtor default
Uma vez definido um construtor o programador deverá
obrigatoriamente utiliza-lo
carro(char *, char *, int);
.....
carro carro1(“Volks”, “Gol”,123); funciona
carro carro2; Não funciona. Não foram passados os
argumentos esperados
Porém é possível instanciar objetos sem inicializá-los ou
então inicializá-los com valores padrão
Para isso se usa o construtor default
Construtor default
Por ser uma função deve ter o protótipo e definição, mas não
recebe argumentos
Pode ser definido de duas formas:
Por meio de valores default passados a todos os argumentos do
construtor existente
Por meio de sobrecarga de funções utilizando um segundo construtor,
mas sem argumentos (construtor vazio)
Se não for declarado um construtor o C++ cria
automaticamente um construtor vazio para o programador
#include <iostream>
#include <cstring>
#include <conio.h>
using namespace std;
class carro {
string marca;
string modelo;
int anofab;
public:
// Construtor default com valores default
carro (string = “”, string = “”, int = 0);
}
..
int main() {
// Instancia objeto chamando construtor
carro carro1(“Volks”, “Gol”, 123);
carro carro2;  construtor default
…..
getch();
return 0;
};
carro :: carro(string m1, string m2, int a){
marca = m1;
modelo = m2;
anofab = a;
}
Exemplo de código com
construtor default com valores
default
#include <iostream>
#include <cstring>
#include <conio.h>
using namespace std;
// Implementacao do const default vazio
carro :: carro () {
}
class carro {
string marca;
string modelo;
int anofab;
int main() {
// Instancia objeto chamando construtor
carro carro1(“Volks”, “Gol”, 123);
public:
carro (string , string , int);
carro carro2;  construtor default
…..
// Construtor default vazio
carro ();
..
getch();
return 0;
};
carro :: carro(string m1, string m2, int a){
marca = m1;
modelo = m2;
anofab = a;
}
}
Exemplo de código com
construtor vazio
Construtor de cópia
Quando instanciamos um objeto e queremos inicializá-lo com
valores guardados em outro objeto já existente
class Ponto {
float x, y;
public :
Ponto( Ponto & );
Ponto(float a, float b) {x = a; y= b; }
};
void main(){
Ponto estePonto(2.2, 5.3);
Ponto outroPonto = estePonto;
}
Ponto::Ponto(Ponto & _ponto){
x = _ponto.x;
y = _ponto.y;
}
Destrutores
É invocado quando um objeto sai do escopo ou quando é
eliminado pelo operador delete (no caso de alocação
dinâmica pelo operador new)
não podem ter argumentos, retorno e não podem ser
sobrecarregados.
Mesmo nome da classe iniciando com ~
class NomeClasse {
...
public :
~Nome_Classe ();
}
// Sintaxe na definição da Função Destrutora :
NomeClasse :: ~ NomeClasse ()
{
// código na função destrutora
}
Ponteiro this
É um ponteiro que aponta para o objeto corrente
É criado automaticamente pelo compilador
void carro :: exibe (){
cout << “Nome :” << nome;
cout << “Nome com ponteiro this:” << this -> nome;
cout << “Nome com ponteiro this de-referenciado:” << (*this).nome;
Como this é um ponteiro a necessidade do seletor indireto de
membro -> ou o operador de de-referencia *
Download

Mostrar()