Arquivo da categoria ‘Abap’

Existem muitos estilos de programação e estes chamados de paradigmas. As linguagens mais antigas possuem o estilo processual (procedural) , pois da ênfase sobre a especificação computacional de procedimentos, enquanto as linguagens mais modernas são orientadas a objeto, as linguagens que evoluirão ou as que nasceram de uma linguagem de outro paradigma e ainda mantém as suas características seja por opção ou por compatibilidade, estas são chamadas de hibridas, que em ciência da computação é uma linguagem de programação que se baseia em elementos de mais de um paradigma de programação.

Um paradigma de programação fornece e determina a visão que o programador possui sobre a estruturação e execução do programa. Por exemplo, em programação orientada a objetos, programadores podem abstrair um programa como uma coleção de objetos que interagem entre si, enquanto em programação funcional os programadores abstraem o programa como uma sequência de funções executadas de modo empilhado.

Em linguagens multi paradigmas a maioria da programação hoje em dia é orientada a objeto, o que significa que o foco está em objetos e suas interações.

Em programação orientada a objetos existem dois tipos de métodos, chamados métodos de classe e métodos de objetos. Métodos de classe são identificados pela palavra-chave static na primeira linha. Qualquer método que não possua a palavra-chave static é um método de objeto. Este significado pode variar dependendo da linguagem de programação vide Python.

Então podemos dividir os métodos entre estáticos e não estáticos:

Estáticos: métodos estáticos não requerem uma instância da classe nem podem acessar implicitamente os dados (this, self, Me, etc.) de tal instância. Um método estático é distinguido em algumas linguagens de programação com a palavra-chave static colocada em algum lugar na assinatura do método.

Não Estáticos: métodos não estáticos requerem uma instância da classe e podem acessar implicitamente os dados (this, self, Me, etc.) de tal instância. Este método exige um tipo de código diferente da programação de códigos estáticos, pois está sempre se referindo a instancia do objeto e não da classe.

Código do Método Objeto:

  • Não declarar a instrução estática.
  • Nomear o  método para ser mais idiomático.
  • Remover o parâmetro da própria classe na declaração.
  • Dentro do método de objeto você deve se referir as variáveis ​​de instância como variáveis ​​locais.

Exemplo:

A por default a maioria das linguagens de  programação orientada a objetos fornecem um método chamado equals(igual) que define a equivalência entre objetos As classes default fornecem o método  equals que já faz toda a coisa do modo correto. Mas para os tipos definidos pelo usuário o comportamento padrão é o mesmo que identidade, que normalmente não é o resultado que você quer. Então tudo o que temos a fazer é reescrever o método  equals para nosso objeto.

O modo correto é criar uma função Override para o método equals, mas aqui vamos escrever a função com o nome traduzido para que fique claro a diferença entre métodos de classe e métodos de objeto, que é o objetivo deste post.

Java

Classe #1

public class Program
 {

public static void main(String[] args)
 {
   // Instancia dos Objetos

   Quadrado q1 = new Quadrado(32);
   Quadrado q2 = new Quadrado(32);

   System.out.println("Verifica se os Objetos são iguais\n");

   // Usa método da Classe
   System.out.print("Testa método da classe:");
   System.out.println(Quadrado.iguaisQ(q1, q2));

   // Usa método do Objeto
   System.out.print("Testa método do objeto:");
   System.out.println(q1.iguais(q2));
  }
}

Classe #2

public class Quadrado
 {
    private double lado;
Quadrado (double lado)
     {
      this.lado = lado;
     }
     // Método da Classe - Estatico
     static public boolean iguaisQ(Quadrado q1, Quadrado q2)
     {
      return (q1.lado == q2.lado);
     }
     // Método do Objeto  - Não Estatico
     public boolean iguais(Quadrado q2)
     {
      return (lado == q2.lado);
     }
}

C++

Classe #1

#include "stdafx.h"
#include <iostream>
#include "Quadrado.h"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
 {

  // Instancia dos Objetos
  Quadrado q1 (32);
  Quadrado q2 (32);

  cout << "Verifica se os Objetos são iguais\n" << endl;

  // Usa método da Classe
  cout << "Testa método da classe:";
  cout << Quadrado::iguaisQ(q1, q2) << endl;

  // Usa método do Objeto
  cout << "Testa método do objeto:";
  cout << q1.iguais(q2) << endl;
  system("pause");
  return 0;
 }

Classe #2

#include "stdafx.h"
#include <iostream>
using namespace std;

class Quadrado
 {
 private:

 double lado;

 public:

 Quadrado(double lado)
  {
   this->lado = lado;
  }

  // Método da Classe - Estatico
  static  bool iguaisQ(Quadrado q1, Quadrado q2)
  {
   return (q1.lado == q2.lado);
  }

  // Método do Objeto  - Não Estatico
  bool iguais(Quadrado q2)
  {
   return (lado == q2.lado);
  }
};

C#

Classe #1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DesenvolvimentoAberto
 {
     class Program
     {
         static void Main(string[] args)
         {

           // Instancia dos Objetos
           Quadrado q1 = new Quadrado(32);
           Quadrado q2 = new Quadrado(32);
           Console.WriteLine("Verifica se os Objetos são iguais\n");

          // Usa método da Classe
          Console.Write("Testa método da classe:");
          Console.WriteLine(Quadrado.iguaisQ(q1, q2));

          // Usa método do Objeto
          Console.Write("Testa método do objeto:");
          Console.WriteLine(q1.iguais(q2));
          Console.ReadKey();
         }
     }
 }

Classe #2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DesenvolvimentoAberto
 {
     class Quadrado
     {
       private double lado;

             public Quadrado(double lado)
             {
                 this.lado = lado;
             }

             // Método da Classe - Estatico
             static public Boolean iguaisQ(Quadrado q1, Quadrado q2)
             {
                 return (q1.lado == q2.lado);
             }

             // Método do Objeto  - Não Estatico
             public Boolean iguais(Quadrado q2)
             {
                 return (lado == q2.lado);
             }
    }
 }

Python

Classe #1

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# objetos_metodos.py
class Q:
     lado = 0
class Quadrado(Q) :
     def __init__(self, lado = 0):
         self.lado = lado

     def iguais(self,q2 = Q()):
         return self.lado == q2.lado

     @staticmethod
     def iguaisQ(q1 = Q() , q2 = Q()):
         return q1.lado == q2.lado

# Instancia dos Objetos
q1 = Quadrado(32)
q2 = Quadrado(32)

print "Verifica se os Objetos são iguais\n"

# Usa método da Classe
print "Testa método da classe:"
print Quadrado.iguaisQ(q1, q2)

# Usa método do Objeto
print "Testa método do objeto:"
print q1.iguais(q2)

raw_input()

Abap

Classe #1

*&---------------------------------------------------------------------*
*& Report  ZMETODOS
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Metodos Estaticos e de Objetos
*&---------------------------------------------------------------------*

REPORT  ZMETODOS.

class Quadrado DEFINITION.

PUBLIC SECTION.

DATA lado TYPE i.

METHODS:

  CONSTRUCTOR IMPORTING lado TYPE i,

  IGUAIS IMPORTING Q2 TYPE REF TO QUADRADO
         RETURNING VALUE(resultado) TYPE ABAP_BOOL.

CLASS-METHODS

  IGUAISQ IMPORTING  Q1 TYPE REF TO QUADRADO
                     Q2 TYPE REF TO QUADRADO
          RETURNING VALUE(resultado) TYPE ABAP_BOOL.

ENDCLASS.

CLASS QUADRADO IMPLEMENTATION.

  METHOD CONSTRUCTOR.
    CALL METHOD SUPER->CONSTRUCTOR.
    me->LADO = LADO.
  ENDMETHOD.

  METHOD IGUAIS.
    IF me->LADO EQ  Q2->LADO.
      RESULTADO = ABAP_TRUE.
    ELSE.
      RESULTADO = ABAP_FALSE.
    ENDIF.
  ENDMETHOD.

  METHOD IGUAISQ.
    IF Q1->LADO EQ  q2->LADO.
      RESULTADO = ABAP_TRUE.
    ELSE.
      RESULTADO = ABAP_FALSE.
    ENDIF.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

DATA Q1 TYPE REF TO QUADRADO.
DATA Q2 TYPE REF TO QUADRADO.
DATA RT TYPE ABAP_BOOL.

CREATE OBJECT Q1 EXPORTING LADO = 32.
CREATE OBJECT Q2 EXPORTING LADO = 32.

WRITE : / 'Verifica se os Objetos são iguais'.

* Usa método da Classe

WRITE: / 'Testa método da classe:'.

QUADRADO=>IGUAISQ( exporting Q1 = Q1 Q2 = Q2 receiving RESULTADO = RT ).
PERFORM RESULTADO USING RT.

* Usa método do Objeto

WRITE : / 'Testa método do objeto:'.

RT = Q1->IGUAIS( Q2 ).
PERFORM RESULTADO USING RT.

FORM RESULTADO USING VALUE(R) TYPE ABAP_BOOL.
  IF R = ABAP_TRUE.
    WRITE :  'TRUE'.
  ELSE.
    WRITE :  'FALSE'.
  ENDIF.
ENDFORM.

Método de sobrecarga é uma característica encontrada em várias linguagens de programação, que permite a criação de vários métodos com o mesmo nome, que diferem uns dos outros no tipo da entrada e a saída da função. É simplesmente definido como a capacidade de uma função para executar diferentes tarefas.

Construtores, são usados ​​para criar instâncias de um objeto, também podem ser sobrecarregados em algumas linguagens de programação orientadas a objeto. Porque em muitas línguas o nome do construtor é pré-determinado pelo nome da classe. Sempre que são necessários vários construtores são implementados como funções sobrecarregadas. Um construtor padrão não tem parâmetros, instanciam os membros do objeto com um valor zero.

Ter pelo menos dois construtores é quase obrigatório em programação orientada a objeto, o construtor default facilita criar métodos Modifiers e Fill-in, pois é possível manipular objetos sem ter que passar nenhum parâmetros para eles e trabalhar com seus atributos dentro dos métodos, enquanto ao mesmo tempo é pratico criar objetos com valores inicializados, sem ter que escrever varias linhas.

Em Java, C++ e C# sobrecarregar um construtor  é simples, basta apenas criar quantos construtores forem necessários, por outro lado linguagens hibridas como Abap e Python (C++ também é uma linguagem hibrida, mas é muito poderosa) não é possível  sobrecarregar o método construtor, mas como este é um recurso extremamente útil, existe um modo de criar o mesmo efeito de sobrecarga nos construtores.

Abap possui a palavra chave OPTIONAL, na qual marca o parâmetro como opcional, deste modo é possível criar um objeto que simula o construtor Overload.

Python é uma linguagem moderna e bem flexível em sua sintaxe e possibilita inicializar o construtor atribuindo valores a variável e podemos usar a palavra chave None para dizer que o conteúdo é vazio, simulando deste modo um construtor Overload.

Exemplo:

Neste exemplo criamos dois construtores : o construtor default e um construtor Overload, para as linguagens Java, C++ e C# e para as  linguagens Abap e Python usamos um recurso da língua para simular o construtor Overload obtendo o mesmo efeito.

Java

public class Sobrecarga
  {
     int x = 0;
     int y = 0;

     public Sobrecarga () {}

     public Sobrecarga(int x, int y)
   {
     this.x = x;
     this.y = y;
   }

   public  void imprimeSb()
   {
     System.out.println("X=" + this.x + " Y=" + this.y);
   }

   public static void main(String[] args)
   {
       Sobrecarga sc1 = new Sobrecarga();
       Sobrecarga sc2 = new Sobrecarga(10,20);
       System.out.println("Construtor Default");
       sc1.imprimeSb();
       System.out.println("Construtor Overload");
       sc2.imprimeSb();
  }
 }

C++

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

using namespace std;

class Sobrecarga
  {
  public:
   int x = 0;
   int y = 0;

   Sobrecarga( )   {   }

   Sobrecarga(int x, int y)
   {
    this->x = x;
    this->y = y;
   }

  void imprimeSb()
   {
    cout << "X=" << this->x << " Y=" << this->y << endl;
   }
};

int _tmain(int argc, _TCHAR* argv[])
  {
   Sobrecarga sc1;  Sobrecarga sc2(10, 20);
   cout << "Construtor Default" << endl;
   sc1.imprimeSb();

   cout << "Construtor Overload" << endl;
   sc2.imprimeSb();
   system("pause");
   return 0;
  }

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesenvolvimentoAberto
  {
      class Sobrecarga
      {
          int x = 0;
          int y = 0;

         public Sobrecarga() { }

         public Sobrecarga(int x, int y)
          {
              this.x = x;
              this.y = y;
          }

      public void imprimeSb()
       {
         Console.WriteLine("X=" + this.x + " Y=" + this.y);
       }

          static void Main(string[] args)
          {
              Sobrecarga sc1 = new Sobrecarga();
              Sobrecarga sc2 = new Sobrecarga(10,20);
              Console.WriteLine("Construtor Default");
              sc1.imprimeSb();
              Console.WriteLine("Construtor Overload");
              sc2.imprimeSb();
              Console.ReadKey();
          }
      }
  }

Abap

*&---------------------------------------------------------------------*
*& Report  ZOBJETOS_OVER
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Construtor Overload
*&---------------------------------------------------------------------*

REPORT  ZOBJETOS_OVER.

* Declara Classe

Class SobreCarga DEFINITION.

PUBLIC SECTION.
   DATA X TYPE i.
    DATA Y TYPE i.

" Efeito Overload
METHODS:
CONSTRUCTOR IMPORTING
             X TYPE i OPTIONAL
             Y TYPE i OPTIONAL,
ImprimeSB.

ENDCLASS.

Class SOBRECARGA IMPLEMENTATION.

 METHOD CONSTRUCTOR.
     me->X = X.
     me->Y = Y.
 ENDMETHOD.

 METHOD ImprimeSB.
     WRITE: / 'X=', me->X, 'Y=', me->Y.
 ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

DATA SB1 TYPE REF TO SOBRECARGA.
DATA SB2 TYPE REF TO SOBRECARGA.

* Cria Objetos Construtor Default e Overload
CREATE OBJECT SB1.
CREATE OBJECT SB2 EXPORTING X = 10 Y = 20.

WRITE: / 'Construtor Default:'.
SB1->IMPRIMESB( ).
WRITE: / 'Construtor Overload:'.
SB2->IMPRIMESB( ).

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# sobrecarga.py

class SobreCarga:
      x = 0
      y = 0
      def __init__(Self,x= None, y = None):
          if (x is not None) and (y is not None):
              Self.x = x
              Self.y = y
      def ImprimeSb(Self):
          print "X=", Self.x, "Y=", Self.y

sc1 = SobreCarga();
sc2 = SobreCarga(10,20);
print "Construtor Default"
sc1.ImprimeSb();
print "Construtor Overload"
sc2.ImprimeSb();
raw_input()

Pure Function

Usa os objetos como argumentos, mas não os modifica. o valor de retorno é ou um primitivo ou um novo objeto criado dentro do método.

Um método é considerado uma função pura se o resultado depender apenas dos argumentos, e não ter efeitos colaterais, como modificar um argumento ou imprimir algo. O único resultado de chamar uma função pura é o seu valor de retorno.

Na transformação funcional pura, um conjunto de funções, chamadas funções puras, definem a forma de como transformar um conjunto de dados estruturados a partir de sua forma original para outra forma. A palavra “pura” indica que as funções são combináveis​​, que exige que elas sejam:

Auto-suficiente, de modo que elas podem ser livremente ordenada e rearranjada sem emaranhamento ou interdependências com o resto do programa. Transformações puras não têm conhecimento ou efeito sobre o meio ambiente. Ou seja, as funções utilizadas para a transformação não tem efeitos colaterais.

Sem mudança de estado, de modo que a execução da mesma função ou conjunto específico de funções na mesma entrada sempre resultará na mesma saída. Transformações puras não têm memória do seu uso anterior. Funções puras ajudam a gerenciar a complexidade dos grandes projetos.

Modifiers

Usa objetos como argumentos e modifica alguns elementos ou todos eles. Muitas vezes, retorna um method. Um método modificador muda a forma como os objetos funcionam.

Fill-in

Um dos argumentos é um objeto vazio que é preenchido em pelo método. Tecnicamente, este método também é um tipo de Modifier.

Melhores Praticas

É recomendado que você escreva funções puras sempre que for razoável, e recorra aos Modifiers e Fill-ins apenas se houver uma grande vantagem.

Métodos Modifiers e Fill-in  são eficientes porque eles não têm que criar novos objetos. Mas se torna mais difícil de isolar partes de um programa, e em grandes projetos podem causar erros que são difíceis de encontrar.

Exemplo:

Neste exemplo escrevemos três métodos diferentes: Pure function, Modifier e um fill-in, e manipulamos objetos utilizando estes métodos.

Abap

*&---------------------------------------------------------------------*
*& Report  ZOBJETOS_M
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Objetos - Métodos - Pure Function, Modifier e Fill-in
*&---------------------------------------------------------------------*

REPORT  ZOBJETOS_M.

* Classe Retangulo
Class Retangulo DEFINITION.
PUBLIC SECTION.

DATA : x       TYPE i,
       y       TYPE i,
       altura  TYPE i,
       largura TYPE i.

METHODS:

" Workaround para efeito Overload
CONSTRUCTOR IMPORTING
       X       TYPE i OPTIONAL
       Y       TYPE i OPTIONAL
       altura  TYPE i OPTIONAL
       largura TYPE i OPTIONAL,

imprimeRet.

ENDCLASS.

Class RETANGULO IMPLEMENTATION.

METHOD CONSTRUCTOR.
   me->X       = X.
   me->Y       = Y.
   me->ALTURA  = ALTURA.
   me->LARGURA = LARGURA.
ENDMETHOD.

METHOD IMPRIMERET.
   WRITE: / 'X=', me->X, 'Y=', me->Y, 'Altura=', me->ALTURA, 'Largura=', me->LARGURA.
ENDMETHOD.

ENDCLASS.

* Classe Métodos
CLASS METODOS DEFINITION INHERITING FROM RETANGULO.
PUBLIC SECTION.

METHODS:

CONSTRUCTOR,

maxRet   IMPORTING
 ret     TYPE REF TO RETANGULO
 altura  TYPE i
 largura TYPE i
         RETURNING VALUE(resultado) TYPE abap_bool,

posicao  IMPORTING
     ret TYPE REF TO RETANGULO
     x   TYPE i
     y   TYPE i,

modRet  IMPORTING
     r1 TYPE REF TO RETANGULO
     r2 TYPE REF TO RETANGULO
     r3 TYPE REF TO RETANGULO.

ENDCLASS.

CLASS METODOS IMPLEMENTATION.

METHOD CONSTRUCTOR.
     CALL METHOD SUPER->CONSTRUCTOR.
ENDMETHOD.

* Método Pure Function
METHOD MAXRET.
  IF  me->altura LT altura AND me->largura LT largura.
    RESULTADO = abap_true.
  ELSE.
    RESULTADO = abap_false.
  ENDIF.
ENDMETHOD.

* Método Modifier
METHOD POSICAO.
   RET->X = RET->X + X.
   RET->Y = RET->Y + Y.
ENDMETHOD.

* Método Fill-in
METHOD MODRET.
   R1->X = R2->X + R3->X.
   R1->Y = R2->Y + R3->Y.
   R1->ALTURA = R2->ALTURA + R3->ALTURA.
   R1->LARGURA =  R2->LARGURA +  R3->LARGURA.
ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

* Cria Instâncias e Objetos

DATA RET1 TYPE REF TO RETANGULO.
DATA RET2 TYPE REF TO RETANGULO.
DATA RET3 TYPE REF TO RETANGULO.
DATA MET1 TYPE REF TO METODOS.
DATA REST TYPE ABAP_BOOL.

* Objetos instanciados contrutores

CREATE OBJECT RET1 EXPORTING X = 50 Y = 50 ALTURA = 200 LARGURA = 300.
CREATE OBJECT RET2 EXPORTING X = 15 Y = 15 ALTURA = 120 LARGURA = 150.

* Objeto instanciado Overload

CREATE OBJECT RET3.

* Objeto de Metodos

CREATE OBJECT MET1.

* Manipula Método Pure Function

RET1->IMPRIMERET( ).
MET1->MAXRET( exporting RET = RET1 ALTURA = 500 LARGURA = 600 RECEIVING RESULTADO = REST  ).

IF REST = abap_true.
   WRITE : / 'Retangulo está dentro do limite maximo: TRUE'.
ELSE.
   WRITE : / 'Retangulo está dentro do limite maximo: FALSE'.
ENDIF.

* Manipula Método Modifier
WRITE : / .
WRITE : / 'Modifica posição do retangulo:'.
MET1->POSICAO( exporting RET = RET1 X   = 20 Y   = 20 ).
RET1->IMPRIMERET( ).

* Manipula Métodos Fill-in
WRITE : / .
WRITE : / 'Modifica tamanho do retangulo:'.
MET1->MODRET( exporting R1 = RET3 R2 = RET1 R3 = RET2 ).
RET3->IMPRIMERET( ).

Programação orientada a objetos apela em vários níveis. Para os gestores, que promete um desenvolvimento e manutenção mais rápido e mais barato. Para analistas e designers, o processo de modelagem torna-se mais simples e produz um design claro e gerenciável.

Para os programadores, a elegância e clareza do modelo de objeto e do poder de ferramentas e bibliotecas orientadas a objetos faz programação de uma tarefa muito mais agradável, e programadores experimentam um aumento na produtividade. Todo mundo ganha, ao que parece.

Se há um lado negativo, é à custa da curva de aprendizado. Pensar em objetos é uma dramática partida de pensar processualmente, e o processo de criação de objetos é muito mais desafiador do projeto processual, especialmente se você está tentando criar objetos reutilizáveis​​.

A abordagem orientada a objetos dá um passo mais longe, fornecendo ferramentas para o programador representar elementos no espaço do problema. Esta representação é geral o suficiente para que o programador não é fique restrito a qualquer tipo particular de problema.

Objetos são mutáveis

Você pode alterar o conteúdo de um objeto, fazendo uma atribuição a uma de suas variáveis de instância.

Você pode escrever métodos que retornam objetos. Observe que você pode usar a palavra chave CREATE OBJECT para criar um novo objeto, e logo em seguida usar o RETURNING (resultado) como valor de retorno.

Modificando objetos, passando-os como argumentos para métodos podem ser úteis, mas também pode tornar a depuração mais difícil, porque nem sempre são claras as invocações que o método faz ou não para modificar seus argumentos. Mais tarde, vamos discutir alguns prós e contras deste estilo de programação.

Passando e Retornando Objetos

Em programação orientada a objetos é possível criar métodos passando um objeto e retornando um objeto.

Alias de Objetos

Quando dois objetos referem-se ao mesmo objeto. Em outras palavras, este objeto tem dois nomes, Objeto1 e Objeto2. Quando uma pessoa usa dois nomes, é chamado de aliasing. A mesma coisa com os objetos. Quando duas variáveis são alias, todas as mudanças que afetam uma variável também afetara a outra.

Null

Quando você cria uma variável de objeto, lembre-se que você está criando uma referência a um objeto. Até você fazer variável apontar para um objeto, o valor da variável é nulo. null é um valor especial e uma palavra-chave que significa: nenhum objeto.

Garbage collection

Se ninguém se refere a um objeto, então ninguém pode ler ou gravar qualquer dos seus valores, ou chamar um método nele. Em efeito, ele deixa de existir. Poderíamos manter o objeto na memória, mas seria apenas um espaço de resíduos, assim como o seu programa é executado periodicamente, o sistema procura por objetos encalhados e tenta recupera-los, em um processo chamado de coleta de lixo. Posteriormente, o espaço de memória ocupado por o objeto estará disponível para ser utilizado como parte de um novo objeto. Você não tem que fazer nada para fazer a coleta de lixo acontecer, e em geral você não vai estar ciente disso. Mas você deve saber que é periodicamente executado em segundo plano.

Objetos e Primitivos

Existem dois tipos diferentes, tipos primitivos e tipos de objetos. primitivos, como int e boolean começam com letras minúsculas; tipos de objetos começam com letras maiúsculas. Esta distinção é útil porque nos lembra algumas das diferenças entre eles:

Quando você declara uma variável primitiva, você tem espaço de armazenamento para um valor primitivo. Quando você declara uma variável de objeto, você tem um espaço para uma referência a um objeto.

Se você não inicializar um tipo primitivo, é dado um valor padrão a ele que depende de cada tipo primitivo.

Variáveis primitivas são bem isoladas, no sentido de que não há nada você possa fazer em um método que vai afetar uma variável em outro método.

Há uma outra diferença entre primitivos e tipos de objetos. Você não pode adicionar novos primitivos, mas você pode criar novos tipos de objetos.

Exemplo:

Neste exemplo criamos dois objetos de classes distintas e usamos algumas técnicas de manipulação de objetos, como: métodos de referencias ao objeto, retorno de objetos, aliasing de objetos.

Dica:

Você pode rodar o código fonte abaixo, ou separar as classes no Class Builder, deixando o código fonte menor e muito mais limpo.

Abap

*&---------------------------------------------------------------------*
*& Report  ZOBJETO
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Objetos
*&---------------------------------------------------------------------*

REPORT  ZOBJETO.

* Cria classe Pontos

class PONTOS DEFINITION.

PUBLIC SECTION.

data : x TYPE i,
       y TYPE i.

METHODS :

        " Workaround para criar Overload
        " Constructor ()

        CONSTRUCTOR IMPORTING x TYPE i OPTIONAL
                              y TYPE i OPTIONAL.

ENDCLASS.

class PONTOS IMPLEMENTATION.

    METHOD CONSTRUCTOR.
       me->x = x.
       me->y = y.
    ENDMETHOD.

ENDCLASS.

* Cria Classe Retangulo.

class Retangulo DEFINITION INHERITING FROM PONTOS.

PUBLIC SECTION.

data: altura  TYPE i,
      largura TYPE i.

METHODS: " Workaround para criar Overload
         " Constructor ()

         CONSTRUCTOR IMPORTING x       TYPE i OPTIONAL
                               y       TYPE i OPTIONAL
                               altura  TYPE i OPTIONAL
                               largura TYPE i OPTIONAL,

         OBJETO.

ENDCLASS.

class Retangulo IMPLEMENTATION.

     METHOD CONSTRUCTOR.

        CALL METHOD SUPER->CONSTRUCTOR.
       me->X = x.
       me->Y = y.
       me->ALTURA = altura.
       me->LARGURA = largura.
     ENDMETHOD.

     METHOD OBJETO.

       WRITE: / 'X=', me->X, ' Y=', me->Y,  ' Altura=', me->ALTURA, ' Largura=', me->LARGURA.
     ENDMETHOD.

endclass.

* Cria classe coordenadas

class coordenadas DEFINITION INHERITING FROM PONTOS.

PUBLIC SECTION.

METHODS achaCentro IMPORTING ret TYPE REF TO RETANGULO
                   RETURNING VALUE(pt) TYPE REF TO PONTOS.

ENDCLASS.

class COORDENADAS IMPLEMENTATION.

      METHOD ACHACENTRO.
        me->X = RET->X + RET->LARGURA / 2.
        me->Y = RET->Y + RET->ALTURA  / 2.
        CREATE OBJECT PT
           EXPORTING
              X = me->X
              Y = me->Y.
        ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

* Instancia objeto

DATA pnt TYPE REF TO PONTOS.
CREATE OBJECT pnt
   EXPORTING
      X = 10
      Y = 15.

DATA ret1 TYPE REF TO RETANGULO.
CREATE OBJECT ret1
      EXPORTING
          X       = pnt->X
          Y       = pnt->Y
          ALTURA  = 150
          LARGURA = 200.

* Objetos são Mutaveis

MOVE 300 TO RET1->ALTURA.
MOVE 400 TO RET1->LARGURA.

RET1->OBJETO( ).

* Aliasing
* Utiliza método com efeito Overload feito no Workaround acima
DATA ret2 TYPE REF TO RETANGULO.
CREATE OBJECT RET2.

RET2 = RET1.

WRITE : / .
WRITE : / 'Aliasing:'.
WRITE : /  'Objeto2:'.

RET2->OBJETO( ).

* Altera objeto ret1
MOVE 100 TO RET1->ALTURA.
MOVE 200 TO RET1->LARGURA.

WRITE : / .
WRITE : / 'Alterando Objeto1 e afetendo Objeto2'.
WRITE : / 'Objeto2:'.

RET2->OBJETO( ).

* cria objeto de coordenadas
* passando e retornando objetos
* achando o centro do retangulo

DATA Coord TYPE REF TO COORDENADAS.
CREATE OBJECT COORD.

COORD->ACHACENTRO( RET1 ).

WRITE : / .
WRITE : / 'Centro do Retangulo:'.
WRITE : / 'Coordenadas X:', COORD->X.
WRITE : / 'Coordenadas Y:', COORD->Y.

Já sabemos que é legal um método invocar o outro método, e vimos vários exemplos destes. Mas também é legal um método invocar ele mesmo. Pode não ser óbvio  o por que é isto é necessário, mas acaba por ser uma das coisas mais interessantes  que um programa pode fazer e este tipo de técnica é chamada de recursão.

Recursão é o processo de repetir itens de uma forma auto similar. Por exemplo, quando as superfícies dos dois espelhos são exatamente paralela uma com a outra as imagens que ocorrem aninhadas são uma forma de recursividade infinita. O termo tem uma variedade de significados específicos para uma variedade de disciplinas que vão desde a lógica linguística. A aplicação mais comum da recursividade é em matemática e ciência da computação, no que se refere a um método de definição de funções em que a função a ser definida é aplicada dentro de sua própria definição.

Mas é preciso planejar bem as recursões pois se houver erros em sua lógica, assim como os laços as recursões também podem ser infinitas.

Exemplo:

Neste exemplo vamos programar uma contagem regressiva  utilizando um método recursivo.

Java

public class Recursiva
 {
  static void contagemRegressiva (int n )
  {
    if ( n == 0 )
    {
      System.out.println("Explosão!!!");
    }
    else
    {
      System.out.println(n);
      contagemRegressiva (n-1);
    }
  }
  public static void main(String[] args)
  {
   int contagem = 10;
   System.out.println("Iniciando contage regressiva");
   contagemRegressiva(contagem);
  }
}

C++

#include "stdafx.h"
#include <iostream>
using namespace std;

static void contagemRegressiva(int n)
 {
  if (n == 0)
  {
    cout << "Explosão!!!" << endl;
  }
  else
  {
    cout << n << endl;   contagemRegressiva(n - 1);
  }
 }

int _tmain(int argc, _TCHAR* argv[])
 {
  int contagem = 10;
  cout << "Iniciando contagem regressiva." << endl;
  contagemRegressiva(contagem);
  system("pause");
  return 0;
 }

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DesenvolvimentoAberto
 {
     class Program
     {
         static void contagemRegressiva (int n )
      {
        if ( n == 0 )
        {
               Console.WriteLine("Explosão!!!");
        }
        else
        {
               Console.WriteLine(n);
               contagemRegressiva (n-1);
        }
      }

         static void Main(string[] args)
         {
             int contagem = 10;
             Console.WriteLine("Iniciando contagem regressiva");
             contagemRegressiva(contagem);
             Console.ReadKey();
         }
     }
 }

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# recursivo.py
# Importa OS
import os

# Limpa a tela
os.system("clear")

def ContagemRegressiva (n):
     if (n==0):
         print"Explosão!!!"
     else:
         print n
         ContagemRegressiva(n-1)

contagem = 10
print "Inciando contagem regressiva"
ContagemRegressiva (contagem)

raw_input()

Abap

*&---------------------------------------------------------------------*
*& Report  ZRECURSIVO
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Metodos Recursivos
*&---------------------------------------------------------------------*

REPORT  ZRECURSIVO.
PARAMETERS :CONTAGEM TYPE i.

WRITE : / 'Iniciando contage regressiva.'.

PERFORM CONTAGEM_REGRESSIVA USING CONTAGEM.

FORM CONTAGEM_REGRESSIVA USING N TYPE i.
  IF ( N EQ 0 ).
    WRITE : / 'Explosão!!!'.
  ELSE.
    WRITE : / N.
    N = N - 1.
    PERFORM CONTAGEM_REGRESSIVA USING  N.
  ENDIF.
ENDFORM.

SAP – Database e o Dicionário ABAP

Publicado: 28 de fevereiro de 2014 em Abap

O Dicionário ABAP (SE11) permite centralizar a definição e a gestão de tipos:

  • Criação de elementos de dados definidos pelo usuário, estruturas e tipos de tabela.
  • Definição de tabelas, índices e visualizações.
  • Definição dos serviços que suportam o desenvolvimento do programa.
  • O bloqueio de tabela e liberação de bloqueio.

Definindo a ajuda de entrada (F4)  e a ajuda de campo (F1)  .

Mudanças no Dicionário ABAP entram imediatamente em vigor para os programas que usam o que os elementos do dicionário.

sap-data-objects

Definição

Três tipos de dados podem ser definidos:

  • Elemento de dados (Data Element)
  • Estrutura (Structure)
  • Tipos de Tabela (internal tables)

Type Group

A opção tipo de grupo (Type Group) é fornecida pelo dicionário e está principalmente lá para apoiar o desenvolvimento antigo. (tipo de grupos estavam disponíveis antes de tipos de dados serem suportados.) Tipo de Grupos agora são usados ​​principalmente para definir constantes não-orientadas a objetos.

Domain

Dados de domínio (Domain) estão disponíveis para apoiar a definição de tipos de dados, mas os dados de domínio não são acessível em um programa ABAP.

Tables

Tabelas consistem em colunas (campos) e linhas (entradas). No ABAP tabelas do Dicionário têm nomes e atributos gerais, como classe de entrega e manutenção de autorização. A tabela tem um ou mais campos-chave, designados como a chave primária. campos da tabela são geralmente baseados em elementos de dados que se baseiam em dados do domínio. Campos de tabela podem ser digitados sem referência a um elemento de dados (Foreing Key). Neste caso, o campo é dito ser digitado direto. Tabelas têm configurações técnicas que regem a forma como o sistema deve otimizar o armazenamento de dados e acessar a tabela.

sap-data-field

Tabelas Transparentes

Quando uma tabela é definida no dicionário ABAP, ela é uma tabela transparente. Quando a tabela transparente é ativada, ela é criada no DBMS subjacente. A tabela específica do DBMS tem o mesmo nome que o nome da tabela transparente no ABAP Dictionary. Os tipos de campo na tabela DBMS específicas são convertidos para qualquer que seja a definição do tipo de dados apropriado no DBMS. Os elementos do quadro (por exemplo, campo, etc) subjacente podem ser alterados conforme necessário. A tabela transparente no Dicionário ABAP é a representação independente de banco de dados da tabela subjacente, e é usada em programação ABAP.

sap-data-table

Open SQL

Instruções SQL abertas(Open SQL) em programa ABAP são convertidas em instruções específicas do banco de dados SQL pela interface de banco de dados.

É possível ter acesso ao banco de dados com SQL nativo, mas o código é então do banco de dados específico e menos transportável.

Muitas declarações Open SQL se espelham nas instruções de SQL “tradicionais”, mas com diferenças sutis e refinamentos.

Open SQL contém apenas manipulação de Dados por comandos de linguagem (DML). As operações são feitas utilizando o Dicionário ABAP.

Quatro comandos Open SQL básico:

  • SELECT – seleciona dados em uma tabela.
  • UPDATE – altera dados em uma tabela.
  • INSERT –  insere dados em uma tabela.
  • DELETE – apaga dados em uma tabela.

Sap Luw

SAP LUW (unidade lógica de trabalho) é um conjunto de alterações lógicas para um banco de dados onde todas pertencem uma a outra. O LUW é feito de acordo com o princípio de “tudo ou nada”,  se sequência inteira não pode ser terminada, a operação será revertida (Rollback).

Operação Commit é cometida implicitamente ou via instrução ABAP COMMIT WORK. Rollback é feito via instrução ROLLBACK WORK.

sap-luw

Necessidade do LUW

SAP ERP possui arquitetura cliente-servidor de três camadas. No servidor de aplicação, as aplicações do usuário final são executadas através de processos de trabalho. Trabalho de vários processos em vigor simultaneamente. Ao particionar operações de banco de dados em LUWs, a integridade do banco de dados pode ser mantida e um processo de trabalho pode acessar e liberar recursos de banco de dados rapidamente.

Database Locking

Para evitar alterações simultâneas em tabelas de banco de dados a partir de vários programas, os bloqueios são usados.

Exemplo: o comando select campo (single) da tabela DBTABLE FOR UPDATE irá bloquear o registro selecionado na expectativa de uma mudança pendente. No final do LUW, o bloqueio é libertada.

Para bloquear um recurso para uma sequência mais prolongada, o sistema mantém uma tabela de bloqueio global que gerencia as travas definidas programaticamente para vários recursos.

Para definir o bloqueio: lockobject ENQUEUE.

Para liberar o bloqueio: lockobject DEQUEUE.

SY-SUBRC é definida após todas as operações de banco de dados. 0 = conclusão bem sucedida. Outros valores indicam diferentes tipos de erro, sy-dbcnt está definido para o número de registros afetados pela última operação.

A maioria das tabelas de sistema contêm um campo MANDT para designar um cliente. Comandos OPEN SQL  por padrão são feitos apenas para o cliente atual. Para substituir esse comportamento adicione a cláusula CLIENT SPECIFIED ao comando.

JOINS

É possível unir tabelas em uma consulta.

Sintaxe:

SELECT * FROM table1 INNER JOIN table2 ON table1~field = table2~field WHERE <condition>.

Chamado link em ABAP. Se um JOIN é feito em um programa, é um vínculo dinâmico. Links pré-existentes, links estáticos, são definidos no Dicionário ABAP. Estes são chamados de Views.

Revisão e Exemplos:

Comandos Open SQL tabelas transparentes: https://desenvolvimentoaberto.wordpress.com/2014/02/20/select-e-insert-abap/

Comandos Open SQL tabelas Internas: https://desenvolvimentoaberto.wordpress.com/2014/02/20/internal-tables-abap/

Modelo de Dados do Dicionário ABAP: https://desenvolvimentoaberto.wordpress.com/2014/02/20/netweaver-flight-model-introducao-ao-database-mini-sap/

Exception – Try … Catch – Raise – Abap

Publicado: 26 de fevereiro de 2014 em Abap

A Classe Exception, representa os erros que ocorrem durante a execução de aplicativos. Todas as classes de exceção devem herdar da superclasse CX_ROOT  e uma de suas classes subclasses:

  • CX_STATIC_CHECK
  • CX_DYNAMIC_CHECK
  • CX_NO_CHECK

Todas as classes de exceção devem começar com o prefixo CX_. Elas são geralmente definidas globalmente no Class Builder do ABAP Workbench. Classes de exceção locais podem, no entanto, também ser definidas.

Execptions

Um erro de aplicativo é um erro de tempo de execução que não pode necessariamente ser evitado escrevendo um código livre de erros.

Erros de tempo de execução podem ocorrer por uma variedade de razões. No entanto, nem todos os erros devem ser tratados como exceções em seu código.

Em alguns casos, um erro de programa pode refletir uma condição de erro esperada ou de rotina. Neste caso, você pode querer evitar o uso de tratamento de exceção para lidar com o erro do programa.

Em outros casos, um erro de programa reflete uma condição de erro inesperado que pode ser manipulado em seu código. Por exemplo, mesmo que você tenha verificado para garantir que existe um arquivo, ele pode ser excluído antes que você possa abri-lo, ou ele pode estar corrompido.

A falha do sistema é um erro de tempo de execução que não podem ser tratada por meio de programação de uma maneira significativa. Por exemplo, qualquer método pode lançar uma exceção OutOfMemory se o Runtime é incapaz de alocar memória adicional

TRY … CATCH

Um modelo de tratamento de exceção que se baseia na representação de exceções como objetos, e a separação de código de programa e o código de tratamento de exceções em blocos TRY e blocos CATCH. Pode haver um ou mais blocos catch, cada um projetado para lidar com um determinado tipo de exceção, ou um bloco projetado para capturar uma exceção mais específica que outro bloco.

Exemplo:

Neste exemplo criamos uma classe para nosso erro herdada da classe CX_DYNAMIC_CHECK e usamos o comando TryCatch para manipular o erro e exibir uma mensagem mais amigável para o usuário.

Abap

*&---------------------------------------------------------------------*
*& Report  ZEXCECAO
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Exceções
*&---------------------------------------------------------------------*

REPORT  ZEXCECAO.

CLASS CX_MinhaExcecao DEFINITION INHERITING FROM CX_DYNAMIC_CHECK.

PUBLIC SECTION.

METHODS : CONSTRUCTOR IMPORTING pvalor TYPE p.

DATA VALOR TYPE p DECIMALS 2.

ENDCLASS.

CLASS CX_MinhaExcecao IMPLEMENTATION.

METHOD CONSTRUCTOR.
CALL METHOD SUPER->CONSTRUCTOR( ) .
VALOR = pvalor.
ENDMETHOD.

ENDCLASS.

start-of-selection.

DATA ERRO         TYPE REF TO CX_MinhaExcecao.
DATA saldo        TYPE p DECIMALS 2.
DATA saque        TYPE p DECIMALS 2.
DATA insuficiente TYPE p DECIMALS 2.

* Efetua Um deposito na conta
WRITE : / 'Deposito de: R$ 500,00'.
saldo = 500.

* Tenta efetuar um saque
PERFORM SAQUE.

FORM SAQUE.
  try.
    " Efetua um saque na conta
    WRITE : /   'saque de: R$ 1000,00'.
    saque =  1000.

    if ( saque LT saldo ).
      saldo = saldo - saque.
    else.
      insuficiente = saque - saldo.
      RAISE EXCEPTION TYPE CX_MinhaExcecao
            EXPORTING
                 PVALOR = Insuficiente.
    ENDIF.

  catch CX_MinhaExcecao into ERRO.
    " Tenta efetuar um saque
    WRITE: / 'Desculpe mas seu pedido de saque ultrapassa o seu saldo em: ', ERRO->VALOR.
  ENDTRY.
ENDFORM.

Classes – Interfaces – Abap

Publicado: 25 de fevereiro de 2014 em Abap

Os objetos definem sua interação com o mundo exterior através dos métodos que eles expõem. Métodos formam a interface do objeto com o mundo exterior; os botões na parte frontal do seu aparelho de televisão, por exemplo, são a interface entre você e a fiação elétrica do outro lado do seu invólucro de plástico. Você aperta o botão “Power” para ligar e desligar a televisão.

Na sua forma mais comum, uma interface é um conjunto de métodos relacionados com corpos vazios

A implementação de uma interface permite que uma classe se torne mais formal sobre o comportamento que promete proporcionar. Interfaces formam um contrato entre a classe e o mundo exterior, e este contrato é imposto em tempo de compilação.

Se sua classe reivindica implementar uma interface, todos os métodos definidos por essa interface deve aparecer em seu código-fonte antes da classe ser compilada com sucesso.

Em ABAP  a palavra chave interface é realmente levada ao pé da letra, obrigando o programador a referenciar a interface na instrução entre o objeto e o método.

Sintaxe:

CALL METHOD Objeto->Interface~Método.

Lembrando que a interface obriga a classe na qual foi implementada a cumprir o que nela foi declarado. Caso não cumpra o determinado pela interface obterá o seguinte erro de compilação:

Erro: Implementention missing for method “Interface~Method”.

Conceito de interfaces

  • Não pode ser instanciada.
  • Só pode possuir assinaturas de métodos de instância, públicos e abstratos (sem corpo).
  • Não pode possuir métodos concretos (com corpo), nem métodos estáticos.

Uso Comum de Interface

Já que sabemos que os objetos Abap são baseados em C++ e Java, vamos fazer uma curta analogia para que você entenda perfeitamente o uso de interfaces. As classes Abap separam a implementação da definição, assim como C++, mas também assim como Java não permitem heranças múltiplas.

Na linguagem de programação C++ pode se utilizar uma interface abstrata, mas este uso não é muito comum, pois a convenção de classes C++ já contempla que a interface seja separada da implementação na criação da própria classe, utilizando arquivos diferentes (.h e .cpp). Além da linguagem C++ permitir múltiplas heranças tornando raro a necessidade do uso de interfaces abstratas.

Java e Abap utilizam a interface pois não permitem múltiplas heranças, então a interface se torna necessária para criar um efeito deste tipo, por exemplo, imagine que temos a classe Casa e queremos que esta classe herde as classes Portas e Janelas, isto não será possível em Java e Abap, mas é possível em C++.

Para garantir que teremos os métodos paras portas e janelas na classe Casa, precisamos utilizar a interface Portas e a Interface Janelas, ainda não garantindo como em C++ os tipos de portas e janelas já que as interfaces são abstratas e não métodos concretos, Mas este recurso permite que a classe Casa tenha obrigatoriamente, portas e janelas de qualquer tipo.

Este também é o motivo de uso de uma interface abstrata em C++, quando queremos métodos abstratos para uma classe dizendo que você permite portas e janelas de qualquer tipo. Nota-se assim que C++ é uma linguagem mais flexível em termos de recursos na criação de objetos

Exemplo:

Neste exemplo simulamos um programa de I/O de arquivos, criamos uma interface contendo os métodos obrigatórios para qualquer classe, que reivindicar a interface:

Abap

*&---------------------------------------------------------------------*
*& Report  ZINTERFACE
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Interfaces
*&---------------------------------------------------------------------*

REPORT  ZINTERFACE.

* Declara Interface

INTERFACE Acao.

   METHODS :
          ABRE   IMPORTING ARQUIVO TYPE STRING,
          GRAVA  IMPORTING ARQUIVO TYPE STRING,
          DELETA IMPORTING ARQUIVO TYPE STRING.

ENDINTERFACE.

* Declara Classe

CLASS ARQUIVO DEFINITION.

   PUBLIC SECTION.

      INTERFACES ACAO.

ENDCLASS.

* Declara Implementação da Classe

CLASS ARQUIVO IMPLEMENTATION.

   METHOD ACAO~ABRE.

      " ... Implementa método para abrir o arquivo.

      WRITE: / 'Arquivo:', ARQUIVO, 'em uso'.

   ENDMETHOD.

   METHOD ACAO~GRAVA.

      " ... Implementa método para gravar o arquivo.

      WRITE: / 'Arquivo:', ARQUIVO, 'Gravado com sucesso'.

   ENDMETHOD.

   METHOD ACAO~DELETA.

      " ... Implementa método para deletar o arquivo.

      WRITE: / 'Arquivo:', ARQUIVO, 'Deletado com sucesso'.

   ENDMETHOD.

ENDCLASS.

* Cria Objetos

START-OF-SELECTION.
DATA ARQ1 TYPE REF TO ARQUIVO.
CREATE OBJECT ARQ1.

ARQ1->ACAO~ABRE( EXPORTING ARQUIVO = 'Texto.txt' ).
ARQ1->ACAO~GRAVA( EXPORTING ARQUIVO = 'Texto.txt' ).
ARQ1->ACAO~DELETA( EXPORTING ARQUIVO = 'Texto.txt' ).

* ou

CALL METHOD ARQ1->ACAO~ABRE( EXPORTING ARQUIVO = 'Texto.txt' ).
* ...

Classes – Inheritance e Override – Abap

Publicado: 25 de fevereiro de 2014 em Abap

Inheritance (herança)

Programação orientada a objetos permite que classes possam herdar estados e comportamentos comuns usados de outras classes. Neste exemplo, bicicleta torna-se agora a superclasse de MountainBike. Na linguagem de programação, cada classe é permitido ter uma superclasse direta, e cada superclasse tem o potencial para um número ilimitado de subclasses.

Override

Métodos Override (substituição), em programação orientada a objeto, é um recurso de linguagem que permite que uma subclasse ou classe filha possa fornecer uma implementação específica de um método que já é fornecido por uma de suas superclasses ou classes pai.

A implementação Override das subclasses substitui a implementação na superclasse, fornecendo um método que tem o mesmo nome, mesmos parâmetros ou assinatura, e mesmo tipo de retorno como o método na classe pai.

Final e Abstract

Abap possui o conceito de classes e métodos finais, uma classe final não pode ter uma subclasse. Um método final não pode ser redefinido em uma subclasse. Eles concluem uma árvore de herança.

Um método abstrato é definido em uma classe abstrata e não pode ser implementado na classe. Em vez disso, ele é implementado em uma subclasse da classe. Classes abstratas não podem ser instanciadas.

Redefinition

É a instrução na qual cria um método override. A implementação da redefinição na subclasse obscurece a implementação original na superclasse.

Exemplo:

Utilizando o exemplo de classes anterior onde definimos e implementamos a classe ZBICICLETA no Class Builder vamos criar uma subclasse desta superclasse, para isto precisamos modificar o parâmetro da classe que por default no R/3 é marcado como uma classe final, siga os passos abaixo:

  1. Entre no Class Builder,  trasação SE24.
  2. Escolha a classe que criamos anteriormente ZBICICLETA e clique no botão Change.
  3. Na aba Properties, desmarque a opção Final, use como referencia a imagem abaixo:

FinalClass

Neste exemplo damos a classe BICICLETAMONTANHA todos os mesmos campos e métodos da classe bicicleta, e ainda permite que seu código se concentre exclusivamente sobre as características que a tornam única. Isso faz do código de suas subclasses fáceis de ler. Usamos métodos Override neste exemplo, para substituir o método BICICLETA da superclasse na subclasse.

No entanto, você deve tomar cuidado para documentar corretamente o estado e o comportamento que cada superclasse define, uma vez que o código não irá aparecer no arquivo de origem de cada subclasse.

Abap

*&---------------------------------------------------------------------*
*& Report  ZHERANCA
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Herança e Override
*&---------------------------------------------------------------------*

REPORT  ZHERANCA.

* Cria uma herança da classe ZBICICLETA

CLASS BICICLETAMONTANHA DEFINITION INHERITING FROM ZBICICLETA.

PUBLIC SECTION.

DATA:   marchas       TYPE STRING,
        amortecedores TYPE STRING,
        garrafa       TYPE STRING,
        gps           TYPE STRING.

METHODS BICICLETA REDEFINITION.

ENDCLASS.

CLASS BICICLETAMONTANHA IMPLEMENTATION.

METHOD BICICLETA.

CALL METHOD super->BICICLETA.

WRITE : / ' Marchas:', marchas.
WRITE : / ' Amortecedores:', amortecedores.
WRITE : / ' Garrafa:', garrafa.
WRITE : / ' Gps:', gps.

ENDMETHOD.

ENDCLASS.

* Cria Instancia da Classe Herdada
START-OF-SELECTION.
DATA BIKE1 TYPE REF TO BICICLETAMONTANHA.
CREATE OBJECT BIKE1.

* Propriedades (Atributos) da classe ZBICICLETA.

MOVE 'TRACK X100'       TO BIKE1->MODELO.
MOVE 'Fibra de Carbono' TO BIKE1->QUADRO.
MOVE 'Disco'            TO BIKE1->FREIOS.
MOVE 'Aluminio'         TO BIKE1->RODAS.

* Propriedades (Atributos) da classe BICICLETAMONTANHA

MOVE '18'              TO BIKE1->MARCHAS.
MOVE 'PRO III S'       TO BIKE1->AMORTECEDORES.
MOVE 'Aluminio 500 ml' TO BIKE1->GARRAFA.
MOVE 'Discovery PRO'   TO BIKE1->GPS.

* chama método OVERRIDE.

WRITE : / 'Bicicleta Montanha é uma herança da classe Bicicleta', / .

CALL METHOD BIKE1->BICICLETA.

SAP – Classes – Abap

Publicado: 24 de fevereiro de 2014 em Abap

Orientação a Objeto é geralmente considerada superior à programação procedural devido ao encapsulamento de dados com  funcionalidades relacionadas. ABAP Objects é conceitualmente semelhante as linguagens como C++ e Java, no entanto as duas linguagens estão entre as mais utilizadas atualmente e evoluem em alta velocidade, o mesmo não acontece com ABAP OO, podemos dizer que na pratica a diferença  na construção de classes é uma sintaxe um pouco mais pesada e a não permissão de criar métodos Overload dentro de uma classe, exemplo, não podemos ter um construtor vazio e um construtor utilizando parâmetros ao mesmo tempo.

Mas o ponto mais impactante entre o desenvolvimento ABAP OO e outras línguas orientadas a objeto segundo a própria SAP, “As instruções ABAP utilizadas para processamento de listas ainda não estão totalmente disponíveis em ABAP Objects“. Linguagens orientadas a objeto utilizam de forma intensa objetos de listas que são conhecidos como coleções ou Containers para manipular objetos, o ABAP possui algumas destas classes entretanto suas funcionalidades são precárias e não podem ser comparadas com os frameworks de coleções como STL para C++ e JCF para Java que praticamente definem conceitos para a manipulação de objetos.

Deste modo é comum mesmo em programas disponibilizados pela própria SAP, encontrarmos instruções consideradas procedurais como FORM e PERFORM entre outras sendo utilizada em conjunto com objetos, caso queira uma completa programação orientada a objeto como acontece em outras linguagens de programação, enquanto a SAP não disponibiliza a implementação total das coleções, você deve herdar as classes de coleções e estender as funcionalidades disponibilizadas pela SAP. Algumas construções da linguagem ABAP são consideradas obsoletas e ainda são suportadas em ABAP processual, não são permitidas em objetos ABAP.

ABAP Objects suporta:

  • Herança – uma classe compartilha a estrutura e comportamento com outra.
  • Polimorfismo – objetos diferentes (mas relacionados) têm a mesma interface de comunicação.
  • Eventos – respondem quando provocados. Os objetos podem disparar um evento.

Classe

A definição da estrutura e funcionalidade de um objeto. Define se o objeto de dados irá conter (atributos) e funcionalidades relacionadas (métodos).

Sintaxe da classe ABAP divide a definição de classe (contendo declarações de atributos e definições de interface do método) e a implementação da classe (definições de funcionalidade do método).

Sintaxe:

CLASS classe DEFINITION.

ENDCLASS.

CLASS classe IMPLEMENTATION.

ENDCLASS.

Uma classe pode ser definida localmente ou globalmente, usando a transação Class Builder SE24.

Objeto

A instanciação de uma classe, o armazenamento de dados reais e ou permitir a execução do método.

A definição de classe pode definir o seguinte: tipos, constantes, objetos de dados (atributos) e interfaces de método.

Os itens podem ser designados como:

  • PUBLIC (público) disponível a partir de fora do objeto.
  • PRIVATE (privada), disponível somente dentro do próprio objeto.
  • PROTECTED (protegida) disponível dentro do próprio objeto e suas sub classes.
  • STATIC (estático) é um atributo cujo valor é compartilhado entre todos os objetos em uma classe e não é dependente de instanciação, em ABAP a palavra chave Static não é utilizada e é referida como sendo “da classe” ou seja dados da classe, métodos da classes.

Um atributo público pode ser designado como somente leitura. Dentro da definição de classe, o setor público deve vir antes do setor privado.

Um atributo estático muitas vezes usado para coisas como contadores ocorrência de objeto e como os dados pertencem à classe e é compartilhado entre os objetos, ele é declarado como CLASS-DATA.

Método

  • Na definição de classe, a definição do método indica um método de interface.
  • Métodos podem ser designados como públicos ou privados.
  • Um método privado só pode ser chamado de dentro de outro método da classe.
  • Métodos de classe podem ser definidos e estes métodos só podem acessar atributos estáticos.
  • Métodos de classe podem ser invocados usando o nome da classe ou um objeto da classe.
  • Um objeto não precisa ser instanciado para chamar uma método de classe.
  • Código para a funcionalidade de um método é colocado na implementação da classe.
  • Os nomes de parâmetros e tipos não estão listados, pois eles já foram declarados na definição da classe.

Parâmetros do método:

IMPORTING – Parâmetros importador de entrada, usado para transferir dados de um método. Pode ser designado como opcional. Pode ter um valor padrão especificado.

EXPORTING – Parâmetros exportadores de saída. Parâmetros de exportação são sempre opcionais (por padrão).

CHANGING – Mudança de combinação acima. Passado para o método a ser utilizado. Pode ser alterado. Pode ser designado como opcional. Pode ter um valor padrão especificado.

Construtor

Uma classe pode definir um método construtor chamado constructor. O método deve ter parâmetros públicos e só importadores. O construtor não é chamado explicitamente, mas é chamado implicitamente quando um novo objeto é criado. Em ABAP Objects um método construtor não pode ser sobrecarregado (Overload) utilizando um outro método construtor, entretanto é possível criar este efeito através de parâmetros opcionais.

Construtores são úteis para:

  • Inicializar os atributos de um objeto.
  • Alocação de recursos para o objeto.
  • Modificando atributos estáticos (programação).
  • Disparando outras atividades que precisam acontecer quando um novo objeto é criado.

Auto Referencia

Dentro de um método, a referência aos atributos do objeto ou outros métodos geralmente não pode ser ambígua. Em caso de ambigüidade (um parâmetro tem o mesmo nome de um atributo), você pode se referir ao objeto, seus atributos e seus métodos usando: me.

Sintaxe:

me-> nomedotributo.

DIAGRAMA DE UMA CLASSE

Classe - Diagrama

Classe – Diagrama

CLASS BUILDER – SE24

O Class Builder permite criar e manter as classes ABAP globais e interfaces. Ambos os tipos de objetos, como os tipos de dados globais, são definidos no Repositório ABAP, compondo, assim, uma biblioteca de classes central. Juntos, eles formam uma biblioteca de classe central e são visíveis em todo o sistema. Você pode exibir as classes e interfaces existentes na biblioteca de classes usando o navegador de classe.

Criando Uma Classe no Class Builder

1 –  Entre com a transação SE24.

bicicleta1

2 – Crie a Classe ZBICICLETA como na imagem acima, utilizando os mesmos parâmetros mostrados em cada janela da imagem, na ultima janela acima escolha Local Object.

bicicleta2

3 – Na aba Attributes crie os atributos MODELO, QUADRO, RODAS, FREIOS como String, utilize a imagem acima para referencia.

bicicleta3

4 – Na aba Methods, crie o método BICICLETA utilizando a imagem acima como referencia.

bicicleta4

5 – Na barra de tarefas clique em Source Code Based para ver o código fonte da classe, também é permitido altera-lo caso seja necessário.

6 – Digite o código como mostra na imagem acima para o método BICICLETA e clique em salvar, volte uma tela e clique em ACTIVATE para ativar a classe.

7 – Pronto já temos nossa classe ZBicicleta com quatro atributos e um método BICICLETA, agora entre na transação SE38 e crie um programa para nosso exemplo abaixo onde utilizaremos nossa classe.

Exemplo:

Neste exemplo instanciaremos a classe ZBICICLETA criada no Class Builder utilizando os parâmetros acima, criaremos uma nova classe chamada MOUNTAINBIKE utilizando parâmetros em seu construtor.

Obs: Para que uma classe forme um objeto completo é necessário métodos de entrada e saída. A classe abaixo ainda não contempla o conceito de métodos Getter e Setter (C++, Java e Abap) também equivalentes a propriedades em outras linguagens de programação (Delphi, C#, Python). Estes métodos são essências na manipulação dos atributos, veremos estes métodos no tópico exclusivo com o assunto métodos.

Abap

*&---------------------------------------------------------------------*
*& Report  ZLOJA
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Classes ABAP
*&---------------------------------------------------------------------*

REPORT  ZLOJA.

* Define Classe dinamicamente.

class MOUNTAINBIKE definition.

PUBLIC SECTION.

data MODELO type STRING .
data QUADRO type STRING .
data FREIOS type STRING .
data RODAS  type STRING .

methods CONSTRUCTOR IMPORTING
                        PMODELO TYPE STRING
                        PQUADRO TYPE STRING
                        PFREIOS TYPE STRING
                        PRODAS  TYPE STRING.

methods BICICLETA .

ENDCLASS.

CLASS MOUNTAINBIKE IMPLEMENTATION.

method BICICLETA.

" Minha implementação.

WRITE: / ' Bicicleta:', modelo.
WRITE: / ' Quadro:', quadro.
WRITE: / ' Rodas:', rodas.
WRITE: / ' Freios:',  freios.

endmethod.

method CONSTRUCTOR.

me->MODELO = pmodelo.
me->QUADRO = pquadro.
me->RODAS  = prodas.
me->FREIOS = pfreios.

endmethod.

ENDCLASS.

* Cria objetos Bicicleta - definidos na CLASS BUILDER.

START-OF-SELECTION.
DATA BIKE1 TYPE REF TO ZBICICLETA.
CREATE OBJECT BIKE1.

DATA BIKE2 TYPE REF TO ZBICICLETA.
CREATE OBJECT BIKE2.

* Alimenta Variáveis
* Tem uma pegadinha aqui! você já descobriu?

* Objeto Bicicleta #1
MOVE 'BMX'       TO BIKE1->MODELO.
MOVE 'Ferro'     TO BIKE1->QUADRO.
MOVE 'Ferro'     TO BIKE1->RODAS.
MOVE 'Pastilhas' TO BIKE1->FREIOS.

* Objeto Bicicleta #2
MOVE 'Caloi'        TO BIKE1->MODELO.
MOVE 'Aluminio'     TO BIKE1->QUADRO.
MOVE 'Aluminio'     TO BIKE1->RODAS.
MOVE 'Pastilhas'    TO BIKE1->FREIOS.

* Chama o metodo bicicleta

CALL METHOD BIKE1->BICICLETA.

WRITE: / .

CALL METHOD BIKE2->BICICLETA.

* Objeto criado usando o  metodo Construtor

WRITE: / .

DATA BIKE3 TYPE REF TO MOUNTAINBIKE.

CREATE OBJECT BIKE3 EXPORTING

pMODELO = 'ZX-Track'
pQUADRO = 'Fibra de Carbono'
pFREIOS = 'Disco'
pRODAS  = 'Aluminio'.

CALL METHOD BIKE3->BICICLETA.