Sunteți pe pagina 1din 101

Autor: Fábio Pagoti

Instrutor: Fábio Pagoti


Orientação a Objetos em ABAP
Cópia de Marcos

Sumário

1 Prefácio
2 Memória eidética: O mundo procedural
2.1 Definição dos dados
2.2 Definição da lógica
2.3 Refletindo sobre as definições no mundo procedural
2.3.1 Divisão de responsabilidades
2.3.2 Reaproveitamento de código
2.3.3 Testes Unitários
2.3.4 Encapsulamento
2.3.5 Falsos mitos sobre as vantagens de OO
2.4 O TOP Include do Grupo de Função
3 Conceitos básicos
3.1 Classes
3.2 Referências
3.3 Objetos (ou instâncias)
3.4 O processo de construção e destrução de um objeto
3.4.1 Criação de objetos
3.4.2 Destruição de Objetos e o Garbage Collector
3.4.3 Tabela interna de referências
3.4.4 LIKE REF TO
3.5 Atributos
3.6 Métodos
4 Conceitos intermediários
4.1 Construtores
4.1.1 Construtor de Instância
4.1.2 Construtor estático (ou de classe)
4.2 Auto‐referência “me”
4.3 Sessões de visibilidade
4.3.1 PUBLIC SECTION
4.3.2 PRIVATE SECTION
4.4 Atributos e Métodos de Instância vs Estáticos

1
Orientação a Objetos em ABAP
Cópia de Marcos

4.4.1 Atributos de instância


4.4.2 Atributos estáticos
4.4.3 Métodos de instância
4.4.4 Métodos estáticos
4.5 Herança
4.5.1 Sessão protegida
4.6 Eventos
4.7 Classes de exceção
4.8 Interfaces
5 Conceitos Avançados
5.1 Abstração
5.1.1 Classes abstratas
5.1.2 Métodos abstratos
5.2 Final
5.2.1 Classes Final
5.2.2 Métodos Final
5.3 Geração de Instância
6 Conclusão

2
Orientação a Objetos em ABAP
Cópia de Marcos

1 Prefácio
Este livro foi criado no ano de 2016 para tentar solucionar um problema
que deveria na opinião do autor ter sido resolvido por volta de uma
década antes: o problema de ainda haver desenvolvedores ABAP sem o
conhecimento necessário em orientação a objetos para exercer com
sucesso suas atividades no dia‐a‐dia.

Adquirir tal conhecimento talvez tenha sido opcional ou mais do que o


suficiente em certa época, mas se você está lendo este prefácio deve
compartilhar da minha opinião que este tempo já passou.

Claro que há muitos desenvolvedores ABAP que alegam não precisar de


orientação objetos para realizarem seus trabalhos. Eles provavelmente
sempre implementaram BAdI’s sem ter total convicção do que estavam
fazendo e acabaram tratando problemas que a orientação a objetos
elementar resolve de maneira simples usando artifícios quase
indecifráveis em termos de lógica. Quem diz isso é alguém que já viu os
comandos EXPORT e IMPORT sendo usados para transferir dados do
mesmo objeto simplemente por estarem em diferentes métodos.

Mas mesmo que tal pessoa nunca tenha tido dificuldades para
implementar BAdI’s, será que esta pessoa recebe outros tipos de
demanda das 8 as 5? Será que ela é alocada em projetos que envolvem
coisas diferentes ou modernas e até mesmo obrigatórias para quem quer
se considerar um desenvolvedor ABAP sério?

A ideia deste livro é de não esgotar os exemplos. Falo de demandas e


projetos que envolvem Enhancements Framework, Workflow, PI, Web
Dynpro, FPM, SAP Gateway (necessário ou não por conta do Fiori), BOPF,
CRM, BRF+, HANA, etc. Certamente Orientação a Objetos (ou

3
Orientação a Objetos em ABAP
Cópia de Marcos

simplesmente OO) é um conhecimento que vai muito além de um mero


ALV que responde a um duplo clique.

A quem diga que o ABAP não é orientado a objetos pois não tem todos os
recursos que o Java tem. Se encontrar alguém na rua que lhe diga tal
blasfêmia (palavra mais próxima do que o autor gostaria de dizer
encontrada) diga a ela que Java não implementa todos os recursos de
orientação a objetos do SmallTalk, que foi criado em 1969. Encerre a
conversa neste ponto para não perder o amigo.

Independente de como os ABAPers enxergam o ABAP, este conhecimento


é de vital importância a você meu caro amigo. Claro, caso você queira
continuar sua jornada como ABAP.

Caso você queira continuar sua jornada como ABAP, continue na próxima
página.

4
Orientação a Objetos em ABAP
Cópia de Marcos

2 Memória eidética: O mundo


procedural
Para entender o que é um objeto, é preciso entender bem como funciona
a alocação de memória em um programa ABAP e para começar neste
assunto vamos direto ao ponto que o desenvolvedor ABAP se sente em
casa: no mundo procedural.

Entenda por mundo procedural qualquer programa ABAP baseado em


rotinas locais (FORM) ou globais (módulos de função).

Independente do tipo de programa, seja um executável (também


conhecido como report), um module pool (vulgarmente conhecido como
online) ou até mesmo um smartform, algumas características são comuns
no mundo procedural.

2.1 Definição dos dados


Tais programas reservam um ou mais trechos de código para a declaração
de tipos, constantes e variáveis, usadas extensivamente ou em certos
pontos da aplicação como um todo. Desenvolvedores ABAP conhecem tais
techos como TOP Include ou Include TOP ou simplesmente reservam tal
espeço no cabeçalho do programa.

Obviamente tais tipos e variáveis podem e devem ser declarados


localmente dentro de rotinas e funções quando usados em pequenos
trechos.

Contudo, ainda existe tal espaço reservado para declarações gerais e


consequentemente para fins diversos.

5
Orientação a Objetos em ABAP
Cópia de Marcos

Exemplo: Um programa executável que possui:


➔ Uma tela de seleção (criada com PARAMETERS e SELECT‐OPTIONS ‐
que são representados por variáveis simples e tabelas internas
respectivamente)
➔ Alguma lógica de seleção de dados (com work areas e tabelas
internas usadas como destino e auxílio de comandos SELECT e
chamadas de funções que as populam)
➔ Certa representação do resultado final (via arquivo, ALV, WRITE,
resultado de um batch input ‐ seja como for isso também envolve a
declaração de tipos e variáveis).

Para organizar sua obra o desenvolvedor ABAP cuidadoso incluir


comentários ilustrativos quando a responsabilidade de um conjunto de
tipos e variáveis. Por exemplo, para indicar que algumas tabelas internas
são usadas para a realização de um batch input ou para a saída em forma
de ALV.
 

2.2 Definição da lógica


Sabendo onde os dados são criados, vamos refletir como a lógica de uma
aplicação procedural é criada.

Tipicamente encontramos um conjunto encadeado de rotinas e funções


separadas por partes, uma após a outra. Seja várias chamadas em
sequência dentro do mesmo bloco, seja um AT SELECTION‐SCREEN antes
de um START‐OF‐SELECTION ou até mesmo um PROCESS BEFORE OUTPUT
(PBO) antes de um PROCESS AFTER INPUT (PAI).

Pensando em boas práticas, cada rotina e função recebe como forma de


parâmetros somente o que usará para fazer o que deve ser feito ‐ nem
mais, nem menos.

6
Orientação a Objetos em ABAP
Cópia de Marcos

Esta boa prática permite que deixemos o código mais legível, adaptável e
reutilizável.
➔ Legível pois fica fácil saber o que a função espera de nós para que
ela funcione.
➔ Adaptável pois não precisamos alterar algo que está fora da função
para poder alterar o seu comportamento
➔ Reutilizável pois podemos passar os mesmos parâmetros em
diferentes lugares para ter o mesmo efeito. Tais lugares podem ser
simplesmente diferentes pontos na mesma aplicação (bom cenário
para rotinas locais) ou até em aplicações diferentes (bom cenário
para o uso de módulos de função).

É possível não declarar parâmetros em uma rotina local e usar tipos e


variáveis definidos fora dela e ter um programa funcional. É possível
também que uma pessoa tenha a capacidade de lamber seus próprios
cotovelos. Geralmente a reação de uma outra pessoa ao ver qualquer um
dos casos anteriores é a mesma.

2.3 Refletindo sobre as definições no mundo


procedural
É muito provável que o que você leu até então é trivial por conta de sua
experiência há alguns anos, e é bem por isso que a sessões anteriores são
bem curtas. Mas elas são importantes para fazermos algumas reflexões
sobre o mundo procedural. Considere que os itens abaixo se aplicam a
programas procedurais bem construídos, seguindo melhores práticas de
desenvolvimento. 

2.3.1 Divisão de responsabilidades


No mundo procedural, dividimos responsabilidades.

7
Orientação a Objetos em ABAP
Cópia de Marcos

Algumas variáveis são usadas na seleção de dados e outras na interação


com o usuário.

Algumas rotinas servem para calcular enquanto outras servem para exibir
um resultado.

2.3.2 Reaproveitamento de código


Código relevante para várias aplicações são postos em módulos de função
separados logicamente em grupos de função. Podemos reaproveitar tais
instruções simplesmente chamando a mesma função em diversas
aplicações. Tais chamadas são ainda facilmente rastreáveis usando a
função de lista de utilização, que salva a vida de milhares de ABAPers
diariamente.

2.3.3 Testes Unitários


Ainda com módulos de função, podemos criar testes unitários e até testes
em sequência pela transação SE37, o que permite testar tais trechos de
código de forma independente.

2.3.4 Encapsulamento
Apesar de ser um termo constantemente usado na orientação a objetos, o
mundo procedural também provê encapsulamento. Um report que chama
uma função de seleção de dados não precisa conhecer nada além dos
parâmetros necessários para fazer a chamada. Se internamente a função
faz 1 ou 15 SELECTs não é possível descobrir lendo somente o trecho de
código do programa que contém a instrução CALL FUNCTION. 

2.3.5 Falsos mitos sobre as vantagens de OO


Após fazer tal reflexão sobre como é feita a organização e construção de
programas procedurais, podemos fazer uma análise mais crítica sobre

8
Orientação a Objetos em ABAP
Cópia de Marcos

quais serão de fato as vantagens exclusivas da orientação a objetos em


relação ao mundo procedural.

Divisão de responsabilidade, reaproveitamento de código, testes unitários


e encapsulamentos são características de uma aplicação alcançáveis em
ambos os mundos, todavia feitos de uma maneira diferente. Seria raso
afirmar que tais fatores são a vantagem da orientação a objetos em
relação ao modelo rústico.

Há outros conceitos porém que somente a orientação a objetos irá prover


de uma maneira ​ viável​ instanciação,​
. O principal deles, o conceito de ​
que será estudado mais adiante.

2.4 O TOP Include do Grupo de Função


Talvez você ficado curioso em saber porque o nome deste capítulo é
“Memória eidética” (termo também conhecido como “memória
fotográfica). Esta é uma analogia como o gerenciamento de memória é
feito numa aplicação procedural, em especial para as que usam funções
globais.

Você já usou o TOP Include de um Grupo de funções? Sabe em detalhes o


que acontece com as variáveis declaradas nele antes e depois dos
módulos de funções serem chamados em uma aplicação? Vamos analisar
tal tópico para então entender mais adiante o que significa ​
instanciação.

O que será discutido nesta sessão com certeza deveria ser sabido por
quem já trabalha com ABAP há algum tempo, mas me arrisco em dizer
que a importância dado a tal conhecimento é de certa forma ignorado ou
menosprezado.

9
Orientação a Objetos em ABAP
Cópia de Marcos

Podemos pensar em Includes como principalmente uma forma de agrupar


um trecho de código. Uma forma simples de entender Includes em ABAP
para programadores que tem conhecimentos em .NET, é associá‐los com
namespaces em C#.

É possível também reutilizar código através da reutilização de Includes e


o código standard faz isso de maneira obsessiva. Porém, quem já
vivenciou tal prática sabe que hoje existem melhores formas de se
reutilizar código. O standard faz isso até os dias atuais muito mais por
uma questão de retrocompatibilidade do que por qualquer outro motivo.

O TOP Include acaba sendo tão usado e importante, que será estudado
em detalhes. Como geralmente ele é usado no começo de uma aplicação,
recebe tal nome diferenciado. Geralmente o desenvolvedor ABAP está
acostumado a trabalhar com TOP Includes em programas executáveis
(report) e pools de módulos (“​online”)​
. Contúdo, tais includes também
estão presentes em grupos de função.

Quando um grupo de função é criado, automaticamente um TOP Include é


criado dentro dele. As variáveis declaradas neste include podem ser
usadas por qualquer módulo de função dentro do mesmo grupo ​ somente​
.
Tal conceito prova que grupos de função não são meramente separações
lógicas de funções mas sim entidades que carregam dados que podem por
sua vez ser compartilhados pelas funções contidas neles.

Abaixo, temos o código gerado de um grupo de função chamado ZOO_FG.

******************************************************************* 
*​
   ​
System​
­​
defined​
 ​
Include​
­​
files​
.​
                                 * 
******************************************************************* 
  INCLUDE LZOO_FGTOP​
.​
                        ​
" Global Data 
  INCLUDE LZOO_FGUXX​
.​
                        ​
" Function Modules 
 

10
Orientação a Objetos em ABAP
Cópia de Marcos

******************************************************************* 
*​
   ​
User​
­​
defined​
 ​
Include​
­​
files ​
(​
if​
 necessary​
).​
                    * 
******************************************************************* 
*​
 INCLUDE LZOO_FGF​
...​
                        ​
" Subroutines 
*​
 INCLUDE LZOO_FGO​
...​
                        ​
" PBO­Modules 
*​
 INCLUDE LZOO_FGI​
...​
                        ​
" PAI­Modules 
*​
 INCLUDE LZOO_FGE​
...​
                        ​
" Events 
*​
 INCLUDE LZOO_FGP​
...​
                        ​
" Local class implement. 
*​
 INCLUDE LZOO_FGT99​
.​
                        ​
" ABAP Unit tests 
Grupo de Função ZOO_FG

Dentro deste grupo de função, criaremos dois módulos de função, ambos


que acessam a mesma variável a ser definida no include LZOO_FGTOP.

FUNCTION​
­​
POOL zoo_fg​
.​
                       ​
"MESSAGE­ID .. 
 
*​
 INCLUDE LZOO_FGD​
...​
                        ​
" Local class definition 
 
DATA v_count TYPE i. 
 
Include LZOO_FGTOP

O primeiro módulo de função simplesmente incrementa o valor da


v_count​
variável ​ .

FUNCTION Z_OO_INCREMENT_COUNTER. 
 
  ADD ​
1​
 TO v_count. 
 
ENDFUNCTION. 
 
Módulo de Função Z_OO_INCREMENT_COUNTER

O segundo módulo de função captura o valor da variável no include e


preenche um parâmetro de exportação.

11
Orientação a Objetos em ABAP
Cópia de Marcos

FUNCTION Z_OO_GET_COUNTER 
  EXPORTING 
    EX_COUNT TYPE I. 
 
  ex_count ​
=​
 v_count. 
 
ENDFUNCTION. 
Módulo de Função Z_OO_GET_COUNTER

Representando nosso grupo de função graficamente, temos:

Representação gráfica do módulo de função

As conexões a esquerda representam os únicos pontos de acesso1 ao nosso


grupo de função ‐ que são seus módulos. Todas as variáveis declaradas

1
Não considera‐se aqui o acesso a variável na pilha de execução via FIELD‐SYMBOLS e o comando
ASSIGN

12
Orientação a Objetos em ABAP
Cópia de Marcos

nos includes que estão no grupo de função (que é o caso da variável


v_count​)​
, podem ser apenas2 acessadas pelos módulos de função.

Vamos agora criar uma aplicação simples que chama tais módulos de
função. Nosso foco será em entender o que acontece com a variável
v_count contida dentro do grupo de funções ‐ mesmo que do ponto de
vista da aplicação nem se saiba da sua existência.

REPORT zoo_fg_caller. 
 
DATA current_value TYPE i. 
 
DO ​
5​
 TIMES. 
 
  CALL FUNCTION ​
'Z_OO_GET_COUNTER' 
    IMPORTING 
      ex_count ​
=​
 current_value. 
 
  WRITE ​
/​
 current_value. 
 
  CALL FUNCTION ​
'Z_OO_INCREMENT_COUNTER'. 
 
ENDDO. 
Programa ZOO_FG_CALLER

➔ DESAFIO !!!
Você consegue imaginar qual seria a saída do programa?

Opção 1 Opção 2 Opção 3


0 0 0
0 1 1
0 2 0
0 3 1
0 4 0

2
Tais variáveis poderiam ser acessadas por telas e outros includes definidos no grupo de função, caso
existissem.

13
Orientação a Objetos em ABAP
Cópia de Marcos

Resposta: ​Você acertou se respondeu a opção 2. Enquanto a opção 3 não


faz sentido algum, é compreensível caso você tenha achado que a opção
1 seria a correta. Note que todas as opções começam imprimindo zero. A
dúvida começa quando tentamos entender o que acontece em memória
uma vez que nossa aplicação cai na segunda ocorrência da instrução DO.

Para entender, vamos representar graficamente a aplicação chamando


nossos módulos de função.

Representação de Programa chamando módulos de função

Precisamos entender que na imagem acima temos duas aplicações ABAP:


um programa executável e um grupo de funções. A forma que se cria cada
um destes é diferente, mas ambos possuem variáveis declaradas em
memória. O ABAP trata as variáveis de forma igual independente do tipo
de aplicação.

14
Orientação a Objetos em ABAP
Cópia de Marcos

A variável current_value do programa executável é posta em memória


assim que o programa é carregado. A variável existe em memória até o
encerramento do mesmo, quando então a memória do servidor de
aplicação é desalocada. No grupo de funções, o mesmo processo
acontece: quando o grupo de função é posto em momória, todas suas
variáveis são alocadas em memória e permanecem lá até o encerramento
do grupo de funções.

Tal afirmação gera duas novas dúvidas:

➔ Quando de fato o grupo de função é alocado em momória?

Assim que algum módulo de função deste é chamado. Logo, não importa
qual foi o primeiro grupo de função chamado. Antes da chamada ser de
fato realizada o ABAP aloca todo o grupo de função em memória: isso
incluir as variáveis definidas no TOP include do grupo de função.

➔ Quando se dá o encerramento de um grupo de função?

No mesmo momento que o programa que o chama é encerrado. Logo,


pode‐se entender que um grupo de função nunca é encerrado de maneira
isolada ‐ sempre quem faz a chamada a algum dos seus módulos é
encerrado juntamente ao primeiro.

Note ainda que é totalmente possível haver um módulo de função


chamando um outro módulo de função que está contido num grupo
diferente. Ainda neste caso nada muda: caso o segundo grupo de função
não esteja em memória esta será alocada antes da primeira chamada a
seu módulo e será desalocada no mesmo momento que o primeiro grupo
de função for desalocado.

15
Orientação a Objetos em ABAP
Cópia de Marcos

Em suma, grupos de função tem uma memória eidética pois as variáveis


em seu TOP include permanecem com os mesmos valores mesmo depois
da execução de um CALL FUNCTION.

O entendimento de tal característica dos grupos de função é fundamental


para entender o comportamento de um ​ objeto,​visto que este pode ser
desalocado de memória muito antes da aplicação que o chamou ser
encerrada.

Anteriormente afirmamos que:

Há outros conceitos porém que somente a orientação a objetos irá


prover de uma maneira ​viável​
.

Apesar de não termos controle em quando um grupo de função é


desalocado de memória, podemos definir um módulo de função
resetar/limpar​
responsável por ​ as variáveis dentro de seu TOP Include.

Tal procedimento funciona, mas é considerado aqui inviável uma vez que
quanto mais variáveis temos, mais comandos CLEAN/REFRESH/FREE
devemos executar, além de ser necessário chamar o módulo responsável
pela limpeza explicitamente.

Não é por coincidência que existem diversos módulos de função standard


“limpadores” que devem ser chamados caso se queira chamar um módulo
de função diversas vezes.

Verifique na SE37 quantos módulos de função existem com os nomes:


➔ *CLEAR*BUFFER*
➔ *CLEAR*GLOBAL*

16
Orientação a Objetos em ABAP
Cópia de Marcos

3 Conceitos básicos
É preciso entender que a orientação a objetos não muda as demandas que
já temos como desenvolvedor, ela simplesmente muda a forma como as
entregamos.

Começaremos na orientação a objetos esclarecendo seus principais


conceitos. É importante ter clara a definição de cada um deles antes de
pensar como seria uma aplicação ABAP orientada a objetos resolvendo um
problema real.

3.1 Classes
Comparado ao mundo procedural, uma classe seria o mais próximo de um
grupo de funções. Todavia existem muitas diferenças. Para evitar
comparações num nível técnico, tentarei deixar a apresentação deste
importante conceito um pouco mais lúdica.

Eu sou uma pessoa que gosta de bolos. Chocolate, cenoura, morango ‐


não importa. É verdade que cada bolo tem suas características mas para
se fazer um bolo, independente de como ele seja, é preciso de uma
forma que, obviamente, define a forma que os bolos serão.

A relação que quero estabelecer entre a forma de bolo e as classes é no


sentido de ser necessário somente uma forma para se fazer uma
quantidade enorme de bolos. Da mesma forma, com uma classe é possível
criar uma quantidade enorme de objetos.

Ao passo que uma forma redonda só permitirá fazermos bolos redondos e


portanto semelhantes entre si, uma classe só permite criar objetos
também semelhantes entre si.

17
Orientação a Objetos em ABAP
Cópia de Marcos

Ainda não vimos o conceito de objetos (representado pelos bolos que


podem ser criados), mas não precisamos defini‐lo ainda para que você
veja uma classe criada em ABAP.

CLASS lcl_ordem_de_venda DEFINITION. 
 
ENDCLASS. 
Exemplo de classe

Muitos comandos podem estar contidos entre o bloco de código acima. O


que temos por hora é uma classe o mais simples possível no ABAP.

As diferenças com grupos de função já começam nesta simples classe.


Primeiramente, usamos o nome de classes no código fonte. No caso acima
usamos para ​criar​
a classe mas depois veremos que também usamos tal
nome para ​usar​a classe.

Falando em nomes de classes, a regra não‐escrita “​


dar bons nomes a tudo
que se cria​
” continua valendo. Uma classe representa algo. Mesmo que
sendo um conceito abstrato, representa um conceito acima de tudo. Por
isso, é comum encontrarmos substantivos sendo usados para nomear
classes.

No que se refere a convenções de código, o prefixo l​ cl​é bastante usado.



local class.​
Esta sigla significa ​ Uma classe local é criada dentro de uma
aplicação (geralmente dentro de algum Include) e por isso pode ser
apenas usada localmente naquele programa. É possível definir classes
globais também (mais semelhantes com grupos de função que são sempre
globais). Neste caso, o ​namespace​ ZCL_​
próprio é ​ . Classes globais serão
vistas mais adiante. Os conceitos vistos neste capítulo são independentes
do escopo local ou global.

18
Orientação a Objetos em ABAP
Cópia de Marcos

3.2 Referências
Agora que temos uma classe o mais básica possível, precisamos saber o
que é possível fazer com ela e a resposta para este caso é: não muito.

Conforme dito antes, uma classe é como se fosse uma forma de bolo.
Para fazer o bolo precisamos usar as mãos: independente se for para
quebrar os ovos e batê‐los ou para abrir a caixa com o bolo em pó pronto.

Tal analogia é usada aqui para ilustrar o que são referências.

Uma referência é como uma mão que segura um (e somente um) bolo. A
nossa mão pode não estar segurando um bolo e do mesmo modo uma
referência pode não estar com objeto algum.

Uma vez que tenhamos posse de uma forma (classe), usamos nossas mãos
para enchermos a forma quantas vezes quisermos.

Da mesma maneira que uma forma de bolo pode ser usada por diversas
pessoas, precisamos declarar quais mãos manipularão quais formas.

DATA​
:​
 r_ordem_a TYPE REF TO lcl_ordem_de_venda, 
      r_ordem_b TYPE REF TO lcl_ordem_de_venda, 
      r_ordem_c TYPE REF TO lcl_ordem_de_venda, 
      r_ordem_d LIKE r_ordem_c. 
Referências a classes

Não se confunda. No exemplo acima temos quatro ​ referências e não


quatro objetos. Uma das principais dificuldades para iniciantes no assunto
da orientação a objeto é diferenciar estes conceitos.

19
Orientação a Objetos em ABAP
Cópia de Marcos

Isso se reflete até na nomenclatura usada por muitos. Enquanto no código


acima optamos por declarar nossas referências usando o prefixo ​ r_​
,
muitos usariam o prefixo ​ o_ (simbolizando um ​
objeto ‐ que está errado
pois não temos nenhum objeto no trecho de código acima).

➔ Afinal, uma referência declarada usando uma classe se refere a


que?

Esta é uma excelente dúvida para se ter neste momento. Olhando o


código que cria as referências vemos o nome da nossa classe sendo usado.
Porém, seria errado afirmar que uma referência “aponta” para uma
classe. Uma referência ​pode​ apontar para um objeto ou estar vazia.

➔ Referências são variáveis (ou data objects)?

Sim, criadas com a variação REF TO. Isso quer dizer que são variáveis que
internamente guardam o endereço de memória de outras variáveis.

Quando a variação REF TO é usada precedendo uma classe, temos o que


chamamos de referência a objeto. Quando tal variação é usada antes de
uma variável primitiva, work area ou tabela interna, temos o que muitos
conhecem como ponteiro: pouco usado no ABAP em aplicações
customizadas mas totalmente possível.

Veja os exemplos abaixo.

TYPES tt_mara TYPE STANDARD TABLE OF mara WITH DEFAULT KEY. 
 
DATA​
:​
 v_i      TYPE i, 
      v_string TYPE ​
string, 
      v_num_10 TYPE numc10, 
      wa       TYPE syst, 
      itab     TYPE tt_mara. 
 

20
Orientação a Objetos em ABAP
Cópia de Marcos

BREAK​
­​
POINT​
.​
 ​
" Debug a partir daqui 
 
 
v_i ​
=​
 ​
10. 
v_string ​
=​
 ​
'Orientação a Objetos'. 
v_num_10 ​
=​
 ​
'01234'. 
 
wa ​
=​
 sy. 
 
SELECT ​
*​
 FROM mara INTO TABLE itab. 
Preenchimento de objetos de dados comuns (variáveis, work area e
tabela interna)

Com certeza o código acima é bem trivial para quem já desenvolve em


ABAP. Ele usa variáveis cujos tipos são estruturas de dados muito
conhecidas: primitivas (usando ou não o dicionário de dados), work areas
e tabelas internas.

A representação de tais variáves em memória é exibida abaixo.

21
Orientação a Objetos em ABAP
Cópia de Marcos

Representação de variáveis comuns

Analise agora o segundo exemplo, fazemos o preenchimento de variáveis


semelhantes, mas declaradas usando referências (note a variação REF TO
sendo usada no comando DATA).

TYPES tt_mara TYPE STANDARD TABLE OF mara WITH DEFAULT KEY. 
 
DATA​
:​
 r_i      TYPE REF TO i, 

22
Orientação a Objetos em ABAP
Cópia de Marcos

      r_string TYPE REF TO ​
string, 
      r_num_10 TYPE REF TO numc10, 
      r_wa     TYPE REF TO syst, 
      r_itab   TYPE REF TO tt_mara. 
 
BREAK​
­​
POINT​
.​
 ​
" Debug a partir daqui 
 
CREATE DATA: 
      r_i, 
      r_string, 
      r_num_10, 
      r_wa, 
      r_itab. 
 
r_i​
­>*​
 ​
=​
 ​
10. 
r_string​
­>*​
 ​
=​
 ​
'Orientação a Objetos'. 
r_num_10​
­>*​
 ​
=​
 ​
'01234'. 
 
r_wa​
­>*​
 ​
=​
 sy. 
 
SELECT ​
*​
 FROM mara INTO TABLE r_itab​
­>*. 
Criação de refências e preenchimento de objetos de dados a que elas se
referem (variáveis, work area e tabela interna)

O que está acontecendo no código acima de diferente?

Temos agora não 5 variáveis porém 10. Cinco delas ainda são as variáveis
anteriores porém para ter acesso a elas agora precisamos usar 5
referências que nos levam até de fato o endereço de memória delas.

Uma imagem vale mais que mil palavras.

23
Orientação a Objetos em ABAP
Cópia de Marcos

Representação de variáveis de referência

Na imagem acima, as variáveis de referência estão em vermelho. As


u, v, x, y ​
letras ​ e z simbolizam endereços de memória. Internamente as
referências guardam tais endereços, que são números inteiros cujo valor
variam bastante. Quando se trabalha com variáveis de referência, o
depurador ABAP converte tais números “aleatórios” em sequenciais para
que se facilite o trabalho do desenvolvedor.

24
Orientação a Objetos em ABAP
Cópia de Marcos

Na imagem abaixo a primeira variável de referência do programa é


exibida no depurador com o endereço ​ 1​
, que não é de fato o endereço de
memória de tal variável pois a conversão do endereço já foi realizada.

Outra diferença entre os dois trechos de código é que quando usamos


referências, a única alocação de memória feita no início da aplicação são
das referências em si. Antes que o comando CREATE DATA seja realizado,
nenhuma das três variáveis primitivas, nem a work area ou a tabela
interna existem ainda em memória. Logo, no início da execução desta
aplicação existem 5 referências em memória e antes do seu
encerramento temos outras 5 variáveis “comuns” alocadas.

Caso você tente usar uma referência ainda não criada na sua aplicação
(usar ‐>* sem antes ter realizado o comando CREATE), um DUMP ocorre.

➔ Checkbox REF TO
Em diversas transações de desenvolvimento, existe um checkbox chamado
REF TO, justamente que define se o que está sendo criada é um
tipo/variável simples ou uma referência a algo.

25
Orientação a Objetos em ABAP
Cópia de Marcos

Podemos encontrar tais checkboxes nas transações SE37 para definir os


tipos dos parâmetros de uma função e SE24 para se definir atributos e
parâmetros de métodos ‐ conceitos estudados mais adiante.

3.3 Objetos (ou instâncias)


Na nossa analogia, objetos são os bolos. Com uma classe, é possível criar
quantos objetos quiser, desde que se tenha pelo menos uma referência
também.
Se estamos estudando orientação a objetos é de se presumir que
deveríamos ter vários destes em nossas aplicações e a resposta é
verdadeira para aplicações orientadas a objetos bem construídas.

Um objeto muitas vezes é chamado também de instância. O processo de


se criar um objeto é corriqueiramente chamado de instanciação.

➔ Como se cria um objeto no ABAP?

A forma mais conhecida é através do comando CREATE OBJECT, sendo


também possível através do comando NEW.

CREATE OBJECT​
:​
  r_ordem_a, 
                r_ordem_b TYPE lcl_ordem_de_venda. 
 
r_ordem_c ​
=​
 NEW lcl_ordem_de_venda​
(​
 ​
). 
 
Criação de objetos

Caso esteja usando uma versão do NetWeaver de meados de 2012, é


possível criar uma referência e um objeto para ela na mesma linha de
código ‐ muito semelhante como o que é feito em Java.

DATA​
(​
r_ordem_e​
)​
 ​
=​
 NEW lcl_ordem_de_venda​
(​
 ​
).

26
Orientação a Objetos em ABAP
Cópia de Marcos

Criação de referência e objeto

3.4 O processo de construção e destrução de


um objeto

Sem dúvida alguma, esta sessão é uma das mais importantes deste livro.
Não passe para a próxima sessão sem antes ter entendido bem o tema
atual, o processo de construção e destrução de um objeto.

Você já foi intruduzido aos conceitos de classes, referências e objetos.


Eles são mais do que o suficiente para confundir aqueles iniciantes a
orientação a objetos.

Isso devido ao fato que é neste âmbito que mora uma das principais
diferenças entre o mundo procedural e o orientado a objetos ‐ a
utilização da memória de uma aplicação.

Vimos no capítulo anterior como um grupo de função funciona. Sabemos


quando a memória usada para as variáveis declaradas em seu TOP include
é desalocada: quando a aplicação termina. Sabemos também que a
alocação acontece quando qualquer módulo de função pertencente a tal
grupo é chamado.

No mundo orientado a objetos, não é bem assim. Apesar de toda a


memória ser desalocada quando a aplicação como um todo se encerra,
objetos​
podemos ter ​ sendo desalocados de memória.

Abaixo temos a declaração da nossa classe e suas referências.

27
Orientação a Objetos em ABAP
Cópia de Marcos

CLASS lcl_ordem_de_venda DEFINITION. 
 
ENDCLASS. 
 
DATA​
:​
 r_ordem_a TYPE REF TO lcl_ordem_de_venda, 
      r_ordem_b TYPE REF TO lcl_ordem_de_venda, 
      r_ordem_c TYPE REF TO lcl_ordem_de_venda, 
      r_ordem_d LIKE r_ordem_c.
Declaração de classe e referências

Graficamente, temos:

Nossas referências ainda não apontam para ​objetos. Isso porque na


verdade nem temos objetos criados! Até o momento temos 1 classe, 4
referências e nenhum objeto.

3.4.1 Criação de objetos

28
Orientação a Objetos em ABAP
Cópia de Marcos

Vamos criar nosso primeiro objeto. Já sabemos que para criar um objeto
precisamos de uma referência.

CREATE OBJECT r_ordem_a.
Criação de primeiro objeto

O comando CREATE OBJECT inspeciona a declaração da referência


r_ordem_a e nota que esta se refere a classe lcl_ordem_de_venda. Logo,
ele cria um objeto de acordo com a definição da classe (que por hora
ainda é vazia para não nos adiantarmos).

Objetos são tipicamente representados por circunferências e a imagem


acima segue prática. Como resultado, temos:

Representação do primeiro objeto criado

Como pode‐se notar pela imagem e código acima, somente a referência


r_ordem_a aponta para um objeto. Todas as outras referências estão em
memória.

29
Orientação a Objetos em ABAP
Cópia de Marcos

Vamos agora criar outro objeto.

r_ordem_b ​
=​
 NEW lcl_ordem_de_venda​
(​
 ​
).
Criação de segundo objeto através do comando NEW

Usamos outro comando acima simplesmente para informar desta


possibilidade. Tal comando espera um tipo e uma classe nada mais é que
um tipo complexo.

A criação do segundo objeto nos leva a representar a memória da


aplicação de acordo.

Representação de dois objeto criados

Até o momento, esta tal de orientação a objetos não parece ser tão
difícil não é mesmo?

➔ DESAFIO !!!

30
Orientação a Objetos em ABAP
Cópia de Marcos

Chegou a hora de se deparar com um código campeão na geração de


dúvidas.

Dado o cenário apresentado até então onde temos dois objetos criados, o
que acontece quando executamos a instrução abaixo? Tente imaginar ou
desenhar como a representação em memória ficaria.

r_ordem_c ​
=​
 r_ordem_b.
Atribuição entre referências

Reposta: ​A resposta para tal desafio se resume a lembrar que as


referências guardam endereços de memória que no fundo são números.
Imaginando que a referência r_ordem_b guarda o endereço de memória
548, estamos copiando tal valor para a referência r_ordem_c. O resultado
de copiar o endereço de memória NÃO é o mesmo de copiar o objeto.

Logo, a resposta abaixo está incorreta.

Resposta incorreta: copiar um endereço de memória não duplica um


objeto

31
Orientação a Objetos em ABAP
Cópia de Marcos

A resposta correta para o desafio é representada abaixo.

Resposta correta: mais de uma referência pode apontar para o mesmo


objeto

➔ Podemos ter mais de uma referência apontando para o mesmo


objeto?

Sim e isso é muito mais comum do que talvez pareça por hora. Toda
aplicação orientada a objetos vai ter em algum certo momento muito
mais que duas referências apontando para o mesmo objeto.

➔ Podemos ter a mesma referência apontando para mais de um


objeto?

Não. Assim como uma variável declarada como inteiro só pode ter um
valor, uma referência só pode guardar um endereço de memória, além de
estar vazia. A diferença no caso das referência é que caso algum comando
seja exercido em uma referência “vazia” (que não aponta para objeto
algum), um DUMP ocorre. A única exceção a esta regra é sobre os

32
Orientação a Objetos em ABAP
Cópia de Marcos

comandos que criam os objetos para as referências como o CREATE


OBJECT e NEW.

3.4.2 Destruição de Objetos e o Garbage Collector

Assim como podemos preencher uma referências, podemos apagar seu


conteúdo usando comando CLEAR.

CLEAR r_ordem_a.
Limpando uma referência

É justamente neste cenário que temos uma grande diferença com os


grupos de função: um objeto que não possui referências é retirado da
memória. Em outras palavras, a memória que aquele objeto ocupava
poderá ser usada para outro fim.

Apesar de isso não ser um problema típico quando está se desenvolvendo,


é importante saber que esta desalocação de memória não acontece
automaticamente.

Muitas linguagens orientadas a objetos, ABAP incluso, possuem um


Garbage Collector​
, que é responsável por justamente identificar objetos
que não possuem referências e reaproveitar a memória que os mesmos
ocupavam. Uma vez que não temos mais como acessar o objeto, não há
porque ele continuar residindo em memória. A boa notícia é que o
desenvolvedor não precisa se preocupar com isso pois este processo é
transparente.

Logo, representando a memória antes da atuação do Garbage Collector,


temos:

33
Orientação a Objetos em ABAP
Cópia de Marcos

Memória imediatamente após comando CLEAR mas antes da atuação do


Garbage Collector

Garbage Collector​
Depois da atuação do ​ , temos:

Memória após a atuacão do Garbage Collector: objeto é excluído de


memória

34
Orientação a Objetos em ABAP
Cópia de Marcos

É possível “forçar” a execução do ​Garbage Collector através do


depurador ABAP escolhendo a opção ​
Edit > System Functions > Start
Garbage Collector​
.

➔ DESAFIO !!!

Sabendo o que acontece no momento que se apaga uma instância que


antes apontava para um objeto, qual o efeito de apagar o conteúdo da
referência r_ordem_b? Pense na representação assim como fez no desafio
anterior.

Resposta: ​Neste caso, o objeto não é apagado de memória pelo ​


Garbage
Collector visto que este ainda pode ser acessado pela referência
r_ordem_c. O mesmo aconteceria se a referência r_ordem_c fosse
deletada ao invés da r_ordem_b. O que importa para o ​
Garbage Collector
atuar é encontrar um objeto sem referência nenhuma. Todas as
referências que apontam para o mesmo objeto tem a mesma importância.
É indiferente qual foi a referência usada no momento da criação do
objeto. Assim sendo, temos:

Representação após limpeza da referência r_ordem_b

35
Orientação a Objetos em ABAP
Cópia de Marcos

Muitas vezes, não se sabe quantos objetos de um determinado tipo serão


criados durante a execução de uma aplicacão. Também é muito comum
não querer desassociar todas as referências de um determinado objeto ‐
para manté‐lo em memória acessível quando se fizer necessário. Nestes
casos, precisamos de um número “ilimitado” de referências declaradas na
nossa aplicação.

3.4.3 Tabela interna de referências

Para resolver tal necessidade, podemos declarar uma tabela interna de


referências. Tal tabela interna permite termos um número qualquer de
referências na mesma estrutura de dados. Os comandos próprios para
tabelas internas podem ser usados livremente.

DATA t_r_ordens TYPE TABLE OF REF TO lcl_ordem_de_venda. 
 
DATA r_ordem TYPE REF TO lcl_ordem_de_venda. 
 
CREATE OBJECT r_ordem. 
 
APPEND r_ordem TO t_r_ordens.
Declaração e preenchimento de uma tabela interna de referências

Com o código acima, poderíamos reutilizar a referência r_ordem tantas


vezes quanto fossem necessárias para a criação de objetos do tipo ordem
de venda. Isso é verdadeiro desde que antes de reescrever tal referência
(o que invalidaria o objeto), criássemos uma linha nova na tabela interna
de referências apontando para o objeto mais recente.

36
Orientação a Objetos em ABAP
Cópia de Marcos

Referência sendo usada para criar uma quantidade indefinida de objetos.


Uma tabela interna de referências é necessária para evitar a destrução
dos objetos.

3.4.4 LIKE REF TO


A nossa referência r_ordem_d (declarada através da variação LIKE REF
TO) serve para lembrar que o comando LIKE não copia o calor da variável
usada após o REF TO. Logo em todo momento desta aplicação a
referência r_ordem_d se manteve vazia.

3.5 Atributos

Até o momento a definição de nossa classe (CLASS DEFINITION…


ENDCLASS.) se manteve vazia. Contúdo conforme dito anteriormente,
classes nada mais são que tipos complexos. Diga‐se de passagem, muito
mais complexos que um mero BEGIN OF.. END OF pode fazer em uma
work area​.

Um atributos basicamente se resumem a declarações de variáveis


colocadas entre o bloco CLASS DEFINITION … ENDCLASS.

37
Orientação a Objetos em ABAP
Cópia de Marcos

Tudo que você já sabe sobre o comando DATA pode ser aplicado neste
contexto. É possível usar tipos primitivos, do dicionário, cláusula LIKE,
definição de work areas e tabelas internas e assim por diante.

É possível também usar tipos (TYPES) e constantes (CONSTANTS) dentro


do bloco CLASS DEFINITION.

Veja o exemplo abaixo.

CLASS lcl_ordem_de_venda DEFINITION. 
  PUBLIC SECTION. 
 
    TYPES tt_items TYPE TABLE OF vbap. 
 
    CONSTANTS c_tipo TYPE vbak​
­​
auart VALUE ​
'OR'. 
 
    DATA​
:​
 valor  TYPE p LENGTH ​
10​
 DECIMALS ​
2, 
          id     TYPE vbeln_va, 
          header TYPE vbak, 
          items  TYPE tt_items. 
 
ENDCLASS.
Atributos de uma classe

Uma vez que seja inserido pelo menos algum conteúdo entre o bloco
CLASS DEFINITION e ENDCLASS, é necessário definir uma ​ sessão de
visibilidade. Discutiremos este assunto num capítulo futuro. Por hora,
sempre inclua a opção PUBLIC SECTION em suas classes para depois
entender o efeito desta.

Novamente comparando com grupos de função, as declarações em uma


classe possuem um comportamento diferenciado.

Primeiramente, quando o programa que possui a classe


lcl_ordem_de_venda for carregado em memória, nenhuma das variáveis

38
Orientação a Objetos em ABAP
Cópia de Marcos

declaradas nela serão alocadas. Isso acontece pois as variáveis declaradas


usando a instrução DATA dentro do bloco CLASS DEFINITION cria variáveis
que pertencem aos objetos desta classe e não a classe em si. A exceção a
esta regra acontecerá para atributos estáticos, vistos mais adiante, no
qual criar variáveis pertencentes a classe e não aos objetos desta.

Supondo que criemos um objeto (usando uma referência) a nossa única


classe, o que teremos é o resultado expresso abaixo.

39
Orientação a Objetos em ABAP
Cópia de Marcos

Objeto com atributos

Obviamente, todas as variáveis irão ser carregadas com seu valor inicial.
Logo o que temos acima é somente uma representação não os valores em
items​
si. A tabela interna ​ por exemplo seria carregada com zero linhas.

40
Orientação a Objetos em ABAP
Cópia de Marcos

Caso criássemos mais dois objetos da mesma classe, somando 3 no total,


teríamos várias vezes as variáveis declaradas. Porém, estas seriam
totalmente independentes uma das outras.

Três objetos do mesmo tipo criados: cada objeto possui seus próprios
dados

No exemplo acima, temos três referências a classe lcl_ordem_de_venda


sendo que cada uma aponta para um objeto distinto já criado.

➔ Neste caso a mesma aplicação pode ter várias variáveis com o


mesmo nome?

Sim, de fato há três variáveis chamadas “id”, três tabelas internas


chamadas “items” e assim por diante. Todavia cada um destas variáveis
contexto​
estão em um ​ de memória diferente.

Temos o mesmo efeito de termos dois TOP Includes de grupos de funções


diferentes em memória com pelo menos uma variável com o mesmo
nome. A diferença é que no caso dos grupos de função ter uma variável

41
Orientação a Objetos em ABAP
Cópia de Marcos

com o mesmo nome em seus includes pode ser mera coincidência,


enquanto ​ todos os objetos de lcl_ordem_de_venda possuirão ​ todos os
atributos definidos dentro da classe. Portanto, não existe algum tipo de
“declaração opcional”. Todos os objetos tem o mesmo formato… bem
como tem os bolos feitos usando a mesma forma.

➔ Como diferenciar os atributos de objeto para objeto sendo que


eles tem o mesmo nome?

Através das referências. Não é possível ler ou escrever em um atributo de


objeto sem tocar em alguma referência. Em outras palavras, a única
forma de se chegar em algum objeto é via uma referência que aponta a
este.

Veja os exemplos abaixo.

DATA r_ordem_a TYPE REF TO lcl_ordem_de_venda. 
 
CREATE OBJECT r_ordem_a. 
 
r_ordem_a​
­>​
id ​
=​
 ​
'1234'. 
 
r_ordem_a​
­>​
valor ​
=​
 ​
1000. 
 
r_ordem_a​
­>​
valor ​
=​
 r_ordem_a​
­>​
valor ​
­​
 ​
100. 
 
r_ordem_a​
­>​
header​
­​
vbeln ​
=​
 r_ordem_a​
­>​
id. 
 
APPEND INITIAL LINE TO r_ordem_a​
­>​
items. 
 
READ TABLE r_ordem_a​
­>​
items INDEX ​
1​
 INTO DATA​
(​
wa_item​
). 
 
LOOP AT r_ordem_a​
­>​
items ASSIGNING FIELD​
­​
SYMBOL​
(<​
item​
>). 
  WRITE ​
/​
 ​
<item>​
­​
vbeln. 
ENDLOOP.
Manipulacão de atributos de um objeto

42
Orientação a Objetos em ABAP
Cópia de Marcos

Note que a referência sempre antecede o atributo em si. Como as


referências são manipuladas usando ‐>, basta trocarmos o asterisco (*)
usado em referências a tipos comuns pelo nome do atributo.

Nota: Usar ‐>* para uma variável que se refere a uma classe não retorna
dados algum.

Por isso, um dos principais pontos chave para se tornar um bom


entendedor de orientação a objetos é saber qual referência está
apontando para qual objeto num dado momento.

3.6 Métodos
Objetos não simplesmente podem carregar dados em forma de atributos
mas também são capazes de processar tais dados. Em outras palavras um
objeto tem a capacidade de possuir código ABAP como seleções no banco
de dados, leitura de arquivos, chamadas a funções, exibições de telas,
etc.

métodos​
Tais instruções são encapsuladas em ​ , que podem ser comparados
a módulos de função no sentido de possuírem parâmetros de entrada e
saída, tratamento de erros, além do código em si.

Por infelicidade do destino, quando a SAP definiu qual seria a sintaxe dos
comandos de orientação a objetos, os comandos relacionados a métodos
talvez não tiveram uma atenção tão especial. O resultado disso é que
uma vez que sua classe tenha métodos (o que tipicamente vai ocorrer)
sua classe irá crescer em número de linhas de código.

No ABAP, separa‐se a declaração da implementação de uma classe. A


parte de declaração define basicamente os atributos e métodos da classe
enquanto a parte de implementação conterá o código que pode ser
depurado. Tais trechos de código estarão ​ sempre dentro da

43
Orientação a Objetos em ABAP
Cópia de Marcos

implementação dos métodos. Logo, precisamos adicionar um novo bloco


de código que conterá tais implementações.

CLASS lcl_ordem_de_venda DEFINITION. 
  PUBLIC SECTION. 
 
" Declaração de atributos (...) 
 
ENDCLASS. 
 
CLASS lcl_ordem_de_venda IMPLEMENTATION. 
 
ENDCLASS.
Blocos DEFINITION e IMPLEMENTATION

Agora que temos os dois possíveis blocos de uma classe, vamos criar um
método o mais simples possível, que por hora não fará rigorosamente
nada (mas que pelo menos existirá).

Primeiramente, vamos ​ declarar o método. Para isso, usamos o comando


METHODS ​(no plural) seguido do nome do método.

CLASS lcl_ordem_de_venda DEFINITION. 
  PUBLIC SECTION. 
 
    TYPES tt_items TYPE TABLE OF vbap. 
 
    CONSTANTS c_tipo TYPE vbak​
­​
auart VALUE ​
'OR'. 
 
    DATA​
:​
 valor  TYPE p LENGTH ​
10​
 DECIMALS ​
2, 
          id     TYPE vbeln_va, 
          header TYPE vbak, 
          items  TYPE tt_items. 
 
    METHODS fazer_absolutamente_nada. 
 
ENDCLASS.
Declaração de método

44
Orientação a Objetos em ABAP
Cópia de Marcos

Por fim, vamos ​


implementar o método no recém criado bloco. Para isso
bloco de código ​
METHOD… ENDMETHOD​ . Note que METHOD neste caso é
no singular.

CLASS lcl_ordem_de_venda IMPLEMENTATION. 
 
  METHOD fazer_absolutamente_nada. 
    BREAK​
­​
POINT. 
  ENDMETHOD. 
 
ENDCLASS.
Implementação de método

O comando BREAK‐POINT aqui ajuda a validarmos se o método pode


realmente ser chamado.

Como os métodos declarados neste cenário pertencem aos objetos e


somente é possível usar os objetos através das referências que apontam a
eles, precisamos também das referências para chamar tais métodos.

DATA r_ordem_a TYPE REF TO lcl_ordem_de_venda. 
 
" Opção 1) Semelhante a chamada de módulos de função 
CALL METHOD r_ordem_a​
­>​
fazer_absolutamente_nada. 
 
" Opção 2) Semelhante a outras linguagens orientada a objetos 
r_ordem_a​
­>​
fazer_absolutamente_nada​
(​
 ​
).
Chamadas de métodos

Classes, referências, objetos, atributos e métodos. Estes termos devem


fazer parte do seu vocabulário para desbravar o que está por vir.

45
Orientação a Objetos em ABAP
Cópia de Marcos

4 Conceitos intermediários
Estamos cada parágrafo mais longe no mar da orientação a objetos. É
hora de estudar conceitos que dificilmente podem ser associados com o
mundo procedural. Esteja aberto a novas formas de escrever código a
partir de agora.

4.1 Construtores
Diferente de outras linguagens orientadas a objetos, o ABAP não permite
que haja mais de um método na mesma classe com o mesmo nome.

Construtores são métodos especiais pois são chamados automaticamente


em momentos bem específicos. Existem dois tipos de métodos
construtores, que são identificados pelo seu nome reservado.

4.1.1 Construtor de Instância

➔ constructor ‐ Também conhecido como “construtor de instância”. A


execução deste método é feita sempre que um objeto novo é criado
(independente do comando usado para isso). O principal uso deste
método é para preencher atributos com valores iniciais.

O construtor de intância é declarado usando o comando METHODS, assim


como os métodos vistos até aqui. O que diferencia este método dos
demais é seu nome.

CUIDADO! No ABAP não é possível dar outro nome ao construtor que não
seja ​
constructor. É comum esquecermos o segundo “c” do método ‐ o

46
Orientação a Objetos em ABAP
Cópia de Marcos

código ativa porém o método acaba não sendo chamado automaticamente


no momento da criação de um objeto.

CLASS lcl_ordem_de_venda DEFINITION. 
  PUBLIC SECTION. 
    METHODS constructor. 
 
ENDCLASS. 
 
CLASS lcl_ordem_de_venda IMPLEMENTATION. 
 
  METHOD constructor. 
 
  ENDMETHOD. 
 
ENDCLASS. 

Constructor de instância

4.1.2 Construtor estático (ou de classe)

➔ class_constructor ‐ Também conhecido como “construtor de


classe” ou “estático”. A execução deste método acontece no
máximo uma vez na aplicação: antes de ser realizada a primeira
operação envolvendo a classe. Caso não haja nenhum uso da classe,
este método simplesmente não é executado.

Existem conceitos que se aplicam a objetos e outros que se aplicam a


classes, como tal construtor. Nestes casos, o comando ABAP sendo usado
muda. Comandos que se referem a classes tipicamente começam com
“CLASS‐”. Por exemplo, o construtor de classe deve ser definido com o
comando CLASS‐METHODS (novamente no plural). A parte de
implementação não muda se comparado aos outros métodos e portando
usa‐se o bloco METHOD… ENDMETHOD (no singular).

47
Orientação a Objetos em ABAP
Cópia de Marcos

CLASS lcl_ordem_de_venda DEFINITION​

  PUBLIC SECTION​

    CLASS​
­​
METHODS class_constructor​

 
ENDCLASS​

 
CLASS lcl_ordem_de_venda IMPLEMENTATION​

 
  METHOD class_constructor​

 
  ENDMETHOD​

 
ENDCLASS. 
Construtor de classe

Uma maneira simples de diferenciar quando cada um dos construtores são


chamados é depurando o programa abaixo.

REPORT zoo_construtores. 
 
CLASS lcl_ordem_de_venda DEFINITION. 
  PUBLIC SECTION. 
    METHODS constructor. 
    CLASS​
­​
METHODS class_constructor. 
 
ENDCLASS. 
 
CLASS lcl_ordem_de_venda IMPLEMENTATION. 
  METHOD constructor. 
    BREAK​
­​
POINT. 
  ENDMETHOD. 
 
  METHOD class_constructor. 
    BREAK​
­​
POINT. 
  ENDMETHOD. 
ENDCLASS. 
 
DATA r_ordem TYPE REF TO lcl_ordem_de_venda. 
 
START​
­​
OF​
­​
SELECTION. 

48
Orientação a Objetos em ABAP
Cópia de Marcos

 
  CREATE OBJECT r_ordem. 
  CREATE OBJECT r_ordem. 
  CREATE OBJECT r_ordem. 

Classe com construtor de instância e classe

Somente construtor de instância pode possuir parâmetros. Ainda, estes


obrigatoriamente devem ser importação somente. Caso este construtor
possua pelo menos um parâmetro obrigatório este será passado através do
comando que cria o objeto (CREATE OBJECT ou NEW).

4.2 Auto-referência “me”


Uma vez compreendida a diferença entre os construtores, chegou a hora
de entender o conceito de auto‐referência.

A ​auto‐referência é uma referência chamada “me” declarada


implicitamente (obviamente usando a variáção REF TO) acessível dentro
de blocos METHOD… ENDMETHOD e portanto pode ser usada somente
dentro de implementações de classes.

Um caso de uso típico da auto‐referência me é dentro do construtor de


instância. Veja o código abaixo.

CLASS lcl_employee DEFINITION. 
  PUBLIC SECTION. 
 
    TYPES ty_pernr TYPE pa0002​
­​
pernr. 
    DATA pernr TYPE ty_pernr. 
 
    METHODS constructor 
      IMPORTING 
        i_personal_number TYPE ty_pernr. 
 
ENDCLASS. 

49
Orientação a Objetos em ABAP
Cópia de Marcos

 
CLASS lcl_employee IMPLEMENTATION. 
  METHOD constructor. 
    me​
­>​
pernr ​
=​
 i_personal_number​
.​
 ​
"​
 ​
auto​
­​
refer​
ê​
ncia 
  ENDMETHOD. 
 
ENDCLASS. 
 
DATA​
:​
 r_employee_1 TYPE REF TO lcl_employee, 
      r_employee_2 TYPE REF TO lcl_employee, 
      r_employee_3 TYPE REF TO lcl_employee. 
 
START​
­​
OF​
­​
SELECTION. 
 
  CREATE OBJECT r_employee_1 
    EXPORTING 
      i_personal_number ​
=​
 ​
'50000000'. 
 
  r_employee_2 ​
=​
 NEW lcl_employee​
(​
 i_personal_number ​
=​
 ​
'50000001'​
 ​
). 
 
" Ha somente um parametro de entrada 
  r_employee_3 ​
=​
 NEW lcl_employee​
(​
 ​
'50000002'​
 ​
).  
 
  WRITE: 
    ​
|​
1​
 ​
­​
 ​
{​
 r_employee_1​
­>​
pernr ​
}|,​
 ​
/, 
    ​
|​
2​
 ​
­​
 ​
{​
 r_employee_2​
­>​
pernr ​
}|,​
 ​
/, 
    ​
|​
3​
 ​
­​
 ​
{​
 r_employee_3​
­>​
pernr ​
}|.
Auto‐referência sendo usada no construtor

No código acima, três objetos são criados. Portanto, o construtor de


instância é chamado três vezes, no momento que o objeto é criado (via
comando CREATE OBJECT ou NEW).

Ao passo que a pilha de execução sai do contexto START‐OF‐SELECTION e


entra no contexto CLASS IMPLEMENTATION… ENDCLASS, a auto‐referência
me se torna acessível. Neste momento, esta referência aponta
exatamente para o objeto sendo criado. É possível acompanhar o
endereço de memória usado nesta referência pelo depurador. Durante a

50
Orientação a Objetos em ABAP
Cópia de Marcos

execucão do programa é possível perceber que o objeto em questão é o


r_employee​
mesmo sendo apontado por alguma das referências ​ .

É possível usar a auto‐referência para chamar métodos pertencentes a


mesma classe.

Vamos aprimorar um pouco nossa classe lcl_employee para exemplificar


este cenário. Ao invés de imprimir somente o ID de um funcionário,
vamos imprimir também seu nome.

CLASS lcl_employee DEFINITION. 
  PUBLIC SECTION. 
 
    TYPES ty_pernr TYPE pa0002​
­​
pernr. 
 
    DATA​
:​
 pernr     TYPE ty_pernr, 
          wa_pa0002 TYPE pa0002. 
 
    METHODS constructor 
      IMPORTING 
        i_personal_number TYPE ty_pernr. 
 
    METHODS load_personal_data. 
 
    METHODS write_personal_data. 
 
ENDCLASS. 
 
CLASS lcl_employee IMPLEMENTATION. 
 
  METHOD constructor. 
    me​
­>​
pernr ​
=​
 i_personal_number. 
 
    me​
­>​
load_personal_data​
(​
 ​
).​
 ​
"​
 chamada usando ​
auto​
­​
refer​
ê​
ncia 
 
  ENDMETHOD. 
 
  METHOD load_personal_data. 
 
    SELECT ​
*​
 UP TO ​
1​
 ROWS 

51
Orientação a Objetos em ABAP
Cópia de Marcos

      FROM pa0002 
      INTO me​
­>​
wa_pa0002 ​
"​
 escrevendo na ​
auto​
­​
refer​
ê​
ncia 
      WHERE 
        pernr ​
=​
 me​
­>​
pernr ​
"​
 lendo a ​
auto​
­​
refer​
ê​
ncia 
      ORDER BY endda DESCENDING. 
 
    ENDSELECT. 
 
  ENDMETHOD. 
 
  METHOD write_personal_data. 
    ​
"​
 ​
Leitura​
 dos atributos para impressao usando ​
auto​
­​
refer​
ê​
ncia 
    WRITE​
:​
 ​
/​
 ​
|​
 ​
{​
 me​
­>​
wa_pa0002​
­​
pernr ​
}​
 ​
­​
 ​
{​
 me​
­>​
wa_pa0002​
­​
cname ​
}​
 ​
|​
 . 
  ENDMETHOD. 
 
ENDCLASS. 
 
DATA​
:​
 r_employee_1 TYPE REF TO lcl_employee, 
      r_employee_2 TYPE REF TO lcl_employee, 
      r_employee_3 TYPE REF TO lcl_employee. 
 
START​
­​
OF​
­​
SELECTION. 
 
  CREATE OBJECT r_employee_1 
    EXPORTING 
      i_personal_number ​
=​
 ​
'50000000'. 
 
  r_employee_2 ​
=​
 NEW lcl_employee​
(​
 i_personal_number ​
=​
 ​
'50000002'​
 ​
). 
 
  r_employee_3 ​
=​
 NEW lcl_employee​
(​
 ​
'50000003'​
 ​
). 
 
  ​
" Impressao 
  r_employee_1​
­>​
write_personal_data​
(​
 ​
). 
 
  CALL METHOD r_employee_2​
­>​
write_personal_data. 
 
  r_employee_3​
­>​
write_personal_data​
(​
 ​
).
Auto‐referência sendo usada para leitura e escrita de atributos, além de
ser usada para chamado de método da mesma classe.

Note acima quantas vezes usamos a auto‐referência. Isso faz com que
nossa classe seja totalmente independente das referências declaradas a

52
Orientação a Objetos em ABAP
Cópia de Marcos

ela. Em outras palavras, apesar de não usarmos as referências


r_employee dentro dos blocos CLASS...ENDCLASS, podemos manipular os
objetos sendo apontados por elas de uma maneira única e independente.

4.3 Sessões de visibilidade


Até então usamos o comando PUBLIC SECTION dentro dos blocos de
definição de classe. Isso pois quando há pelo menos alguma definição
dentro de uma classe, é obrigatório especificar em qual ​ sessão de
visibilidade​
ela se encontra.

As sessões de visibilidade nos permitem controlar em quais lugares algum


método por ser chamado ou onde algum atributo pode ser acessado
(independente se seja para uma operação de leitura ou escrita).

Existem três sessões de visibilidade possíveis: PUBLIC, PROTECTED e


PRIVATE.

Por hora, vamos entender as sessões PUBLIC e PRIVATE uma vez que a
PROTECTED só faz sentido nos casos que há aplicação de herança, tema
que ainda será abordado.

Dentro de uma sessão pode haver um número qualquer de tipos,


constantes, atributos e definições de métodos e ainda uma mistura
destes. As sessões ainda somente são especificadas no bloco de definição
de classe.

4.3.1 PUBLIC SECTION


Atributos e métodos declarados abaixo da ​sessão pública podem ser
usados em qualquer ponto de uma aplicação. Vamos mudar um pouco a

53
Orientação a Objetos em ABAP
Cópia de Marcos

nossa classe lcl_employee para perceber o que a sessão pública nos


permite fazer.

CLASS lcl_employee DEFINITION. 
  PUBLIC SECTION. 
 
    TYPES ty_pernr TYPE pa0002​
­​
pernr. 
 
    DATA​
:​
 pernr     TYPE ty_pernr, 
          wa_pa0002 TYPE pa0002. 
 
    METHODS load_personal_data. 
 
    METHODS write_personal_data. 
 
ENDCLASS. 
 
CLASS lcl_employee IMPLEMENTATION. 
 
 
  METHOD load_personal_data. 
 
    SELECT ​
*​
 UP TO ​
1​
 ROWS 
      FROM pa0002 
      INTO me​
­>​
wa_pa0002 
      WHERE 
        pernr ​
=​
 me​
­>​
pernr 
      ORDER BY endda DESCENDING. 
 
    ENDSELECT. 
 
  ENDMETHOD. 
 
  METHOD write_personal_data. 
    WRITE​
:​
 ​
/​
 ​
|​
 ​
{​
 me​
­>​
wa_pa0002​
­​
pernr ​
}​
 ​
­​
 ​
{​
 me​
­>​
wa_pa0002​
­​
cname ​
}​
 ​
|​
 . 
  ENDMETHOD. 
 
ENDCLASS. 
 
DATA​
:​
 r_employee_1 TYPE REF TO lcl_employee, 
      r_employee_2 TYPE REF TO lcl_employee, 
      r_employee_3 TYPE REF TO lcl_employee. 
 

54
Orientação a Objetos em ABAP
Cópia de Marcos

START​
­​
OF​
­​
SELECTION. 
 
  CREATE OBJECT r_employee_1. 
  r_employee_1​
­>​
pernr ​
=​
 ​
'50000000'. 
 
  r_employee_2 ​
=​
 NEW lcl_employee​
(​
  ​
). 
  r_employee_2​
­>​
pernr ​
=​
  ​
'50000002'. 
 
  r_employee_3 ​
=​
 NEW lcl_employee​
(​
  ​
). 
  r_employee_3​
­>​
pernr ​
=​
 ​
'50000003'. 
 
*​
 ​
Carrega​
 dados ​
do​
 empregado 
  r_employee_1​
­>​
load_personal_data​
(​
 ​
). 
  r_employee_2​
­>​
load_personal_data​
(​
 ​
). 
  r_employee_3​
­>​
load_personal_data​
(​
 ​
). 
 
 
*​
 ​
Impressao 
  r_employee_1​
­>​
write_personal_data​
(​
 ​
). 
  CALL METHOD r_employee_2​
­>​
write_personal_data. 
  WRITE​
:​
 ​
/​
 ​
|​
 ​
{​
 r_employee_3​
­>​
wa_pa0002​
­​
pernr ​
}​
 ​
­​
 ​

r_employee_3​
­>​
wa_pa0002​
­​
cname ​
}​
 ​
|​
 . 

Uso de atributos e métodos públicos

Primeiramente, não considere o exemplo acima um código orientado a


objetos com qualidade. Ele poderia estar bem melhor escrito usando mais
de uma sessão de visibilidade. Porém, ele é um bom exemplo de o que a
sessão pública nos permite fazer.

Todas as definições na classe acima são públicas. Isso basicamente


permite que usemos elas fora do bloco CLASS IMPLEMENTATION …
pernr ​
ENDCLASS. Note que os atributo ​ e​
wa_pa0002 foram usados dentro
do evento START‐OF‐SELECTION (que está fora da classe). Ainda, os
métodos ​
load_personal_data e ​
write_personal_data também puderam ser
chamados fora do bloco de implementação da classe.

➔ O que poderia melhorar no código acima?

55
Orientação a Objetos em ABAP
Cópia de Marcos

Antes, as nossas definições já eram públicas, mas simplesmente não


usávamos todas elas. Agora, usamos. O construtor foi removido no
exemplo acima justamente para dar a ideia de que ele não é preciso
tecnicamente deste para preencher o atributo ​
pernr. Todavia, para que a
impressão dos dados pessoais funcione, é preciso antes carregar
explicitamente os dados do empregado usando o método
load_personal_data​. Da mesma forma, o método ​ load_personal_data só
irá funcionar caso o atributo ​ pernr esteja carregado. E por último,
precisamos preencher o atributo ​ pernr obrigatoriamente depois da
criação do objeto para evitar um DUMP (lembre‐se que não se pode tocar
usar referências que não estejam apontando para algum objeto).

constructor​
Nota: O método construtor de instância (​ )​
deve sempre ser
público caso usado.

Tivemos portanto que respeitar um sequenciamento lógico para que tudo


funcionasse de acordo. Quando possuíamos o construtor no nosso código,
o preenchimento e carregamento das informações do empregado se dava
automaticamente quando o objeto era instanciado (criado). Isso fazia
com que tivéssemos que nos preocupar menos em chamar o método
corrego no momento correto.

4.3.2 PRIVATE SECTION

Esta nossa versão da classe lcl_employee não ​ encapsula os dados dos


objetos, o que é considerada uma má prática. Se comparado ao modelo
procedural, esta versão orientada a objetos é mais perigosa pois consegue
modificar qualquer atributo de um objeto a qualquer momento. No
mundo procedural, há um encapsulamento automático dentro das
variáveis que são declaradas dentro do TOP include do grupo de função.

56
Orientação a Objetos em ABAP
Cópia de Marcos

Elas não podem ser usadas em outros pontos de código que não sejam os
módulos de função do mesmo grupo.

Para impedir que algum atributo seja acessado ou algum método seja
chamado em qualquer ponto da aplicação, é preciso defini‐lo como
não‐público (PROTECTED ou PRIVATE). No momento, focaremos na ​
sessão
private​
(PRIVATE SECTION).

Vamos adequar nossa classe lcl_employee para fazer uso da sessão


privada.

CLASS lcl_employee DEFINITION. 
  PUBLIC SECTION. 
 
    TYPES ty_pernr TYPE pa0002​
­​
pernr. 
 
    METHODS constructor 
      IMPORTING 
        i_personal_number TYPE ty_pernr. 
 
    METHODS write_personal_data. 
 
  PRIVATE SECTION. 
 
    DATA​
:​
 pernr     TYPE ty_pernr, 
          wa_pa0002 TYPE pa0002. 
 
    METHODS load_personal_data. 
 
ENDCLASS. 
 
CLASS lcl_employee IMPLEMENTATION. 
 
  METHOD constructor. 
    me​
­>​
pernr ​
=​
 i_personal_number. 
 
*​
    ​
Chamada​
 de m​
é​
todo privado. 
*​
     ​
Como​
 estamos dentro ​
do​
 bloco de implementa​
ção 
*​
     isso ​
é​
 permitido 
    me​
­>​
load_personal_data​
(​
 ​
). 

57
Orientação a Objetos em ABAP
Cópia de Marcos

 
  ENDMETHOD. 
 
  METHOD load_personal_data. 
 
    SELECT ​
*​
 UP TO ​
1​
 ROWS 
      FROM pa0002 
      INTO me​
­>​
wa_pa0002 
      WHERE 
        pernr ​
=​
 me​
­>​
pernr 
      ORDER BY endda DESCENDING. 
 
    ENDSELECT. 
 
  ENDMETHOD. 
 
  METHOD write_personal_data. 
    WRITE​
:​
 ​
/​
 ​
|​
 ​
{​
 me​
­>​
wa_pa0002​
­​
pernr ​
}​
 ​
­​
 ​
{​
 me​
­>​
wa_pa0002​
­​
cname ​
}​
 ​
|​
 . 
  ENDMETHOD. 
 
ENDCLASS. 
 
DATA​
:​
 r_employee_1 TYPE REF TO lcl_employee, 
      r_employee_2 TYPE REF TO lcl_employee, 
      r_employee_3 TYPE REF TO lcl_employee. 
 
START​
­​
OF​
­​
SELECTION. 
 
  CREATE OBJECT r_employee_1 
    EXPORTING 
      i_personal_number ​
=​
 ​
'50000000'. 
 
*​
 ​
Erro​
 de sintaxe ​
­​
 atributo privado 
*​
r_employee_1​
­>​
permr ​
=​
 ​
'50000000'. 
 
  r_employee_2 ​
=​
 NEW lcl_employee​
(​
 i_personal_number ​
=​
 ​
'50000002'​
 ​
). 
  r_employee_3 ​
=​
 NEW lcl_employee​
(​
 ​
'50000003'​
 ​
). 
 
*​
 ​
Erro​
 de sintaxe ​
­​
 metodo privado 
*​
 r_employee_1​
­>​
load_personal_data​
(​
 ​
). 
 
  ​
" Impressao 
  r_employee_1​
­>​
write_personal_data​
(​
 ​
). 
  CALL METHOD r_employee_2​
­>​
write_personal_data. 

58
Orientação a Objetos em ABAP
Cópia de Marcos

  r_employee_3​
­>​
write_personal_data​
(​
 ​
). 

Refatoramento de código para usar sessão privada. Chamadas que geram


erro de sintaxe foram comentadas.

No exemplo acima, damos menos liberdade no que tange o uso da classe


lcl_employee, o que é bom. Podemos basicamente fazer duas ações sobre
esta classe:
➔ Criar objetos ‐ o que chama o método construtor. Para criar um
objeto é preciso informar um número de empregado
➔ Imprimir informações ‐ através da chamada do método público
write_personal_data

A chamada do método ​ load_personal_data volta a acontece dentro do


construtor da classe. A diferença agora é que a chamada explícita deste
método é proibida, gerando um erro de ativação caso seja feita fora do
bloco de implementação da classe.

Dependendo da aplicação, poderíamos ainda tornar o método


write_personal_data privado e chamá‐lo no fim do construtor. Neste
caso, bastaria criar o objeto empregado para que as informações do
mesmo fossem carregadas e impressas.

➔ Qual a vantagem de impedir o uso a um atributo ou método?

Dar menos liberdade a quem usa a classe tende a ser uma boa prática:
com menos opções de uso as chances de usar uma classe de maneira
errada diminuem.

Ainda, classes bem construídas tendem a evitar que objetos tenham


estados “inválidos”. Quando todos os atributos da classe lcl_employee
eram públicos, era possível preencher os dados do empregado (atributo

59
Orientação a Objetos em ABAP
Cópia de Marcos

wa_pa0002​ ) sem antes ter preenchido o número do empregado ‐ o que


não faz sentido. Atributos e métodos definidos como privados se bem
usados evitam que objetos tenham valores que não fazem sentidos e que
chamadas desnecessárias sejam feitas.

4.4 Atributos e Métodos de Instância vs


Estáticos
Um tema que costuma gerar confusão para muita gente é a diferença de
instância​
atributos e métodos de ​ estáticos​
com atributos e métodos ​ .

constructor​
Já vimos que existem construtores: o de instância (​ ) e o de
class_constructor​
classe (​ ).

O construtor de instância é chamado quando se cria instâncias (objetos),


enquanto o estático é chamado quando se usa a classe pela primeira vez.

Porém não é somente o construtor que pode ser de instância ou estático.


Atributos e outros métodos também podem pertencer a objetos ​ ou a
classes.

A mesma regra expressa anteriormente ainda se aplica: tudo que se


refere a classes é declarado com um comando começando em CLASS‐.

4.4.1 Atributos de instância


Atributos de instância são declarados usando o comando DATA dentro do
bloco de definição da classe. Cada atributo de instância declara uma
variável independente para cada um os objetos criados.

Os atributos declarados até então foram todos de instância, como


acontecia na classe lcl_ordem_de_venda.

60
Orientação a Objetos em ABAP
Cópia de Marcos

Objetos e seus atributos de instância

4.4.2 Atributos estáticos


Atributos estáticos comumente são ditos como ​ pertencentes a classes.
Estes atributos podem ser usados independente de haver objetos criados,
como abaixo.

Veja o código abaixo. Criamos uma nova classe responsável por selecionar
textos (descrições) de materiais. Cada objeto representa um material
distinto, o que é razoável supondo que tal apliacação não faz seleção em
massa de materiais.

CLASS lcl_material_texts DEFINITION. 
  PUBLIC SECTION. 
    CLASS​
­​
DATA​
:​
 language TYPE makt​
­​
spras. 
 
    CLASS​
­​
METHODS class_constructor. 
 
ENDCLASS. 
 

61
Orientação a Objetos em ABAP
Cópia de Marcos

CLASS lcl_material_texts IMPLEMENTATION. 
 
  METHOD class_constructor. 
    lcl_material_texts​
=>​
language ​
=​
 ​
'P'. 
  ENDMETHOD. 
 
ENDCLASS. 
 
START​
­​
OF​
­​
SELECTION. 
 
WRITE​
:​
 lcl_material_texts​
=>​
language. 
 
lcl_material_texts​
=>​
language ​
=​
 ​
'E'. 
 
WRITE​
:​
 lcl_material_texts​
=>​
language.
Atributo estático em uso

No código acima, usamos um atributo sem ao menos ter criado um único


objeto. Isso só é possível pois tal atributo é estático. Como tal atributo
está abaixo da sessão pública, podemos usá‐lo para leitura e escrita fora
da classe, como acontece no evento START‐OF‐SELECTION.

➔ Um atributo estático é uma constante?


Absolutamente não. Esta é a grande confusão gerada neste assunto. Uma
constante é um objeto de dados ​imutável​
, enquanto um atributo estático
pode ter seu valor alterado normalmente, como é feito no código acima.

Você terá razão em achar que o termo ​estático é então confuso, mas isso
não anula o fato de ser importante entendê‐lo.

O construtor de classe foi criado para atribuir um valor inicial para nosso
atributo estático. Contúdo, podemos alterar tal valor posteriormente.
Dentro do construtor estático a auto‐referência ​ me não existe pois não
temos um objeto sendo criado.

62
Orientação a Objetos em ABAP
Cópia de Marcos

Note que para acessar atributos estáticos usamos uma “seta” ( => ) um
pouco diferente da que estávamos acostumados. Ainda, o termo a
esquerda da seta não é uma referência mas sim o próprio nome da classe.
Assim, além de não precisarmos criar um objeto, não precisamos também
declarar uma referência para fazer uso de atributos estáticos.

Vamos incrementar nosso modelo usando vários conceitos já abordados,


além de criar alguns objetos e trabalhar com eles.

CLASS lcl_material_texts DEFINITION. 
  PUBLIC SECTION. 
 
    TYPES​
:​
 ty_material_id   TYPE makt​
­​
matnr, 
           ty_material_text TYPE makt​
­​
maktx, 
           ty_language      TYPE makt​
­​
spras. 
 
    CLASS​
­​
DATA​
:​
 language TYPE ty_language. 
 
    CLASS​
­​
METHODS class_constructor. 
 
    METHODS constructor 
      IMPORTING 
        i_matnr TYPE lcl_material_texts​
=>​
ty_material_id. 
 
    METHODS select_text 
      RETURNING VALUE​
(​
re_material_text​
)  
        TYPE lcl_material_texts​
=>​
ty_material_text. 
 
  PRIVATE SECTION. 
 
    DATA​
:​
 matnr TYPE ty_material_id​
,​
 ​
"lcl_material_texts=> é opcional 
          material_text TYPE lcl_material_texts​
=>​
ty_material_text, 
          selected_language TYPE ty_language​

ENDCLASS. 
 
CLASS lcl_material_texts IMPLEMENTATION. 
 
  METHOD class_constructor. 
    lcl_material_texts​
=>​
language ​
=​
 ​
'P'. 
  ENDMETHOD. 
 

63
Orientação a Objetos em ABAP
Cópia de Marcos

  METHOD constructor. 
    matnr ​
=​
 i_matnr​
.​
 ​
" me­> é opcional 
 
    me​
­>​
material_text ​
=​
 me​
­>​
select_text​
(​
 ​
). 
 
  ENDMETHOD. 
 
  METHOD select_text. 
 
    IF me​
­>​
material_text IS INITIAL OR 
      lcl_material_texts​
=>​
language ​
<>​
 me​
­>​
selected_language. 
 
      SELECT SINGLE 
        maktx 
        FROM makt 
        INTO re_material_text 
        WHERE 
          matnr ​
=​
 matnr ​
" me­> opcional 
        AND spras ​
=​
 lcl_material_texts​
=>​
language. 
 
      IF sy​
­​
subrc IS INITIAL. 
        me​
­>​
selected_language ​
=​
 lcl_material_texts​
=>​
language. 
        me​
­>​
material_text ​
=​
 re_material_text. 
      ENDIF. 
 
    ENDIF. 
 
    re_material_text ​
=​
 me​
­>​
material_text. 
 
  ENDMETHOD. 
 
ENDCLASS. 
 
DATA​
:​
 r_material_a TYPE REF TO lcl_material_texts, 
      r_material_b TYPE REF TO lcl_material_texts. 
 
START​
­​
OF​
­​
SELECTION. 
 
  WRITE​
:​
 ​
|​
Textos​
 em ​
{​
 lcl_material_texts​
=>​
language ​
}|. 
 
  r_material_a ​
=​
 NEW lcl_material_texts​
(​
 ​
'R­F130'​
 ​
). 
 
  r_material_b ​
=​
 NEW lcl_material_texts​
(​
 ​
'R­T300'​
 ​
). 
 

64
Orientação a Objetos em ABAP
Cópia de Marcos

  WRITE​
:​
 / 
  r_material_a​
­>​
select_text​
(​
 ​
),​
 ​
/, 
  r_material_b​
­>​
select_text​
(​
 ​
),​
 ​
/, 
  NEW lcl_material_texts​
(​
 ​
'MM­FUSIVEL­30'​
 ​
)­>​
select_text​
(​
 ​
). 
 
  lcl_material_texts​
=>​
language ​
=​
 ​
'E'. 
  ULINE. 
 
  WRITE​
:​
 / 
  r_material_a​
­>​
select_text​
(​
 ​
),​
 ​
/, 
  r_material_b​
­>​
select_text​
(​
 ​
).
Exemplo com atributos de instância e estáticos

Pode parecer muito código para resolver um problema pequeno (e é),


mas é interessante notar características deste modelo.

Primeiro, vamos diferenciar graficamente os atributos de instância


(declarados usando DATA) e o nosso único atributo estático (declarado
usando CLASS‐DATA).

65
Orientação a Objetos em ABAP
Cópia de Marcos

Representação de atributos de instância e estático

Cada objeto possui guarda em seus atributos o código de um material, o


sua descrição e o idioma em que tal descrição foi selecionada
(selected_language).

Ainda, todos os objetos compartilham de um atributo chamado ​ language


que guarda o idioma no qual as descrições serão buscadas, independente
do objeto. Poderíamos então criar 10 objetos e seus textos em português,
na sequência alterar o atributo estático para outro idioma e selecionar
textos de outros 15 objetos. A vantagem deste é que não é preciso repetir
o idioma a ser usado para a seleção dos textos para cada objeto.

Mais importante ainda, é o fato do atributo privado poder ser usado


através da classe, como em:

lcl_material_texts​
=>​
language ​
=​
 ​
'E'.

… bem como utilizá‐lo através de referências a objetos, como em:

me​
­>​
selected_language ​
=​
 lcl_material_texts​
=>​
language.

Logo, cuidado com a definição de atributos estáticos que diz ser ​


atributos
que pertencem a classe pois isso não anula o fato de tais atributos
pertencerem (de maneira compartilhada porém) aos objetos também.

Resumidamente, atributos estáticos são aqueles que não precisam de


objetos para serem usados, mas que caso sejam criados compartilham do
mesmo valor. O valor de atributos estáticos podem ser alterados pela
classe ou por objetos, a diferença é que tal alteração reflete em todas as
instâncias da classe pois na verdade, existe apenas uma variável
compartilhada por todos os objetos.

66
Orientação a Objetos em ABAP
Cópia de Marcos

4.4.3 Métodos de instância


Havendo entendido a diferença entre atributos de instância e estáticos,
fica bem simples entender a diferença entre métodos de instância e
estáticos também.

Métodos de instância são declarados usando o comando METHODS no


bloco de definição de classe e implementados usando o bloco METHOD …
ENDMETHOD no bloco de implementação.

Tais métodos podem somente ser invocados usando a referência a um


objeto. Como de costume, tal referência não poderá estar vazia pois isso
ocasiona um erro de execução (DUMP).

Métodos de instância podem usar a auto‐referência (me) para ler e


alterar atributos do objeto sendo invocado, bem como ser utilizado para
a chamada de outros métodos pertencentes ao mesmo objeto.

É importante destacar que dentro de métodos de instância também é


possível ler e alterar atributos estáticos, bem como invocar métodos
estáticos.

4.4.4 Métodos estáticos


A declaração de métodos estáticos segue a mesma regra do construtor de
class_constructor​
classe (​ ): usa‐se o comando CLASS‐METHODS no bloco de
definição da classe e o bloco METHOD… ENDMETHOD dentro do bloco de
implementação da classe.

Cuidado! O termo CLASS‐ não é usado no bloco de implementação!

67
Orientação a Objetos em ABAP
Cópia de Marcos

Métodos estáticos não necessitam de instâncias criadas para serem


executados. Todavia, instâncias também podem fazer uso destes.

Como tais métodos de fato não pertencem a somente um objeto, a


auto‐referência ​
me não pode ser usada dentro de métodos estáticos,
mesmo que estes tenham sido invocados através de uma referência de
objeto.

4.5 Herança

É comum termos a possibilidade de reutilizar um trecho de código, seja


tal reuso válido dentro da aplicação ou feito em vários programas
distintos.

Também é frequente termos a necessidade de adaptar alguns pequenos


detalhes além de ser fazer reuso de um trecho de código.

A​herança é uma maneira que a orientação a objetos provê de reutilizar


código entre classes que são semelhantes.

Acompanhe o seguinte exemplo. No módulo de SD, temos vários tipos de


documentos diferentes. Dois documentos bem famosos são a cotação e a
ordem de venda.

Ambos documentos possui muito em comum: cabeçalho, itens, preços,


quantias. O cabeçalho destes dois tipos de documentos são armazenados
na mesma tabela: VBAK.

Uma das diferenças técnicas destes documentos é a transação usada para


exibir tal documento. Para exibir cotações usa‐se a transação VA23

68
Orientação a Objetos em ABAP
Cópia de Marcos

enquanto para exibição de ordens de venda a tão conhecida VA03 é


utilizada.

Vamos escrever uma aplicação que seleciona uma cotação ou ordem de


venda para posterior exibição. Como ambos documentos tem muito em
comum, usaremos a herança para poder reutilizar boa parte do código.

REPORT zoo_heranca. 
 
CLASS lcl_documento_de_venda DEFINITION. 
  PUBLIC SECTION. 
 
    TYPES: 
      ty_id     TYPE vbak​
­​
vbeln, 
      ty_header TYPE vbak. 
 
    METHODS constructor 
      IMPORTING 
        i_id TYPE ty_id. 
 
    METHODS abrir . 
 
    DATA header TYPE ty_header. 
 
  PRIVATE SECTION. 
 
    METHODS select_header 
      RETURNING VALUE​
(​
re_header​
)​
 TYPE ty_header. 
 
ENDCLASS. 
 
 
CLASS lcl_documento_de_venda IMPLEMENTATION. 
 
  METHOD constructor. 
    me​
­>​
header​
­​
vbeln ​
=​
 i_id. 
    me​
­>​
header ​
=​
 me​
­>​
select_header​
(​
 ​
). 
  ENDMETHOD. 
 
  METHOD select_header. 

69
Orientação a Objetos em ABAP
Cópia de Marcos

 
    SELECT SINGLE * 
      FROM vbak 
      INTO re_header 
      WHERE 
        vbeln ​
=​
 me​
­>​
header​
­​
vbeln. 
 
  ENDMETHOD. 
 
  METHOD abrir. 
    SET PARAMETER ID ​
'AUN'​
 FIELD header​
­​
vbeln. 
  ENDMETHOD. 
 
 
ENDCLASS. 
 
CLASS lcl_cotacao DEFINITION 
    INHERITING FROM lcl_documento_de_venda. 
 
PUBLIC SECTION. 
  METHODS abrir REDEFINITION. 
 
ENDCLASS. 
 
CLASS lcl_cotacao IMPLEMENTATION. 
 
  METHOD abrir. 
    ​
super​
­>​
abrir​
(​
 ​
). 
    call TRANSACTION ​
'VA23'​
 AND SKIP FIRST SCREEN. 
  ENDMETHOD. 
 
ENDCLASS. 
 
 
CLASS lcl_ordem_de_venda DEFINITION 
    INHERITING FROM lcl_documento_de_venda. 
 
PUBLIC SECTION. 
  METHODS abrir REDEFINITION. 
 
ENDCLASS. 
 
CLASS lcl_ordem_de_venda IMPLEMENTATION. 
 

70
Orientação a Objetos em ABAP
Cópia de Marcos

  METHOD abrir. 
    ​
super​
­>​
abrir​
(​
 ​
). 
    call TRANSACTION ​
'VA03'​
 AND SKIP FIRST SCREEN. 
  ENDMETHOD. 
 
ENDCLASS. 
 
 
 
START​
­​
OF​
­​
SELECTION. 
 
DATA​
:​
 r_cotacao TYPE REF TO lcl_cotacao. 
 
create OBJECT r_cotacao 
  EXPORTING 
    i_id ​
=​
 ​
'0020000162'. 
 
r_cotacao​
­>​
abrir​
(​
 ​
). 
 
 
new​
 lcl_ordem_de_venda​
(​
 i_id ​
=​
 ​
'0000016197'​
 ​
)­>​
abrir​
(​
 ​
). 

Aplicação de herança

No exemplo acima, temos três classes:


➔ A nossa classe “mãe” ​ lcl_documento_de_venda,​que possui código a
ser reutilizado pois é comum a ambos os documentos.
➔ A classe “filha” ​ lcl_cotacao​, que exibe uma cotação na transação
VA23
➔ A classe “filha” ​ lcl_ordem_de_venda​ , que exibe uma venda na
transação VA03

herdados ​
Todos os atributos e métodos públicos são ​ para as classes filhas.
Isso significa que o método ​
select_header pode apenas ser chamado na
nossa classe mãe.

Para tornar uma classe filha de outra é necessário adicionar a variação


INHERITING FROM na definição da classe filha. Não há limite para o

71
Orientação a Objetos em ABAP
Cópia de Marcos

número de classes filhas que uma classe pode ter. Ainda, uma classe pode
apenas ter uma e somente mãe.

Pode‐se no exemplo reutilizar o método ​ abrir da classe mãe, que


simplesmente preenche o ID de parâmetro necessário para abrir qualquer
um dos dois documentos de venda.

4.5.1 Sessão protegida

Agora que você já sabe a proposta da herança, é um momento oportuno


para aprender a terceira e última sessão de visibilidade disponível: a
sessão protegida​
. Esta só se faz necessário e útil quando há herança na
sua aplicação.

Atributos e métodos protegidos não podem ser usados fora do bloco de


implementação da classe. Porém, estes são herdados para a classes
filhas, netas, etc... Logo, caso coloquemos nosso método ​select_header
na sessão protegida, este poderá ser chamado dentro das classes filhas.

Vamos adaptar um pouco o exemplo. As classes poderão adiar a seleção


do cabeçalho do documento bem como exibir informações adicionais
antes da exibição do documento em si.

Em especial, a classe de cotação mostrará o tipo do documento enquanto


a classe de ordem de venda será capaz de mostrar a sua quantidade de
iten.

CLASS lcl_documento_de_venda DEFINITION. 
  PUBLIC SECTION. 
 
    TYPES: 
      ty_id     TYPE vbak​
­​
vbeln, 

72
Orientação a Objetos em ABAP
Cópia de Marcos

      ty_header TYPE vbak. 
 
    METHODS constructor 
      IMPORTING 
        i_id TYPE ty_id. 
 
    METHODS abrir . 
 
    DATA header TYPE ty_header. 
 
  PROTECTED SECTION​
.​
 ​
" Protegida! 
 
    METHODS select_header ​
" método será herdado 
      RETURNING VALUE​
(​
re_header​
)​
 TYPE ty_header. 
 
  PRIVATE SECTION. 
 
ENDCLASS. 
 
CLASS lcl_documento_de_venda IMPLEMENTATION. 
 
  METHOD constructor. 
    me​
­>​
header​
­​
vbeln ​
=​
 i_id. 
  ENDMETHOD. 
 
  METHOD select_header. 
 
    SELECT SINGLE * 
      FROM vbak 
      INTO re_header 
      WHERE 
        vbeln ​
=​
 me​
­>​
header​
­​
vbeln. 
 
  ENDMETHOD. 
 
  METHOD abrir. 
    SET PARAMETER ID ​
'AUN'​
 FIELD header​
­​
vbeln. 
  ENDMETHOD. 
 
ENDCLASS. 
 
CLASS lcl_cotacao DEFINITION 
    INHERITING FROM lcl_documento_de_venda. 
 

73
Orientação a Objetos em ABAP
Cópia de Marcos

  PUBLIC SECTION. 
    METHODS abrir REDEFINITION. 
 
ENDCLASS. 
 
CLASS lcl_cotacao IMPLEMENTATION. 
 
  METHOD abrir. 
    me​
­>​
header ​
=​
 me​
­>​
select_header​
(​
 ​
). 
    MESSAGE ​
|​
Cota​
çã​
o ​
do​
 tipo ​
{​
 me​
­>​
header​
­​
auart ​
}​
 ​
|​
 TYPE ​
'I'. 
 
    ​
super​
­>​
abrir​
(​
 ​
). 
   
    CALL TRANSACTION ​
'VA23'​
 AND SKIP FIRST SCREEN. 
   
  ENDMETHOD. 
 
ENDCLASS. 
 
 
CLASS lcl_ordem_de_venda DEFINITION 
    INHERITING FROM lcl_documento_de_venda. 
 
  PUBLIC SECTION. 
    TYPES​
:​
 ty_items TYPE TABLE OF vbap. 
 
    DATA t_items TYPE ty_items READ​
­​
ONLY. 
 
    METHODS constructor 
      IMPORTING 
          i_id_venda TYPE lcl_documento_de_venda​
=>​
ty_id. 
    METHODS abrir REDEFINITION. 
  PRIVATE SECTION. 
 
    METHODS select_items. 
ENDCLASS. 
 
 
CLASS lcl_ordem_de_venda IMPLEMENTATION. 
  
  METHOD constructor. 
    ​
super​
­>​
constructor​
(​
 i_id ​
=​
 i_id_venda ​
). 
    me​
­>​
select_items​
(​
 ​
). 
  ENDMETHOD. 

74
Orientação a Objetos em ABAP
Cópia de Marcos

 
  METHOD abrir. 
    DATA no_linhas TYPE i. 
   
    ​
super​
­>​
abrir​
(​
 ​
). 
 
    DESCRIBE TABLE me​
­>​
t_items LINES no_linhas. 
    MESSAGE ​
|​
Ordem​
 possui ​
{​
 no_linhas ​
}​
 itens ​
|​
 TYPE ​
'I'. 
   
    CALL TRANSACTION ​
'VA03'​
 AND SKIP FIRST SCREEN. 
   
  ENDMETHOD. 
 
  METHOD select_items. 
    SELECT * 
      FROM vbap 
      INTO TABLE me​
­>​
t_items 
      WHERE 
      vbeln ​
=​
 me​
­>​
header​
­​
vbeln. 
  ENDMETHOD. 
 
ENDCLASS. 
 
 
 
START​
­​
OF​
­​
SELECTION. 
 
  DATA​
:​
 r_cotacao TYPE REF TO lcl_cotacao. 
 
  CREATE OBJECT r_cotacao 
    EXPORTING 
      i_id ​
=​
 ​
'0020000162'. 
 
  r_cotacao​
­>​
abrir​
(​
 ​
). 
 
  NEW lcl_ordem_de_venda​
(​
 i_id_venda ​
=​
 ​
'0000016197'​
 ​
)­>​
abrir​
(​
 ​
).

Sessão protegida ‐ Método select_header é herdado para classes filhas

No exemplo acima, também redefinimos o construtor da classe


lcl_ordem_de_venda​
. Apesar de ser possível realizar tal feito, é

75
Orientação a Objetos em ABAP
Cópia de Marcos

necessário destacar que para redefinição construtores, duas excessões se


aplicam:
➔ Não se pode usar a adição REDEFINITION ‐ basta declarar o
construtor novamente.
➔ A chamada do construtor da classe mãe (​ super‐>constructor​
) é
obrigatória.

Em outros métodos que são herdados, a chamada usando a palavra


reservada ​super é opcional. Ela se refere a implementação na classe mãe
e pode ser útil quando o código existente na classe mãe precisa ser
reutilizado, acompanhado por alguma diferença implementada na classe
filha.

Nem todos os métodos precisam ser redefinidos. Os métodos que não são
redefinidos existem na classe filha (desde que públicos ou protegidos)
com a mesma implementação.

4.6 Eventos
Com evento, é possível realizar a comunicação entre dois objetos de uma
maneira mais sofisticada que simplemente chamar um método de um
objeto dentro de outro objeto. Isso pois é possível que um objeto
“dispare” um evento e automaticamente vários outros objetos reajam a
este.

Este conceito é muito útil quando em algum ponto da aplicação, vários


procedimentos, checagens, contas, validações precisam ser feitas de
maneira independente uma das outras.

Ao trabalhar com eventos, sempre haverá 4 passos que obrigatoriamente


irão ser realizados.

76
Orientação a Objetos em ABAP
Cópia de Marcos

➔ 1 ‐ Criação do evento

Um evento é criado no bloco de definição da classe que possuirá o


evento. Tal procedimento é realizado usando o comando EVENTS

CLASS lcl_documentos_fi DEFINITION. 
 
  PUBLIC SECTION. 
    EVENTS​
:​
 documentos_selecionados. 
 
(...) 

➔ 2 ‐ Disparo do evento

O disparo do evento deve ser feito pelo mesmo objeto que possui o
evento. Isto é feito através do comando RAISE EVENT.

 METHOD select_documents. 
 
(...) 
 
    RAISE EVENT documentos_selecionados. 
 
(...) 
 
  ENDMETHOD. 

Assim que um evento é disparado, um conjunto de objetos (até de outras


classes) podem reagir a tal ocorrência. Os passos 3 e 4 devem ser feitos
para cada uma das classes que poderão reagir a evento definido e
disparado nos passos 1 e 2.

➔ 3 ‐ Definição do método a ser automatizado

77
Orientação a Objetos em ABAP
Cópia de Marcos

A maneira a qual um objeto reage a algum evento é através da chamada


automática de pelo menos um de seus métodos. A definição do método
carrega a informação se este seja chamado automaticamente na
ocorrência de um evento que deve ser especificado explicitamente.

METHODS captura_documentos 
    FOR EVENT documentos_selecionados OF lcl_documentos_fi

➔ 4 ‐ Marcação de objetos que serão “escutados”

No quarto e último passo, é necessário especificar quais instancias da


classe que dispara o evento serão “escutadas”, sendo possível especificar
todas as instâncias. Este passo é realizado usando o comando SET
HANDLER. Note que neste passo é especificado o método utilizado no
passo 3.

START​
­​
OF​
­​
SELECTION. 
 
  DATA​
(​
r_relatorio​
)​
 ​
=​
 NEW lcl_relatorio​
(​
 ​
). 
 
  SET HANDLER r_relatorio​
­>​
captura_documentos FOR ALL INSTANCES.

Eventos também podem ser instância ou estáticos e devem estar


presentes em alguma sessão de visibilidade.

Para exemplificar o uso de eventos, vamos criar uma aplicação com mais
de um requisito funcional.

Tal aplicação selecionará documentos financeiros e seus itens, presentes


nas tabelas BKPF e BSEG. Tal seleção é feita através de uma tela de
seleção que possui um PARAMETER para uma empresa e um
SELECT‐OPTIONS para a data de lançamento dos documentos. Tal

78
Orientação a Objetos em ABAP
Cópia de Marcos

SELECT‐OPTIONS só permitirá a entrada de um range de datas (adição no


NO‐EXTENSION).

Com o conjunto de documentos selecionados, é necessário:


1. Somar o crédito de todos os itens
2. Dividir o intervalo de datas do lançamento em duas metades e
calcular a soma de crédito ocorrido em cada uma destas metas
3. Somar o número de itens dentro dos critérios de seleção

Para resolver tal demanda neste caso, vamos criar 2 classes: Uma
lcl_documentos_fi)​
responsável pela seleção dos dados (chamada aqui de ​
e outra responsável pelo cálculo dos três itens desejados (classe
lcl_contador_relatorio​
).

Primeiro, a classe ​
lcl_documentos_fi.

CLASS lcl_documentos_fi DEFINITION. 
 
  PUBLIC SECTION. 
 
    EVENTS​
:​
 documentos_selecionados. 
 
    TYPES: 
      ty_empresa         TYPE bkpf​
­​
bukrs, 
      ty_data_lancamento TYPE RANGE OF bkpf​
­​
budat, 
      ​
BEGIN​
 OF ty_key, 
        bukrs TYPE bkpf​
­​
bukrs, 
        belnr TYPE bkpf​
­​
belnr, 
        gjahr TYPE bkpf​
­​
gjahr, 
      ​
END​
 OF ty_key, 
      ​
BEGIN​
 OF ty_header. 
            INCLUDE TYPE ty_key. 
    TYPES​
:​
 budat TYPE bkpf​
­​
budat, 
           ​
END​
 OF ty_header, 
           ​
BEGIN​
 OF ty_item. 
            INCLUDE TYPE ty_key. 
    TYPES​
:​
 buzei TYPE bseg​
­​
buzei, 
           shkzg TYPE bseg​
­​
shkzg​
,​
 ​
" Debito/Credito 

79
Orientação a Objetos em ABAP
Cópia de Marcos

           dmbtr TYPE bseg​
­​
dmbtr​
,​
 ​
" Valor 
           ​
END​
 OF ty_item, 
 
           tt_headers TYPE HASHED TABLE OF ty_header 
         WITH UNIQUE KEY bukrs belnr gjahr, 
 
           tt_items   TYPE SORTED TABLE OF ty_item 
           WITH UNIQUE KEY bukrs belnr gjahr buzei. 
 
    DATA: 
      v_empresa            TYPE ty_empresa READ​
­​
ONLY, 
      t_ra_data_lancamento TYPE ty_data_lancamento READ​
­​
ONLY, 
      t_headers            TYPE tt_headers READ​
­​
ONLY, 
      t_items              TYPE tt_items READ​
­​
ONLY. 
 
    METHODS constructor 
      IMPORTING 
        iv_bukrs    TYPE ty_empresa 
        it_ra_budat TYPE ty_data_lancamento. 
 
  PRIVATE SECTION. 
 
    METHODS select_documents. 
 
    METHODS select_headers 
      RETURNING VALUE​
(​
re_headers​
)​
 TYPE tt_headers. 
 
    METHODS select_items 
      IMPORTING 
                it_headers           TYPE tt_headers 
      RETURNING VALUE​
(​
re_documentos​
)​
 TYPE tt_items. 
 
ENDCLASS. 
 
CLASS lcl_documentos_fi IMPLEMENTATION. 
 
  METHOD constructor. 
    me​
­>​
v_empresa ​
=​
 iv_bukrs. 
    me​
­>​
t_ra_data_lancamento ​
=​
 it_ra_budat. 
    me​
­>​
select_documents​
(​
 ​
). 
  ENDMETHOD. 
 
  METHOD select_documents. 
 

80
Orientação a Objetos em ABAP
Cópia de Marcos

    me​
­>​
t_items = 
     me​
­>​
select_items( 
       it_headers ​
=​
 me​
­>​
select_headers​
(​
 ) 
     ​
). 
 
    RAISE EVENT documentos_selecionados. 
  ENDMETHOD. 
 
  METHOD select_headers. 
 
    SELECT 
      bukrs 
      belnr 
      gjahr 
      budat 
      FROM bkpf 
      INTO TABLE re_headers 
      WHERE 
        bukrs ​
=​
 me​
­>​
v_empresa 
        AND budat IN me​
­>​
t_ra_data_lancamento. 
 
    IF sy​
­​
subrc IS INITIAL. 
      me​
­>​
t_headers ​
=​
 re_headers. 
    ENDIF. 
 
  ENDMETHOD. 
 
  METHOD select_items. 
 
    SELECT 
      bukrs 
      belnr 
      gjahr 
      buzei 
      shkzg 
      dmbtr
      FROM bseg 
      INTO CORRESPONDING FIELDS OF TABLE re_documentos 
      FOR ALL ENTRIES IN it_headers 
      WHERE 
        bukrs ​
=​
 it_headers​
­​
bukrs 
        AND belnr ​
=​
 it_headers​
­​
belnr 
        AND gjahr ​
=​
 it_headers​
­​
gjahr. 
 

81
Orientação a Objetos em ABAP
Cópia de Marcos

  ENDMETHOD. 
 
ENDCLASS.
Classe lcl_documentos_fi ‐ detentora do evento

Note que a classe acima possui um evento chamado


documentos_selecionados, ​
que é chamado no final do método
select_documents.

Os objetos do tipo ​lcl_documentos_fi portanto “disparam” seus eventos.


Criaremos agora a segunda classe que reagirá ao evento em questão.
Além disso, tal classe possui outros eventos usados nela internamente.

 
CLASS lcl_contador_relatorio DEFINITION. 
 
  PUBLIC SECTION. 
    METHODS captura_documentos 
                  FOR EVENT documentos_selecionados OF 
lcl_documentos_fi 
      IMPORTING sender. 
 
    METHODS percorre_itens. 
 
    DATA v_total TYPE lcl_documentos_fi​
=>​
ty_item​
­​
dmbtr READ​
­​
ONLY. 
 
    DATA​
:​
 ​
BEGIN​
 OF wa_total_periodo READ​
­​
ONLY, 
            primeiro TYPE lcl_documentos_fi​
=>​
ty_item​
­​
dmbtr, 
            segundo  TYPE lcl_documentos_fi​
=>​
ty_item​
­​
dmbtr, 
          ​
END​
 OF wa_total_periodo. 
 
    DATA v_quantidade_itens TYPE i READ​
­​
ONLY. 
  PRIVATE SECTION. 
 
    DATA r_documentos TYPE REF TO lcl_documentos_fi. 
 
    DATA v_metade_periodo TYPE d. 
 

82
Orientação a Objetos em ABAP
Cópia de Marcos

    EVENTS novo_item 
      EXPORTING 
        VALUE​
(​
wa_item​
)​
 TYPE lcl_documentos_fi​
=>​
ty_item. 
 
    METHODS calcula_total 
                  FOR EVENT novo_item OF lcl_contador_relatorio 
      IMPORTING wa_item. 
 
    METHODS soma_periodo 
                  FOR EVENT novo_item OF lcl_contador_relatorio 
      IMPORTING wa_item. 
 
    METHODS conta_item 
         FOR EVENT novo_item OF lcl_contador_relatorio. 
 
ENDCLASS. 
 
CLASS lcl_contador_relatorio IMPLEMENTATION. 
 
  METHOD captura_documentos. 
    me​
­>​
r_documentos ​
=​
 sender. 
 
    DATA​
(​
lv_delta_days​
)​
 = 
    ​
(​
 me​
­>​
r_documentos​
­>​
t_ra_data_lancamento​
[​
 ​
1​
 ​
]­​
high ­ 
      me​
­>​
r_documentos​
­>​
t_ra_data_lancamento​
[​
 ​
1​
 ​
]­​
low ​
). 
 
    v_metade_periodo = 
       me​
­>​
r_documentos​
­>​
t_ra_data_lancamento​
[​
 ​
1​
 ​
]­​
low + 
       ​
(​
 lv_delta_days ​
/​
 ​
2​
 ​
). 
 
    SET HANDLER: 
      me​
­>​
calcula_total FOR me, 
      me​
­>​
soma_periodo FOR me, 
      me​
­>​
conta_item FOR me. 
 
  ENDMETHOD. 
 
  METHOD percorre_itens. 
 
    LOOP AT me​
­>​
r_documentos​
­>​
t_items INTO DATA​
(​
lwa_item​
). 
      RAISE EVENT novo_item 
        EXPORTING 
          wa_item ​
=​
 lwa_item. 
    ENDLOOP. 

83
Orientação a Objetos em ABAP
Cópia de Marcos

 
  ENDMETHOD. 
 
  METHOD calcula_total. 
    IF wa_item​
­​
shkzg ​
=​
 ​
'H'​
.​
 ​
" Credito 
      me​
­>​
v_total ​
=​
 me​
­>​
v_total ​
+​
 wa_item​
­​
dmbtr. 
    ENDIF. 
  ENDMETHOD. 
 
  METHOD soma_periodo. 
 
    IF wa_item​
­​
shkzg ​
=​
 ​
'H'​
.​
 ​
" Credito 
 
      READ TABLE me​
­>​
r_documentos​
­>​
t_headers 
        WITH TABLE KEY 
          bukrs ​
=​
 wa_item​
­​
bukrs 
          belnr ​
=​
 wa_item​
­​
belnr 
          gjahr ​
=​
 wa_item​
­​
gjahr 
          ASSIGNING FIELD​
­​
SYMBOL​
(<​
wa_header​
>). 
 
      IF ​
<wa_header>​
­​
budat ​
<​
 me​
­>​
v_metade_periodo. 
        me​
­>​
wa_total_periodo​
­​
primeiro = 
          me​
­>​
wa_total_periodo​
­​
primeiro ​
+​
 wa_item​
­​
dmbtr. 
 
      ELSE. 
        me​
­>​
wa_total_periodo​
­​
segundo = 
          me​
­>​
wa_total_periodo​
­​
segundo ​
+​
 wa_item​
­​
dmbtr. 
      ENDIF. 
 
    ENDIF. 
  ENDMETHOD. 
 
  METHOD conta_item. 
    ADD ​
1​
 TO me​
­>​
v_quantidade_itens. 
  ENDMETHOD. 
 
ENDCLASS.

Classe lcl_contador_relatorio, que reage a evento de lcl_documentos_fi

documentos_selecionados​
Do ponto de vista do evento ​ , o passo três foi
feito acima: foi definido que na ocorrência de tal evento o método

84
Orientação a Objetos em ABAP
Cópia de Marcos

captura_documentos será invocado. A palavra ​ sender é mais uma


me ​
reservada do ABAP (assim como ​ e super​
) que denota “o objeto que
disparou o evento”.

Falta ainda realizar o último passo que especifica quais objetos do tipo
lcl_documentos_fi serão “ouvidos” pelas instâncias de
lcl_contador_relatorio. Como o método ​ captura_documentos é público
podemos realiar tal procedimento fora do escopo da classe. Veja abaixo a
tela de seleção de aplicação e a instanciação dos objetos necessários.

PARAMETER:
p_bukrs TYPE bkpf‐bukrs OBLIGATORY.

DATA v_budat TYPE bkpf‐budat .


SELECT‐OPTIONS:
s_budat FOR v_budat NO‐EXTENSION OBLIGATORY.

START‐OF‐SELECTION.

DATA(r_relatorio) = NEW lcl_contador_relatorio( ).

SET HANDLER r_relatorio‐>captura_documentos FOR ALL INSTANCES.

DATA(r_documentos_fi) = NEW lcl_documentos_fi(


iv_bukrs = p_bukrs
it_ra_budat = s_budat[]
).

r_relatorio‐>percorre_itens( ).

WRITE:
|Total de crédito: { r_relatorio‐>v_total }|, /,
|Período 1: { r_relatorio‐>wa_total_periodo‐primeiro }|, /
|Período 2: { r_relatorio‐>wa_total_periodo‐segundo } |,/,
|Quantidade Itens: { r_relatorio‐>v_quantidade_itens }|.

85
Orientação a Objetos em ABAP
Cópia de Marcos

Debugando a aplicação acima, é possível perceber que quando os


comandos RAISE EVENT são chamados, automaticamente a execução é
levada a todos objetos que estão ouvindo este evento, exatamente no
método automatizado especificado no passo 3.

4.7 Classes de exceção


Até então criamos classes que representavam documentos de finanças,
materiais, empregados e outros ​ objetos de negócio.​Existem outras
classes que representam erros. Para estas, damos o nome de classes de
exceção, pois erros no mundo perfeito erros deveriam ser a exceção de
uma aplicação.

Além disso, tais classes permitem que as usemos em alguns comandos


especiais para tratamento de erros.

Voltando a fazer uma comparação com o mundo procedural, o tratamento


de erros é feito baseado no comando RAISE, que dispara um erro a ser
verificado na chamada da função. Caso a função tenha resultado em erro
isso é facilmente percebido pela variável de sistema sy‐subrc.

O tratamento de erros no mundo orientado a objetos tem uma sequência


lógica parecida, apesar dos comandos sendo usados serem diferentes.

O comando RAISE possui uma variação para classes de exceção enquanto a


verificação da ocorrência do erro é feita pelo comando TRY… CATCH.

Semelhantemente do que acontece nos módulos de função onde são


declaradas as possíveis exceções na assinatura da função, métodos que
podem lançar erros declaram as classes de exceção em sua assinatura
também usando o comando EXCEPTIONS.

86
Orientação a Objetos em ABAP
Cópia de Marcos

Por definição uma classe de exceção deve ser herdeira da classe


CX_ROOT, mas não diretamente. Não fazemos uma herança simples a
partir desta classe caso seja preciso criar uma classe de erro customizada
pois isso ocasiona um erro de sintaxe. Ao invés disso precisamos iniciar a
herança a partir da classe standard CX_STATIC_CHECK (que já é herdeira
da classe CX_ROOT).

No dia‐a‐dia, é muito mais importante para nossa aplicação possuir uma


classe de exceção do que as funcionalidades de tal classe. Apesar de não
ser comum a necessidade de se criar atributos e métodos em tais classes,
não há restrição quanto a isso.

Veja o código que segue. Ao passar o nome de um usuário o programa


informa quem criou tal usuário. O interessante nesta aplicação é
entender como o tratamento de erros é realizado.

Primeiro, vamos criar classes de exceção que representam os dois


possíveis erros: usuário bloqueado e usuário inexistente.

CLASS lcx_usuario_inexistente DEFINITION 
    INHERITING FROM cx_static_check. 
 
ENDCLASS. 
 
CLASS lcx_usuario_bloqueado DEFINITION 
    INHERITING FROM cx_static_check. 
 
PUBLIC SECTION. 
  CONSTANTS: 
    c_mensagem TYPE string VALUE 'Usuário bloqueado'. 
 
ENDCLASS.
Classes de exceção

87
Orientação a Objetos em ABAP
Cópia de Marcos

Agora, teremos um método que pode lançar tais exceções.

CLASS lcl_seletor_usuario DEFINITION. 
  PUBLIC SECTION. 
 
    TYPES: 
      ty_user_name TYPE usr02​
­​
bname, 
      ty_user      TYPE usr02. 
 
    CLASS​
­​
METHODS seleciona_usuario 
      IMPORTING 
        iv_user        TYPE ty_user_name 
      RETURNING 
        VALUE​
(​
re_user​
)​
 TYPE ty_user 
      RAISING 
        lcx_usuario_inexistente 
        lcx_usuario_bloqueado. 
 
ENDCLASS. 
 
CLASS lcl_seletor_usuario IMPLEMENTATION. 
  METHOD seleciona_usuario. 
    SELECT SINGLE * 
      FROM usr02 
      INTO re_user 
      WHERE 
        bname = iv_user. 
 
    IF sy­subrc IS NOT INITIAL. 
      RAISE EXCEPTION TYPE lcx_usuario_inexistente. 
    ENDIF. 
 
    IF re_user­uflag IS NOT INITIAL. 
      RAISE EXCEPTION TYPE lcx_usuario_bloqueado. 
    ENDIF. 
  ENDMETHOD. 
ENDCLASS. 
Método que pode disparar exceção

88
Orientação a Objetos em ABAP
Cópia de Marcos

Agora, basta implementar o ponto de partida da nossa aplicação


contemplando o tratamento de exceções.

 
PARAMETER p_user TYPE lcl_seletor_usuario​
=>​
ty_user_name OBLIGATORY. 
 
START​
­​
OF​
­​
SELECTION. 
 
  TRY . 
      DATA​
(​
v_criador​
)​
 ​
=​
 lcl_seletor_usuario​
=>​
seleciona_usuario​

p_user ​
)­​
aname. 
 
    CATCH lcx_usuario_inexistente. 
      MESSAGE ​
'Usuário inexistente' 
        TYPE ​
'S'​
 DISPLAY LIKE ​
'E'. 
      STOP. 
 
    CATCH lcx_usuario_bloqueado 
      INTO DATA​
(​
r_erro_user_bloqueado​
). 
 
      MESSAGE r_erro_user_bloqueado​
­>​
c_mensagem 
        TYPE ​
'S'​
 DISPLAY LIKE ​
'E'. 
      STOP. 
 
  ENDTRY. 
 
  WRITE: 
    ​
|​
Criador​
 ​
do​
 usu​
á​
rio ​
{​
 p_user ​
}​
 ​
:​
 ​
{​
 v_criador ​
}​
 ​
|.
Tratamento de exceção usando TRY… CATCH.

Pontos importantes da aplicação acima:


➔ Classes de exceção podem conter atributos e métodos
➔ Método que pode disparar a exceção deve especificar‐las no bloco
de definição da classe
➔ Lançamento da exceção feito pelo comando RAISE EXCEPTION TYPE.
Neste momento, o ABAP está instanciando um objeto do tipo da
classe informada. Tal objeto pode ser capturado na cláusula CATCH
caso necessário.

89
Orientação a Objetos em ABAP
Cópia de Marcos

➔ Cláusula CATCH possui o nome das classes seguidas de uma


referência a classe de exceção optional.

4.8 Interfaces
O termo ​ interface em orientação a objeto em nada tem a ver com
integração entre sistemas como muitos se confundem.

Uma interface é uma forma de tornar classes não relacionadas entre si


minimamente semelhantes, o que permite por exemplo deixar o código
robusto através de uma técnica conhecida como polimorfismo.

Apesar da herança também deixar classes semelhantes entre si, ela


deveria ser usada somente quando uma das classes é uma “versão
especial” da outra. Ainda, no ABAP qualquer classe possui no máximo
uma classe mãe, enquanto uma interface pode ser usada em várias
classes ao mesmo tempo que uma única classe pode se fazer o uso de
várias interfaces.

Pensemos num caso que sua aplicação precisa criar 3 objetos de negócio
diferentes: um material, uma ordem de venda e um lançamento em
finanças.

Estes três cadastros são totalmente diferentes entre si, mas há algo que
queremos fazer com todos estes: o cadastramento de fato.

Para tornar nosso código mais legível, vamos ocultar chamadas de BAPIs e
módulos de função que realizam o cadastro efetivamente. Comecemos
pelas nossas 3 classes.

CLASS lcl_material DEFINITION. 
 

90
Orientação a Objetos em ABAP
Cópia de Marcos

ENDCLASS. 
 
CLASS lcl_ordem DEFINITION. 
 
ENDCLASS. 
 
CLASS lcl_lancamento DEFINITION. 
 
ENDCLASS. 
 
START​
­​
OF​
­​
SELECTION. 
 
  DATA​
(​
r_material​
)​
 ​
=​
 NEW lcl_material​
(​
 ​
). 
  DATA​
(​
r_ordem​
)​
 ​
=​
 NEW lcl_ordem​
(​
 ​
). 
  DATA​
(​
r_lancamento​
)​
 ​
=​
 NEW lcl_lancamento​
(​
 ​
).

Como queremos cadastrar todos os objetos de negócio, seria possível


criar um método chamado ​ cadastrar em todas as classes. Neste cenário,
caso no futuro tivéssemos que implementar a atualização dos três
documentos deveríamos inserir um método ​ atualizar em cada uma das
classes. Tal tipo de manutenção no código é muito mais comum do que se
imagina caso o conceito seja abstraído.

Ao invés de criar métodos semelhantes em cada uma das classes, vamos


criar uma interface que tornará nossas classes semelhantes entre si.

INTERFACE lif_objeto_negocio. 
 
  METHODS criar. 
 
ENDINTERFACE. 
 
CLASS lcl_material DEFINITION. 
  PUBLIC SECTION. 
    INTERFACES lif_objeto_negocio. 
 
ENDCLASS. 
 
CLASS lcl_material IMPLEMENTATION. 

91
Orientação a Objetos em ABAP
Cópia de Marcos

  METHOD lif_objeto_negocio~criar. 
*    CALL FUNCTION 'Z_CRIA_MATERIAL'... 
  ENDMETHOD. 
ENDCLASS. 
 
CLASS lcl_ordem DEFINITION. 
  PUBLIC SECTION. 
    INTERFACES lif_objeto_negocio. 
ENDCLASS. 
 
CLASS lcl_ordem IMPLEMENTATION. 
  METHOD lif_objeto_negocio~criar. 
*    CALL FUNCTION 'Z_CRIA_ORDEM'... 
  ENDMETHOD. 
ENDCLASS. 
 
CLASS lcl_lancamento DEFINITION. 
  PUBLIC SECTION. 
    INTERFACES lif_objeto_negocio. 
ENDCLASS. 
 
CLASS lcl_lancamento IMPLEMENTATION. 
  METHOD lif_objeto_negocio~criar. 
*    CALL FUNCTION 'Z_CRIA_LANCAMENTO'... 
  ENDMETHOD. 
ENDCLASS. 
Implementação de interface

Com o código acima, poderíamos fazer a chamada do método ​ criar


proveniente da interface sem ao menos saber com qual tipo de objeto
estamos trabalhando.

START​
­​
OF​
­​
SELECTION. 
 
  DATA​
(​
r_material​
)​
 ​
=​
 NEW lcl_material​
(​
 ​
). 
  DATA​
(​
r_ordem​
)​
 ​
=​
 NEW lcl_ordem​
(​
 ​
). 
  DATA​
(​
r_lancamento​
)​
 ​
=​
 NEW lcl_lancamento​
(​
 ​
). 
 
  DATA​
:​
 t_obj_negocio 
          TYPE TABLE OF REF TO lif_objeto_negocio, 
        r_obj_negocio TYPE REF TO lif_objeto_negocio. 

92
Orientação a Objetos em ABAP
Cópia de Marcos

 
  APPEND r_material TO t_obj_negocio. 
  APPEND r_ordem TO t_obj_negocio. 
  APPEND r_lancamento TO t_obj_negocio. 
 
  LOOP AT t_obj_negocio INTO r_obj_negocio. 
    r_obj_negocio​
­>​
criar​
(​
 ​
). 
  ENDLOOP.
Polimorfismo

No exemplo acima, temos uma tabela interna de referências. A novidade


é que as referências estão atreladas a uma interface e não uma classe.

➔ Como funciona uma referência a interface?

Uma referência a ​ classe pode apontar para qualquer objeto da classe


especificada depois do TYPE ou de alguma outra classe pertencente a
estrutura de herança da primeira.

Já uma referência a ​
interface a permite apontar ​
para qualquer objeto de
qualquer classe que implementa tal interface​
.

Por implementar uma interface, entenda uma classe que possui o


comando INTERFACES dentro do seu bloco de definição.

A frase acima é fica clara caso você tenha entendido bem conceitos de
orientação a objetos.

93
Orientação a Objetos em ABAP
Cópia de Marcos

5 Conceitos Avançados
Conceitos considerados “avançados” na orientação a objetos não são
difíceis de serem entendidos. O principal desafio é saber aplicá‐los ou
entendê‐los em aplicações para que haja benefício no desenvolvimento.

5.1 Abstração
O conceito de abstração só será relevante caso sua aplicação trabalhe
com herança. Tanto uma classe como um método podem ser considerados
abstratos.

5.1.1 Classes abstratas


Classes abstratas são simplesmente classes que não podem ser
instanciadas, ou seja, não se pode usar a instrução CREATE OBJECT ou
NEW para se criar objetos desta classe.

CLASS lcl_documento DEFINITION ABSTRACT. 
 
ENDCLASS. 
 
CLASS lcl_ordem_de_venda DEFINITION 
    INHERITING FROM lcl_documento. 
 
ENDCLASS. 
 
CLASS lcl_requisicao_de_compra DEFINITION 
    INHERITING FROM lcl_documento. 
 
ENDCLASS. 
 
DATA​
:​
 r_documento            TYPE REF TO lcl_documento​
,​
 ​
" ABSTRATO 
      r_ordem_de_venda       TYPE REF TO lcl_ordem_de_venda, 
      r_requisicao_de_compra TYPE REF TO lcl_requisicao_de_compra. 

94
Orientação a Objetos em ABAP
Cópia de Marcos

 
START​
­​
OF​
­​
SELECTION. 
 
  r_ordem_de_venda ​
=​
 NEW lcl_ordem_de_venda​
(​
 ​
). 
  r_requisicao_de_compra ​
=​
 NEW lcl_requisicao_de_compra​
(​
 ​
). 
*​
r_documento ​
=​
 ​
new​
 lcl_documento​
(​
 ​
).​
 ​
" ERRO DE SINTAXE 
  r_documento ​
=​
 NEW lcl_ordem_de_venda​
(​
 ​
).
Exemplo de classe abstrata

Note que ainda é possível usar uma referência a uma classe abstrata.
Todavia tal referência ao ser preenchida deve apontar para algum objeto
de classe herdeira e da classe abstrata.

5.1.2 Métodos abstratos


Um método abstrato é simplesmente um método cuja redefinição na
classe filha é obrigatória. Por definição um método abstrato deve
pertencer a uma classe abstrata.

A abstração de um método faz com que não seja possível implementá‐lo


no bloco de implementação da mesma classe. Em outras palavras, a
classe abaixo está sintaticamente correta.

CLASS lcl_saida_template DEFINITION ABSTRACT. 
  PROTECTED SECTION. 
    METHODS imprimir ABSTRACT. 
ENDCLASS.
Método abstrato

No caso acima, estamos forçando a herança da classe lcl_saida_template


e​
a redinição do método ​
imprimir.

CLASS lcl_saida_template DEFINITION ABSTRACT. 
  PROTECTED SECTION. 
    METHODS imprimir ABSTRACT. 

95
Orientação a Objetos em ABAP
Cópia de Marcos

ENDCLASS. 
 
CLASS lcl_saida_alv DEFINITION 
    INHERITING FROM lcl_saida_template. 
 
  PROTECTED SECTION. 
    METHODS imprimir REDEFINITION​
.​
 ​
" Obrigatorio 
   
ENDCLASS. 
 
CLASS lcl_saida_alv IMPLEMENTATION. 
  
  METHOD imprimir. 
    ​
" exibe ALV 
  ENDMETHOD. 
  
ENDCLASS.
Redefinição de método abstrato

5.2 Final
finalização ​
O conceito de ​ (ou simplesmente o comando FINAL) é usado
quando quer‐se ​
evitar​o uso de herança.

5.2.1 Classes Final


Uma classe final simplesmente não pode ser herdada.

CLASS lcl_saida_alv DEFINITION FINAL. 
 
ENDCLASS.
Classe final

➔ E por que eu iria evitar que alguém herdasse minha classe?

96
Orientação a Objetos em ABAP
Cópia de Marcos

Um bom motivo é para evitar que manutenções impensadas sejam feitas.


Principalmente quando a classe FINAL é standard. Assim, a SAP pode
evitar que o desenvolvedor ABAP do cliente herde uma classe standard
para deturpar seu comportamento.

5.2.2 Métodos Final

De forma semelhante, métodos FINAL são aqueles que não podem ser
redefinidos.

CLASS lcl_saida_alv DEFINITION. 
  PUBLIC SECTION. 
    METHODS format_columns FINAL. 
 
ENDCLASS. 
 
CLASS lcl_saida_alv IMPLEMENTATION. 
  METHOD format_columns. 
    ​
" Unica implementacao possivel 
    ​
" nao é possível redefinir  
    ​
" este método 
  ENDMETHOD. 
ENDCLASS.
Método Final

5.3 Geração de Instância


Destes pequenos‐grandes detalhes da orientação a objetos, a ​
geração de
instância talvez seja o mais complicado de entender. Mas isso não quer
dizer que seja difícil demais.

Quando uma classe é criada, por padrão podemos criar quantas


referências quisermos a ela e utilizá‐las para criar diversos objetos.

97
Orientação a Objetos em ABAP
Cópia de Marcos

Podemos então instanciar objetos em qualquer local de uma aplicação


ABAP: dentro do START‐OF‐SELECTION, PBO, PAI, dentro de um módulo
de função ou até dentro de um método.

A geração de instância permite definir onde objetos de uma classe podem


ser criados. Isso é feito com a extensão CREATE PUBLIC | PROTECTED |
PRIVATE na declaração de uma classe. A diferença destas três
possibilidades é destacada a seguir:
➔ Pública (padrão): Pode‐se criar objetos em qualquer lugar da
aplicação
➔ Protegido: Pode apenas criar objetos dentro da classe em si ou
dentro de uma classe filha (logo, neste caso há herança)
➔ Privado: Somente a própria classe pode criar objetos com seu tipo.

Exemplo:

CLASS lcl_impressora DEFINITION CREATE PRIVATE. 
  
  PUBLIC SECTION. 
  
    CLASS​
­​
METHODS cria_impressora 
      RETURNING VALUE​
(​
re_nova_impressora) 
                  TYPE REF TO lcl_impressora. 
 
ENDCLASS. 
 
CLASS lcl_impressora IMPLEMENTATION. 
  
  METHOD cria_impressora. 
    ​
" criacao de objetos só pode acontecer 
    ​
" dentro da própria classe 
    re_nova_impressora ​
=​
 NEW lcl_impressora​
(​
 ​
).  
  ENDMETHOD. 
  
ENDCLASS.
Geração de Instância Privada ‐ somente a classe pode criar seus próprios
objetos

98
Orientação a Objetos em ABAP
Cópia de Marcos

99
Orientação a Objetos em ABAP
Cópia de Marcos

6 Conclusão
Com os conceitos apresentados no livro, você deve estar apto a se
aventurar nos diversos frameworks ABAP como Web Dynpro, Gateway e
BOPF.

Bons estudos!

100

S-ar putea să vă placă și