Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Princípios de Programação Orientada a Objetos em Delphi, Notas de estudo de Automação

Neste documento, é apresentado o conceito básico de programação orientada a objetos (poo) no delphi. O poo é uma abordagem de programação que permite a criação de objetos que possuem atributos e métodos, além de herdar características de outros objetos. O documento aborda conceitos como encapsulamento, herança, polimorfismo e sobrecarregamento de métodos. Além disso, são apresentados exemplos de classes e métodos em delphi, como tdata, tpessoa, tprofessor e taluno.

Tipologia: Notas de estudo

2012

Compartilhado em 07/04/2012

maciel-duda-12
maciel-duda-12 🇧🇷

47 documentos

1 / 23

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
UNIVERSIDADE TIRADENTES
DEPARTAMENTO DE CIÊNCIA DA COMPUTAÇÃO
Prof. José Maria Rodrigues Santos Júnior
DELPHI
Orientação a Objetos
+
Object Pascal
Aracaju 4 de Agosto de 1997
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17

Pré-visualização parcial do texto

Baixe Princípios de Programação Orientada a Objetos em Delphi e outras Notas de estudo em PDF para Automação, somente na Docsity!

UNIVERSIDADE TIRADENTES

DEPARTAMENTO DE CIÊNCIA DA COMPUTAÇÃO

Prof. José Maria Rodrigues Santos Júnior

DELPHI

Orientação a Objetos

Object Pascal

Aracaju 4 de Agosto de 1997

Conceitos de Orienção a Objetos

A Metodologia Orientada a Objetos é relativamente nova, pois por volta de 1970 surgiram as primeiras

publicações, mas o seu "boom" se deu nos anos 90, quando tornou-se a principal metodologia de

desenvolvimento de software. A orientação a objetos permite modelar de forma mais natural o mundo real,

pois as estruturas de dados são vistas como objetos, ou seja, têm características e funções. Seu maior

objetivo é aumentar a produtividade do desenvolvimento de software através de uma maior expansibilidade

e reutilização de código, além de controlar a complexidade e o custo da manutenção do mesmo.

Quando a metodologia orientada a objetos é utilizada, a fase de projeto do desenvolvimento do

software está mais intimamente ligada à fase de implementação. Um dos pontos chaves da metodologia

orientada a objetos é centralização das atenções nas Estruturas de Dados, ao contrário da metodologia

estruturada, onde a atenção era centralizada nos procedimentos. Na orientação a objetos há uma maior

aproximação entre dados e procedimentos, pois procedimentos são definidos em termos dos dados.

Componentes Básicos da Orientação a Objetos

Classe

F 0

A E São moldes através dos quais criamos objetos

Objeto

F 0

A E Abstração que agrupa características e comportamentos.

Instância

F 0

A E É o objeto propriamente dito. Possui características próprias.

Propriedade

F 0

A E Define as característica dos objetos de uma classe.

Método

F 0

A E Define o comportamento dos objetos de uma classe.

Mensagem

F 0

A E Representa uma ação do objeto ou uma mudança de estado. Define a comunicação entre

objetos.

Interface

F 0

A E Conjunto de mensagens que define o comportamento de um objeto (Protocolo).

Encapsulamento

  • É a capacidade de "esconder" detalhes de implementação (abstração).
  • O principal objetivo é tornar o objeto independente de sua implementação interna, para isso a

implementação das suas propriedades e métodos são "escondidas" de forma que o usuário precise apenas

conhecer a interface do objeto para poder utilizá-lo. Desta forma o desenvolvedor poderá alterar

tranquilamente a implementação de um objeto (Classe) sem causar transtornos ao usuários.

Herança

Permite que uma nova classe seja descrita a partir de outra classe já existente (Reutilização).

A subclasse herda as características e o comportamento da superclasse.

A subclasse pode adicionar novas características e comportamentos aos herdados da superclasse.

A subclasse pode ter um comportamento diferente da superclasse , redefinindo o método herdado.

A subclasse é uma especialização da superclasse.

Toda instância da subclasse é também uma instância da superclasse.

O resultado de uma seqüência de heranças é uma hierarquia de classes.

Classes Abstratas

Definida para ser a base de uma hierarquia.

Possui métodos que não estão implementados.

Não pode ser instanciada.

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

Object Pascal

Estrutura de uma Unit

Unit ;

Interface

{Especifica o que será exportado pela UNIT afim de ser utilizados por outros módulos }

[uses ;]

<seções de declaração>

Implementation

{Declaração de Variáveis, Constante e tipos locais a UNIT e Implementação dos métodos.

[uses ;]

<definições>

[ Initialization

{Código executado automaticamente quando um aplicativo que utiliza a UNIT é executado }

<instruções>]

[ Finalization

{Código executado automaticamente quando um aplicativo que utiliza a UNIT é finalizado }

<instruções>]

end.

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

Classes

Definição de uma Classe

= class [(Descendência)]

<atributos e métodos>

end ;

Deve ser feita na seção de declaração de tipos principal de um programa ou de uma unit.

No caso do Delphi, todas as classes são descendentes de TObject.

Atributos e Métodos

<visibilidade 1>

<lista de variáveis>

<lista de procedimentos ou funções>

<visibilidade 2>

<lista de variáveis>

<lista de procedimentos ou funções>

<lista de variáveis>

<lista de procedimentos ou funções>

Visibilidade

Define quem tem permissão de acessar e alterar os atributos e métodos da classe.

Em uma mesma classe pode existir atributos e métodos com visibilidades diferentes.

Visibilidade Descrição

Public Os atributos e métodos podem ser manipulados por qualquer classe.

Private Os atributos e métodos só podem ser manipulados pela própria classe.

Protected Os atributos e métodos podem ser manipulados pela própria classe ou por qualquer

subclasse desta e por demais classes declaradas na mesma UNIT.

Published Semelhante a visibilidade public sendo que permite o acesso em tempo de projeto.

Declarando, Instanciando, Destruindo e Referenciando Objetos

  • É declarado da mesma maneira que uma variável.
  • Para que um objeto possa ser utilizado, este deve ser instanciado e após o seu uso o mesmo deve ser liberado

Se comporta como um ponteiro, mas é manipulado como uma variável normal.

Pode ser atribuído o valor nil.

: Classe; {Declarando}

= Classe.Create; {Instanciando}

.Free; {Destruindo}

.Identificador {Referenciando}

,onde Identificador representa uma propriedade ou um método. A

referência a Dados é idêntica a referência a código.

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

Propriedades

  • Representa um mecanismo para encapsular os campos de uma Classe sobrecarrgando as operações de leitura e escrita
  • (^) São uma extensão natural às variáveis de instância de uma classe, pois permitem que o desenvolvedor pareça esta trabalhando

com estas, enquanto na realidade está executando chamadas a métodos.

  • Para utilizar as propriedades os campos (atributos) devem ser declarados como private , os métodos como protected , e as

propriedades como public.

property Identificador : TIPO

[ read MétodoDeLeitura]

[ write MétodoDeEscrita];

,onde, Identificador representa a propriedade, TIPO o tipo da propriedade, MétodoDeLeitura o método associado a leitura da

propriedade, MédodoDeEscrita o método associado a escrita da propriedade.

Verificação de Tipo

Verifica, em tempo de execução, se o objeto é uma instância da classe ou de alguma subclasse desta.

Retorna true ou false.

is

Conversão de Tipo

Converte, se possível, uma referência para o objeto de uma classe base em uma referência para objeto da subclasse.

( as ).<Métodos ou Propriedade>

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

Exemplos de Orientação a Objetos

unit Datas;

interface

type

TData = Class (TObject)

private

Dia, Mes, Ano : Integer;

public

constructor Init (d,m,a : integer);

procedure DefVal (d,m,a : integer);

function AnoBis : boolean;

procedure Incrementa;

procedure Decrementa;

procedure Adiciona (NumDeDias : integer);

procedure Subtrai (NumDeDias : integer);

function GetText : string;

private

function DiasNoMes : Integer;

end;

implementation

constructor TData.Init (d,m,a : integer);

begin

dia := d; Mes := m; ano := a;

end;

procedure TData.DefVal (d,m,a : integer);

begin

dia := d; Mes := m; ano := a;

end;

function TData.AnoBis : boolean;

begin

if (ano mod 4 <> 0)

then AnoBis := false

else

if (ano mod 100 <> 0)

then AnoBis := true

else

if (ano mod 400 <> 0)

then AnoBis := False

else AnoBis := True;

end;

function TData.DiasNoMes : integer;

begin

case Mes of

1,3,5,7,8,10,12 : DiasNoMes := 31;

4,6,9,11 : DiasNoMes := 30;

2 : if (AnoBis)

then DiasNoMes := 29

else DiasNoMes := 28;

end;

end;

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

procedure TData.Adiciona (NumDeDias : integer);

var n : integer;

begin

for n := 1 to NumDeDias do

Incrementa;

end;

procedure TData.Subtrai (NumDeDias : integer);

var n : integer;

begin

for n := 1 to NumDeDias do

Decrementa;

end;

end.

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

unit Universidade;

interface

type

TEndereco = Class

private

FRua, FBairro, FNumero : String;

protected

function GetRua : string;

function GetBairro : string;

function GetNumero : string;

procedure SetRua (Value : string);

procedure SetBairro (Value : string);

procedure SetNumero (Value : string);

public

property Rua : string read GetRua write SetRua;

property Bairro : string read GetBairro write SetBairro;

property Numero : string read GetNumero write SetNumero;

End;

TPessoa = Class

private

FMatricula : string;

FNome : string;

protected

function GetMatricula : string;

function GetNome : string;

procedure SetMatricula (Value : string);

procedure SetNome (Value : string);

public

Endereco : TEndereco;

constructor Create;

destructor Destroy; override;

property Matricula : string read GetMatricula write SetMatricula;

property Nome : string read GetNome write SetNome;

End;

TProfessor = Class(TPessoa)

private

FDepartamento : string;

FAulasMes : byte;

protected

function GetDepartamento : string;

function GetAulasMes : byte;

procedure SetDepartamento (Value : string);

procedure SetAulasMes (Value : byte);

public

property Departamento : String read GetDepartamento write SetDepartamento;

property AulasMes : byte read GetAulasMes write SetAulasMes;

End;

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

{********************** TPessoa******************}

constructor TPessoa.Create;

Begin

inherited Create;

Self.Endereco := TEndereco.Create;

End;

destructor TPessoa.Destroy;

Begin

Self.Endereco.Free;

inherited Destroy;

End;

function TPessoa.GetMatricula : string;

Begin

Result := Self.FMatricula;

End;

function TPessoa.GetNome : string;

Begin

Result := Self.FNome;

End;

procedure TPessoa.SetMatricula (Value : string);

Begin

Self.FMatricula := Value;

End;

procedure TPessoa.SetNome (Value : string);

Begin

Self.FNome := Value;

End;

{********************** TProfessor******************}

function TProfessor.GetDepartamento : string;

Begin

Result := Self.FDepartamento;

End;

function TProfessor.GetAulasMes : byte;

Begin

Result := Self.FAulasMes;

End;

procedure Tprofessor.SetDepartamento (Value : string);

Begin

Self.FDepartamento := Value;

End;

procedure Tprofessor.SetAulasMes (Value : byte);

Begin

Self.FAulasMes := Value;

End;

end.

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

unit Figura;

interface

type

TFigura = Class

private

FCor : string;

protected

function GetCor : string;

procedure SetCor (Value : string);

public

procedure Desenhe; virtual; abstract;

property Cor : string read GetCor write SetCor;

End;

TQuadrado = Class (TFigura)

private

FX : real;

protected

function GetX : real;

procedure SetX (Value : real);

public

procedure Desenhe ; override;

property X : real read GetX write SetX;

End;

TRetangulo = Class (TQuadrado)

private

FY : real;

protected

function GetY : real;

procedure SetY (Value : real);

public

procedure Desenhe; override;

property Y : real read GetY write SetY;

End;

TCirculo = Class (TFigura)

private

FRaio : real;

protected

function GetRaio : real;

procedure SetRaio (Value : Real);

public

procedure Desenhe ;override;

property Raio : real read GetRaio write SetRaio;

End;

implementation

uses dialogs, SysUtils;

{************TFigura************}

function TFigura.GetCor : string;

Begin

Result := Self.FCor;

End;

procedure TFigura.SetCor (Value : string);

Begin

Self.FCor := Value;

End;

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

unit Vetor;

interface

const

Tam = 100;

type

Vetor_T = array[1..Tam] of integer;

TVetorInteiro = class

private

FDados : Vetor_T;

FTamanho : integer;

protected

function GetDados (Posicao : integer) : integer;

procedure SetDados (Posicao ,Value : integer);

function GetTamanho : integer;

procedure SetTamanho (Value : integer);

public

property Tamanho : integer read GetTamanho write SetTamanho ;

property Dados[Posicao : integer] : integer

read GetDados write SetDados; default;

Procedure Insere( Value : integer);

procedure Inverte;

End;

implementation

{ TVetorInteiro}

function TVetorInteiro.GetTamanho : integer;

Begin

Result := Self.FTamanho;

End;

procedure TVetorInteiro.SetTamanho (Value : integer);

Begin

Self.FTamanho := Value;

End;

function TVetorInteiro.GetDados ( Posicao : integer) : integer;

Begin

Result := Self.FDados[Posicao];

End;

procedure TVetorInteiro.SetDados (Posicao , Value : integer);

Begin

Self.FDados[Posicao] := Value;

End;

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

procedure TVetorInteiro.Insere( Value : integer);

Begin

with Self do

Tamanho := Tamanho + 1;

try

Dados[Tamanho] := Value

except

Tamanho := Tamanho - 1;

end;

End;

procedure TVetorInteiro.Inverte;

Var

i, f : byte;

aux : integer;

Begin

i := 1;

f := Self.Tamanho;

while i < f do

Begin

aux := Self[i];

Self[i] := Self[f];

Self[f] := aux;

inc(i);

inc(f,-1);

End;

End;

end.

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

Exemplos:

var

F : File;

begin

AssignFile(F,’Arquivo.xxx’);

Reset(F);

try

{ código que atualiza o arquivo F}

finally

CloseFile(F);

end;

end;

Tratando Exceções

try

<instrução 1>;

<instrução n>

except

[else

<instrução 1>;

<instrução n>]

end;

Tratando Uma Exceção

on <tipo de exceção> do

<instrução>;

Quando uma exceção é tratada, o fluxo de execução continua na instrução seguinte ao tratamento.

Para permitir que o tratamento da exceção prossiga no tratamento default, utiliza-se a palavra-chave raise no fim do bloco de

instruções do tratamento para que a exceção seja lançada novamente.

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E

Principais Classes de Exceção

Classe Descrição

EAceessViolation Acesso inválido a uma região de memória.

EConvertError As funções StrToInt ou StrToFloat não consegue converte uma string num valor numérico

válido

EDivByZero Divisão de inteiro por zero

EGPFault Acesso a memória não permitido

EInOutError Erro de I/O de arquivo

EIntOverFlow Operação inválida com número inteiro

EInvalidCast Typecast inválido utilizando o operado As

EInvalidOp Operação inválida com número real

EOutOfMemory Memória Livre insuficiente para alocar objeto

EOverflow Número real excedeu a faixa válida

ERangeError Valor excede a faixa definida para o inteiro

EStackOverflow Quando a pilha (stack) não pode crescer dinamicamente

EUnderflow Número real menor que a faixa válida

EZeroDivide Divisão de real por zero

Exemplos:

function Media(Soma, NumeroDeItens: Integer): real;

begin

try

Result := Soma div NumeroDeItens;

except

on EZeroDivide do

Result := 0;

end;

end;

F 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B EF 0 B E