laboratório de programação orientada a objetos para engenharia

Post on 09-Jan-2017

217 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Escola Politécnica da Universidade de São Paulo

Laboratório de Programação Orientada a

Objetos para Engenharia Elétrica

Aula 5: Encapsulamento e Tipo Abstrato de

Dados

PCS 3111

Agenda

Questões Típicas

Modularização do Software

Princípios de Modularização do Software

Encapsulamento

Tipo Abstrato de Dados (TAD)

Contrato e Implementação de TAD

Classe como TAD

Classe e Arquivos

2

Questões Típicas

O que caracteriza um bom projeto de software? • Uma boa organização do software

Qual é a estratégia para essa organização? • Modularização do software

Existem princípios que ajudam na modularização do software? • Abstração

• Refinamento passo a passo

• Ocultação de informações

Como deve ser um software? • Reusável

• Extensível

3

Questões Típicas

Quais são os benefícios desses princípios na

modularização do software?

• Facilidade de construção do software

• Facilidade de teste e depuração do software

• Facilidade de modificação do software

• Legibilidade do software

• Facilidade de comunicação entre os desenvolvedores

• Menor time-to-market

4

Modularização do Software

Quebra a solução de software em módulos

Cada módulo pode ser implementado e

compilado independentemente

Os módulos podem ser ligados (linked)

formando a solução completa

Permite isolar os erros cometidos e eliminar

redundâncias

Torna o desenvolvimento do software

gerenciável

5

Princípios de Modularização

Abstração

Refinamento Passo a Passo

Ocultação de Informações

6

Abstração

Torna visíveis somente detalhes do módulo que

interessam

7

Placa vista com Circuitos

Integrados, Resistores,

Capacitores

PC

PC visto com Placa Mãe, Placas de

Vídeo, Placa de Rede, Placa de

Som, Placa de Memória

Abstração

Uma solução modular pode ter muitos níveis de

abstração

• Abstração procedimental: a ação de “ligar” o

equipamento de ar condicionado pode ter uma

sequência de passos procedimentais. Por exemplo:

Pegue o controle remoto

Acione o botão de ligar

Escolha a temperatura

Ative a temperatura escolhida

8

Abstração

Uma solução modular pode ter muitos níveis de

abstração

• Abstração de dados: “equipamento” pode ser

caracterizado por outros dados: Por exemplo:

Fabricante

No. de série

Modelo

Ano

9

Refinamento Passo a Passo

Uma solução modular pode ter muitos níveis de

refinamento

A medida que se desenvolve o software, mais

detalhes são incorporados aos módulos

10

Refinamento Passo a Passo

Exemplo 1:

• “Escolha a temperatura”, um procedimento da

abstração “ligar”, pode ser definido como:

Acione o botão “temp+” para aumentar a temperatura ou

Acione o botão “temp-” para diminuir a temperatura

Exemplo 2:

• “Fabricante”, um dado da abstração “equipamento”,

pode ser definido como:

string de até 10 caracteres. Ex. “Brastemp”

11

Ocultação de Informações

Uma solução modular esconde detalhes do

módulo de outros módulos

Especifica um módulo do ponto de vista externo

Separa o propósito de um módulo de sua

implementação

Restringe o acesso de outros módulos a

detalhes de implementação e a qualquer

estrutura de dados do módulo

12

Encapsulamento

Uma solução modular pode ser obtida usando

princípios na modularização de software

apresentadas anteriormente, mantendo a

integridade dos dados

O encapsulamento esconde detalhes do módulo

que não essenciais para compreender suas

características

O encapsulamento permite o acesso aos dados

do módulo somente através de interfaces

definidas

13

Encapsulamento

O que há dentro dos objetos?

14

Variáveis

(atributos)

Métodos (operações)

Tipo de Dados

Conjunto de valores que uma variável pode

assumir, em uma dada linguagem de

programação. Por exemplo, em C++:

• int i = 1234;

• char a = ‘A’;

• bool flag = true;

15

Tipos de Dados

Exemplo: Inteiros (Integer)

• Operadores:

Aritméticos Unários (+; -)

• Ex: +5 resulta 5

• Ex: -8 resulta -8

Aritméticos Binários (+; -; *; /; %)

• Ex: 2 + 3 resulta 5

• Ex: 8 % 3 resulta 2 (resto)

Relacionais (==; !=; <; <=; >; >=)

• Ex: a != b resulta True se a é diferente de b, caso

contrário, é False

• Ex: a > b resulta True se a é maior do que b, caso

contrário, é False

16

Operadores sobre

Inteiros encapsulam

números inteiros

Tipo Abstrato de Dados (TAD)

É um conceito central de design de programa,

sobretudo na abordagem OO

É independente de linguagem específica de

programação

Incorpora princípios de modularização de

software

Encapsula uma coleção de dados e um conjunto

de operações sobre esses dados

Pode ter várias implementações diferentes

17

Tipo Abstrato de Dados (TAD)

18

Min, Max

Ventilador

Aquecedor

Refrigerador

Ar Condicionado

Residencial

Painel de

Controle

Contrato (Especificação) de um TAD

TAD nome_TAD é

Dados

[Descreve a estrutura de dados]

Operações Construtor

Valores iniciais: [Dados usados para iniciar o objeto]

Processo: [Inicia o objeto]

Operação 1

Entrada: [Dados vindos do cliente]

Pré-condições: [Estado (condição) necessário(a) do sistema antes de executar a operação]

Processo: [Ações executadas com os dados]

Saída: [Dados retornados para o cliente]

Pós-condições: [Estado do sistema depois de executar a operação]

Operação 2 ...

Operação n ...

Destrutor

Processo: [Destrói o objeto]

Fim TAD nome_TAD

19

( Adaptado de Ford e Topp, 1996)

Importante:

O Contrato não

especifica a

representação

dos dados e nem

os algoritmos que

implementam as

operações

Exemplo: Contrato do TAD Sensor

20

TAD Sensor é

Dados

Um número real não negativo que especifica o código do sensor.

Um valor booleano que indica o estado do sensor.

Operações Construtor

Valores iniciais: O código default do sensor.

Processo: Atribuir um valor inicial ao sensor.

Ativação

Entrada: Código do sensor.

Pré-condições: Nenhuma.

Processo: Ativar sensor.

Saída: Nenhuma.

Pós-condições: Nenhuma.

Leitura

Entrada: Código do sensor.

Pré-condições: Nenhuma.

Processo: Ler estado do sensor.

Saída: Retorna estado do sensor.

Pós-condições: Nenhuma.

Destrutor

Processo: Destruir sensor.

Fim TAD Sensor

Classe como TAD

Uma Classe definida pelo usuário implementa

um TAD em C++

21

Privado

Dados membros: valor 1, valor 2...

Operações internas

Público

Construtor

Operação 1

Operação 2

Destrutor

Classe

(Adaptado de Ford e Topp, 1996)

Encapsulamento

Interface de Acesso

Exemplo em C++

22

Privado

Estado

Público

Construtor

Ativação

Leitura

Destrutor

Classe Sensor

class Sensor {

private:

bool estado;

public:

Sensor()

{

estado=false;

}

void Sensor::ativaSensor()

{

estado = true;

}

bool leSensor() {

return estado;

}

~Sensor()

{}

};

Stack

23

Push Pop

Clear Peek

Contrato do TAD Stack

24

TAD Stack é

Dados

Uma lista de itens com uma posição “topo” que indica o topo da Stack.

Operações Construtor

Valores iniciais: Nenhum.

Processo: Inicia o topo da Stack.

StackEmpty

Entrada: Nenhuma.

Pré-condições: Nenhuma.

Processo: Verificar se a Stack está vazia.

Saída: Retorna True se estiver vazia e False, caso contrário.

Pós-condições: Nenhuma.

Pop

Entrada: Nenhuma.

Pré-condições: Stack não está vazia.

Processo: Remover o item do topo da Stack.

Saída: Retorna o elemento do topo da Stack.

Pós-condições: Elemento do topo da Stack é removido. (Ford e Topp, 1996)

Contrato do TAD Stack

25

Push

Entrada: Um item da Stack.

Pré-condições: Nenhuma.

Processo: Armazenar o item no topo da Stack.

Saída: Nenhuma.

Pós-condições: A Stack tem um novo elemento no topo.

Peek

Entrada: Nenhuma.

Pré-condições: Stack não está vazia.

Processo: Recuperar o valor do item no topo da Stack.

Saída: Retorna o valor do item do topo da Stack.

Pós-condições: A Stack está inalterada.

ClearStack

Entrada: Nenhuma.

Pré-condições: Nenhuma.

Processo: Deletar todos os itens da Stack e resetar o topo da Stack.

Saída: Nenhuma.

Pós-condições: A Stack está resetada para a sua condição inicial.

Destrutor

Processo: [Destrói a Stack]

Fim TAD Stack (Ford e Topp, 1996)

Implementação do TAD Stack

Dado um contrato de um TAD, escolher a

melhor forma de implementação

Uma TAD Stack pode ser implementada usando

diferentes estruturas de dados, como por

exemplo, um vetor (Array) ou uma lista ligada

26

Classe Stack

(Implementação usando Vetor)

27

#include <iostream>

using namespace std;

int maxStackSize = 10;

class Stack {

private:

int stackElement[10];

int top;

public:

bool stackEmpty();

int pop();

void push(int x);

int peek();

void clearStack();

};

bool Stack::stackEmpty(){

if (top == -1)

return true;

else

return false;

}

int Stack::pop(){

int x;

if (stackEmpty()) {

cout << "pilha vazia!!! ";

return -1;

}

else {

x = stackElement[top];

top--;

return x;

}

}

void Stack::push(int x) {

if (top < maxStackSize-1){

top++;

stackElement[top] = x;

} else

cout << "pilha cheia" << endl;

}

Classe Stack

(Implementação usando Vetor)

28

Saída

pilha vazia!!!-1

30

20

10

pilha vazia!!! -1

1300

pilha vazia!!! -1

int Stack::peek(){

int x;

if (stackEmpty()){

cout << "pilha vazia!!! ";

return -1;

}

else {

x = stackElement[top];

return x;

}

}

void Stack::clearStack() {

for (int x = 0; x < maxStackSize; x++) {

stackElement[x] = 0;

top = -1;

}

}

int main() {

Stack s;

s.clearStack();

cout << s.peek() << endl;

s.push(10);

s.push(20);

s.push(30);

cout << s.pop() << endl;

cout << s.pop() << endl;

cout << s.pop() << endl;

cout << s.pop() << endl;

s.push(1100);

s.push(1200);

s.push(1300);

cout << s.pop() << endl;

s.clearStack();

cout << s.peek() << endl;

return 0;

}

Classe Stack

(Implementação usando Vetor)

29

#include <iostream>

using namespace std;

class Stack {

private:

static const int maxSize = 10;

int elementos[maxSize];

int top;

public:

bool empty();

int pop();

void push(int x);

int peek();

void clear();

Stack();

};

bool Stack::empty() {

if (top == -1)

return true;

else

return false;

}

int Stack::pop() {

if (empty()) {

cout << "Pop da pilha vazia.\n";

exit(1);

} else {

int x = elementos[top];

top--;

return x;

}

}

void Stack::push(int x) {

if (top < maxSize-1){

top++;

elementos[top] = x;

} else {

cout << "Push na pilha cheia.\n";

exit(1);

}

}

Classe Stack

(Implementação usando Vetor)

30

Saída:

Peek na pilha vazia!-2147483648

30

20

10

1300

Peek na pilha vazia!-2147483648

int Stack::peek() {

if (empty()) {

cout << "Peek na pilha vazia!";

return INT_MIN;

} else {

return elementos[top];

}

}

void Stack::clear() {

top = -1;

}

Stack::Stack() {

clear();

}

int main() {

Stack s;

cout << s.peek() << endl;

s.push(10);

s.push(20);

s.push(30);

cout << s.pop() << endl;

cout << s.pop() << endl;

cout << s.pop() << endl;

s.push(1100);

s.push(1200);

s.push(1300);

cout << s.pop() << endl;

s.clear();

cout << s.peek() << endl;

}

Classes e Arquivos

31

Classes e Arquivos

C++ permite definir e implementar mais de uma

classe em um mesmo arquivo

• Exemplo: sistema bancário

32

class ContaCorrente { ... }; int main(int argc, char** argv) { ... } class Agencia { ... }; void ContaCorrente::depositar(double valor) { ... } void Agencia::adicionar(ContaCorrente c) { ... } class Correntista { ... }; bool ContaCorrente::retirar(double valor) { ... } ...

Classes e Arquivos

Como organizar as classes em um arquivo?

Quantas classes devem ser colocadas em cada

arquivo?

Boa prática

• Crie um arquivo separado para cada definição e

implementação

• Em projetos grandes, não é possível colocar uma

definição e uma implementação por arquivo. Imagine

um projeto com 2000 classes.

33

Definição

Arquivo de cabeçalho: ".h"

• Exemplo: ContaCorrente.h

34

class ContaCorrente { public: double saldo; void depositar(double valor); bool retirar(double valor); };

Implementação

Arquivo .cpp

• Necessário fazer um #include do ".h"

• Exemplo: ContaCorrente.cpp

35

#include "ContaCorrente.h" void ContaCorrente::depositar(double valor) { saldo += valor; } bool ContaCorrente::retirar(double valor) { if (saldo < valor) return false; saldo -= valor; return true; }

Incluindo a definição

Implementação

Arquivo main.cpp

Para compilar e linkar manualmente:

36

#include "ContaCorrente.h" #include <iostream> using namespace std; int main() { ContaCorrente conta={0}; conta.depositar(1000); cout << conta.saldo << endl; }

g++ -c -std=c++11 contacorrente.cpp -o contacorrente.o g++ -c -std=c++11 main.cpp -o main.o g++ contacorrente.o main.o -o main.exe

Inclusão

Indica para o compilador onde o arquivo está

• (O arquivo pode estar em pastas diferentes)

• Quando se inclui cabeçalhos da biblioteca padrão usa-

se o "<" e ">"

O compilador procura o arquivo onde as bibliotecas ficam

Arquivos de cabeçalho também podem fazer

inclusões

• Exemplo: Agencia.h inclui a ContaCorrente.h

37

#include "ContaCorrente.h" #include <iostream>

Do projeto

Da biblioteca padrão

Diretiva ifndef

Problema: múltipla inclusão de um cabeçalho

• Exemplo: tanto a Agência quanto o Correntista

incluem a ContaCorrente

• Gera um erro de compilação!

(Compiladores de outras linguagens evitam esse erro)

Solução: diretiva #ifndef

38

#ifndef CONTACORRENTE_H #define CONTACORRENTE_H class ContaCorrente { ... }; #endif

Se CONTACORRENTE_H não estiver

definido, define-o

Fim do ifndef

Classes e Arquivos

Exemplo: arquivos de um sistema bancário

• ContaCorrente.h e ContaCorrente.cpp

• Agencia.h e Agencia.cpp

• Correntista.h e Correntista.cpp

• main.cpp

No Netbeans

• Novo Arquivo → C++ → Classe C++

• Cria tanto o cabeçalho quanto a implementação

Coloca já o #ifndef no arquivo cabeçalho

Cria alguns métodos (veremos na aula que vem o que eles

significam)

39

Exercício

Dado um equipamento de Ar Condicionado que

pode ser operado com os seguintes comandos:

Ligar, Desligar, Aumentar Ventilação, Diminuir

Ventilação, Aumentar Temperatura e Diminuir

Temperatura, escreva um código que permita

armazenar previamente uma sequência de

tarefas, que seja executada após a

programação do equipamento

Baixe o enunciado do exercício Aula 5 Ar

Condicionado Enunciado v1.pdf e os esqueletos

de códigos do Moodle

40

Bibliografia

FORD, W.; TOPP, W. Data Structures with C++.

Prentice Hall. 1996. 895p.

41

top related