Orientação a Objetos – PROTECTED é mesmo protegido?

Se você leu o título deste post e acha que vamos falar de herança em orientação a objetos, você está enganado. Vamos desafiar seu entendimento de visibilidade de dados em orientação a objetos. Será que o que você sabe realmente é a verdade? Eu decidi escrever este post depois que vi que o que eu entendia sobre o assunto estava errado. Por que não ler isso você também?

protected featured image

Exemplo de Aplicação de MM orientado a objetos

As regras que determinam o conceito de orientação a objetos são algumas mas todas simples: classes, métodos, atributos, eventos, objetos, referências, interfaces, herança, visibilidade e praticamente nada mais. Todavia o que torna orientação a objetos tão desafiador são as inúmeras possibilidades de se resolver um problema com elegância, ou com nem tanta. Isso faz com que sempre haja espaço para novos aprendizados. Veja um exemplo de aplicação de MM abaixo.

*&---------------------------------------------------------------------*
*& Report  ZABAP_OBJECTS_PROTECTED
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zabap_objects_protected.

*----------------------------------------------------------------------*
*       CLASS lcl_material DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material DEFINITION.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING
        im_matnr TYPE mara-matnr
        im_mtart TYPE mara-mtart
        im_maktx TYPE makt-maktx.

    METHODS get_material_details RETURNING value(re_details) TYPE string.

  PROTECTED SECTION.

    DATA:
      v_matnr TYPE mara-matnr,
      v_mtart TYPE mara-mtart,
      v_maktx TYPE makt-maktx.

  PRIVATE SECTION.

ENDCLASS.                    "lcl_material DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_material IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material IMPLEMENTATION.
  METHOD constructor.
    me->v_matnr = im_matnr.
    me->v_mtart = im_mtart.
    me->v_maktx = im_maktx.
  ENDMETHOD.                    "constructor

  METHOD get_material_details.
    re_details =
    |Material: | && me->v_matnr &&
    | is : | && me->v_mtart &&
    | - Description: | && me->v_maktx.
  ENDMETHOD.                    "get_material_details

ENDCLASS.                    "lcl_material IMPLEMENTATION

START-OF-SELECTION.

  DATA vg_material_detail TYPE string.

  DATA r_material TYPE REF TO lcl_material.

  CREATE OBJECT r_material
    EXPORTING
      im_matnr = '1'
      im_mtart = 'FERT'
      im_maktx = 'Coke 2L'.

*write r_material->v_matnr. " Does not work as its protected

  vg_material_detail = r_material->get_material_details( ).
  WRITE vg_material_detail.
  NEW-LINE.

Visibilidade de dados

Mesmo que você só tenha lido alguns exemplos de orientação a objetos sabe o conceito de visibilidade de dados. É possível “esconder” dados (atributos) e funcionalidades (métodos) do “mundo externo” (outras classes) usando as sessões PROTECTED e PRIVATE (na sintaxe do ABAP). A diferença entre os dois acaba sendo que:

Tudo o que é PROTECTED  de uma classe pode ser acessado de outras classes, desde que estas sejam classes filhas da primeira.

Veja a nova classe lcl_material_finished abaixo.

*&---------------------------------------------------------------------*
*& Report  ZABAP_OBJECTS_PROTECTED
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zabap_objects_protected.

*----------------------------------------------------------------------*
*       CLASS lcl_material DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material DEFINITION.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING
        im_matnr TYPE mara-matnr
        im_mtart TYPE mara-mtart
        im_maktx TYPE makt-maktx.

    METHODS get_material_details RETURNING value(re_details) TYPE string.

  PROTECTED SECTION.

    DATA:
      v_matnr TYPE mara-matnr,
      v_mtart TYPE mara-mtart,
      v_maktx TYPE makt-maktx.

  PRIVATE SECTION.

ENDCLASS.                    "lcl_material DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_material IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material IMPLEMENTATION.
  METHOD constructor.
    me->v_matnr = im_matnr.
    me->v_mtart = im_mtart.
    me->v_maktx = im_maktx.
  ENDMETHOD.                    "constructor

  METHOD get_material_details.
    re_details =
    |Material: | && me->v_matnr &&
    | is : | && me->v_mtart &&
    | - Description: | && me->v_maktx.
  ENDMETHOD.                    "get_material_details

ENDCLASS.                    "lcl_material IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS lcl_material_finished DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material_finished DEFINITION INHERITING FROM lcl_material.

  PUBLIC SECTION.
    METHODS constructor
          IMPORTING
          im_matnr TYPE mara-matnr
          im_mtart TYPE mara-mtart
          im_maktx TYPE makt-maktx
          im_volum TYPE mara-volum.

    METHODS get_material_details REDEFINITION.

  PROTECTED SECTION.
    DATA v_volum TYPE mara-volum.

ENDCLASS.                    "lcl_material_finished DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_material_finished IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material_finished IMPLEMENTATION.

  METHOD constructor.
    super->constructor(
      im_matnr = im_matnr
      im_mtart = im_mtart
      im_maktx = im_maktx
    ).
    me->v_volum = im_volum.
  ENDMETHOD.                    "constructor

  METHOD get_material_details.

    re_details =
    |Material: | && me->v_matnr &&
    | - Description: | && me->v_maktx &&
    | is a finished material: | && me->v_mtart &&
    | Volume: | && me->v_volum.

  ENDMETHOD.                    "get_material_details
ENDCLASS.                    "lcl_material_finished IMPLEMENTATION

Instanciação

Vale a pena relembrar do conceito de instanciação. Uma classe dá forma a algo que pode ser criado diversas vezes. Cada uma destas criações são chamadas de objetos e por possuírem  a mesma forma possuem os mesmos atributos e métodos. Todavia por serem criações independentes, seus dados podem perfeitamente ser diferentes uns dos outros. A instanciação é o processo de criação de um objeto, fator que traz a enorme vantagem de independência de dados a orientação a objetos. START-OF-SELECTION.

START-OF-SELECTION.

  DATA vg_material_detail TYPE string.

  DATA r_material TYPE REF TO lcl_material.

  CREATE OBJECT r_material
    EXPORTING
      im_matnr = '1'
      im_mtart = 'FERT'
      im_maktx = 'Coke 2L'.

*write r_material->v_matnr. " Does not work as its protected

  vg_material_detail = r_material->get_material_details( ).
  WRITE vg_material_detail.
  NEW-LINE.

  DATA r_finished_material TYPE REF TO lcl_material_finished.

  CREATE OBJECT r_finished_material
    EXPORTING
      im_matnr = '2'
      im_mtart = 'FERT'
      im_maktx = 'Coke 2L (finished)'
      im_volum = '2'.

*write r_finished_material->v_volum. " Does not work as its protected

  vg_material_detail = r_finished_material->get_material_details( ).
  WRITE vg_material_detail.
  NEW-LINE.

  DATA r_other_finished_material TYPE REF TO lcl_material_finished.

  CREATE OBJECT r_other_finished_material
    EXPORTING
      im_matnr = '3'
      im_mtart = 'FERT'
      im_maktx = 'Pepsi'
      im_volum = '2.5'.

*write r_other_finished_material->v_volum. " Does not work as its protected

  vg_material_detail = r_other_finished_material->get_material_details( ).
  WRITE vg_material_detail.
  NEW-LINE.

Injeção de Dependência

Dependence Injection na minha opinião este é um termo que soa muito mais difícil do que ele realmente é. Caso um objeto precise da ajuda de outro objeto para realizar alguma ação, então uma referência ao segundo objeto pode ser usada como parâmetro de um método do primeiro. Obviamente, você deve estar imaginando que o primeiro objeto só pode pedir ajuda para o segundo objeto acessando seus componentes (atributos ou métodos) públicos, pois classes diferentes fazem parte do “mundo externo” uma da outra.

*&---------------------------------------------------------------------*
*& Report  ZABAP_OBJECTS_PROTECTED
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zabap_objects_protected.

*----------------------------------------------------------------------*
*       CLASS lcl_material DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material DEFINITION.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING
        im_matnr TYPE mara-matnr
        im_mtart TYPE mara-mtart
        im_maktx TYPE makt-maktx.

    METHODS get_material_details RETURNING value(re_details) TYPE string.

  PROTECTED SECTION.

    DATA:
      v_matnr TYPE mara-matnr,
      v_mtart TYPE mara-mtart,
      v_maktx TYPE makt-maktx.

  PRIVATE SECTION.

ENDCLASS.                    "lcl_material DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_material IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material IMPLEMENTATION.
  METHOD constructor.
    me->v_matnr = im_matnr.
    me->v_mtart = im_mtart.
    me->v_maktx = im_maktx.
  ENDMETHOD.                    "constructor

  METHOD get_material_details.
    re_details =
    |Material: | && me->v_matnr &&
    | is : | && me->v_mtart &&
    | - Description: | && me->v_maktx.
  ENDMETHOD.                    "get_material_details

ENDCLASS.                    "lcl_material IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS lcl_material_finished DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material_finished DEFINITION INHERITING FROM lcl_material.

  PUBLIC SECTION.
    METHODS constructor
          IMPORTING
          im_matnr TYPE mara-matnr
          im_mtart TYPE mara-mtart
          im_maktx TYPE makt-maktx
          im_volum TYPE mara-volum.

    METHODS get_material_details REDEFINITION.

  PROTECTED SECTION.
    DATA v_volum TYPE mara-volum.

ENDCLASS.                    "lcl_material_finished DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_material_finished IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material_finished IMPLEMENTATION.

  METHOD constructor.
    super->constructor(
      im_matnr = im_matnr
      im_mtart = im_mtart
      im_maktx = im_maktx
    ).
    me->v_volum = im_volum.
  ENDMETHOD.                    "constructor

  METHOD get_material_details.

    re_details =
    |Material: | && me->v_matnr &&
    | - Description: | && me->v_maktx &&
    | is a finished material: | && me->v_mtart &&
    | Volume: | && me->v_volum.

  ENDMETHOD.                    "get_material_details
ENDCLASS.                    "lcl_material_finished IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS lcl_material_writer DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material_writer DEFINITION.
  PUBLIC SECTION.

    CLASS-METHODS write_material
      IMPORTING
        im_material TYPE REF TO lcl_material.

ENDCLASS.                    "lcl_material_writer DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_material_writer IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material_writer IMPLEMENTATION.
  METHOD write_material.
    DATA lv_material_details TYPE string.
    lv_material_details = im_material->get_material_details( ).
    WRITE lv_material_details.
    NEW-LINE.
  ENDMETHOD.                    "write_material
ENDCLASS.                    "lcl_material_writer IMPLEMENTATION

START-OF-SELECTION.

  DATA vg_material_detail TYPE string.

  DATA r_material TYPE REF TO lcl_material.

  CREATE OBJECT r_material
    EXPORTING
      im_matnr = '1'
      im_mtart = 'FERT'
      im_maktx = 'Coke 2L'.

*write r_material->v_matnr. " Does not work as its protected

  vg_material_detail = r_material->get_material_details( ).
  WRITE vg_material_detail.
  NEW-LINE.

  DATA r_finished_material TYPE REF TO lcl_material_finished.

  CREATE OBJECT r_finished_material
    EXPORTING
      im_matnr = '2'
      im_mtart = 'FERT'
      im_maktx = 'Coke 2L (finished)'
      im_volum = '2'.

*write r_finished_material->v_volum. " Does not work as its protected

  vg_material_detail = r_finished_material->get_material_details( ).
  WRITE vg_material_detail.
  NEW-LINE.

  DATA r_other_finished_material TYPE REF TO lcl_material_finished.

  CREATE OBJECT r_other_finished_material
    EXPORTING
      im_matnr = '3'
      im_mtart = 'FERT'
      im_maktx = 'Pepsi'
      im_volum = '2.5'.

*write r_other_finished_material->v_volum. " Does not work as its protected

  vg_material_detail = r_other_finished_material->get_material_details( ).
  WRITE vg_material_detail.
  NEW-LINE.

  ULINE.
  WRITE: `Using WRITER class:`, /.
  lcl_material_writer=>write_material( r_material ).
  lcl_material_writer=>write_material( r_finished_material ).
  lcl_material_writer=>write_material( r_other_finished_material ).

Misturando todos estes conceitos

O desafio é simples: O que acontece com componentes protegido de um objeto quando tentamos acessá-lo a partir de um outro objeto da mesma classe?

Difícil entender? Veja o código abaixo para simplificar a questão. Estude cada uma das chamadas de métodos e talvez você se surpreenderá com o resultado.

*&---------------------------------------------------------------------*
*& Report  ZABAP_OBJECTS_PROTECTED
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zabap_objects_protected.

*----------------------------------------------------------------------*
*       CLASS lcl_material DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material DEFINITION.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING
        im_matnr TYPE mara-matnr
        im_mtart TYPE mara-mtart
        im_maktx TYPE makt-maktx.

    METHODS get_material_details RETURNING value(re_details) TYPE string.

    CLASS-METHODS write_material_1
      IMPORTING
        im_material TYPE REF TO lcl_material.

    CLASS-METHODS write_material_2
      IMPORTING
        im_material TYPE REF TO lcl_material.

  PROTECTED SECTION.

    DATA:
      v_matnr TYPE mara-matnr,
      v_mtart TYPE mara-mtart,
      v_maktx TYPE makt-maktx.

  PRIVATE SECTION.

ENDCLASS.                    "lcl_material DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_material IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material IMPLEMENTATION.
  METHOD constructor.
    me->v_matnr = im_matnr.
    me->v_mtart = im_mtart.
    me->v_maktx = im_maktx.
  ENDMETHOD.                    "constructor

  METHOD get_material_details.
    re_details =
    |Material: | && me->v_matnr &&
    | is : | && me->v_mtart &&
    | - Description: | && me->v_maktx.
  ENDMETHOD.                    "get_material_details

  METHOD write_material_1.
    DATA lv_details TYPE string.
    lv_details =
    |Material: | && im_material->v_matnr &&
    | is : | && im_material->v_mtart &&
    | - Description: | && im_material->v_maktx.
    WRITE lv_details.
    NEW-LINE.
  ENDMETHOD.                    "write_material_1

  METHOD write_material_2.
    DATA lv_material_details TYPE string.
    lv_material_details = im_material->get_material_details( ).
    WRITE lv_material_details.
    NEW-LINE.
  ENDMETHOD.                    "write_material

ENDCLASS.                    "lcl_material IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS lcl_material_finished DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material_finished DEFINITION INHERITING FROM lcl_material.

  PUBLIC SECTION.
    METHODS constructor
          IMPORTING
          im_matnr TYPE mara-matnr
          im_mtart TYPE mara-mtart
          im_maktx TYPE makt-maktx
          im_volum TYPE mara-volum.

    METHODS get_material_details REDEFINITION.

  PROTECTED SECTION.
    DATA v_volum TYPE mara-volum.

ENDCLASS.                    "lcl_material_finished DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_material_finished IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material_finished IMPLEMENTATION.

  METHOD constructor.
    super->constructor(
      im_matnr = im_matnr
      im_mtart = im_mtart
      im_maktx = im_maktx
    ).
    me->v_volum = im_volum.
  ENDMETHOD.                    "constructor

  METHOD get_material_details.

    re_details =
    |Material: | && me->v_matnr &&
    | - Description: | && me->v_maktx &&
    | is a finished material: | && me->v_mtart &&
    | Volume: | && me->v_volum.

  ENDMETHOD.                    "get_material_details
ENDCLASS.                    "lcl_material_finished IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS lcl_material_writer DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material_writer DEFINITION.
  PUBLIC SECTION.

    CLASS-METHODS write_material
      IMPORTING
        im_material TYPE REF TO lcl_material.

ENDCLASS.                    "lcl_material_writer DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_material_writer IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_material_writer IMPLEMENTATION.
  METHOD write_material.
    DATA lv_material_details TYPE string.
    lv_material_details = im_material->get_material_details( ).
    WRITE lv_material_details.
    NEW-LINE.
  ENDMETHOD.                    "write_material
ENDCLASS.                    "lcl_material_writer IMPLEMENTATION

START-OF-SELECTION.

  DATA vg_material_detail TYPE string.

  DATA r_material TYPE REF TO lcl_material.

  CREATE OBJECT r_material
    EXPORTING
      im_matnr = '1'
      im_mtart = 'FERT'
      im_maktx = 'Coke 2L'.

*write r_material->v_matnr. " Does not work as its protected

  vg_material_detail = r_material->get_material_details( ).
  WRITE vg_material_detail.
  NEW-LINE.

  DATA r_finished_material TYPE REF TO lcl_material_finished.

  CREATE OBJECT r_finished_material
    EXPORTING
      im_matnr = '2'
      im_mtart = 'FERT'
      im_maktx = 'Coke 2L (finished)'
      im_volum = '2'.

*write r_finished_material->v_volum. " Does not work as its protected

  vg_material_detail = r_finished_material->get_material_details( ).
  WRITE vg_material_detail.
  NEW-LINE.

  DATA r_other_finished_material TYPE REF TO lcl_material_finished.

  CREATE OBJECT r_other_finished_material
    EXPORTING
      im_matnr = '3'
      im_mtart = 'FERT'
      im_maktx = 'Pepsi'
      im_volum = '2.5'.

*write r_other_finished_material->v_volum. " Does not work as its protected

  vg_material_detail = r_other_finished_material->get_material_details( ).
  WRITE vg_material_detail.
  NEW-LINE.

  ULINE.
  WRITE: `Using WRITER class:`, /.
  lcl_material_writer=>write_material( r_material ).
  lcl_material_writer=>write_material( r_finished_material ).
  lcl_material_writer=>write_material( r_other_finished_material ).

  ULINE.
  WRITE: `Using Material Writter Methods:`, /.
  lcl_material=>write_material_1( r_material ).
  lcl_material=>write_material_2( r_material ).

  ULINE.
  WRITE: `Using Material Writter Methods using object references:`, /.

  " Seems redundant... but it's OK

  WRITE : /, 'r_material->write_material_1( r_material ).' COLOR COL_TOTAL . NEW-LINE.
  r_material->write_material_1( r_material ).

  WRITE: /, 'r_material->write_material_2( r_material ).' COLOR COL_TOTAL. NEW-LINE.
  r_material->write_material_2( r_material ).

  WRITE: /, 'r_finished_material->write_material_1( r_finished_material ).' COLOR COL_TOTAL. NEW-LINE.
  r_finished_material->write_material_1( r_finished_material ).

  WRITE: /, 'r_finished_material->write_material_2( r_finished_material ).' COLOR COL_TOTAL. NEW-LINE.
  r_finished_material->write_material_2( r_finished_material ).

  WRITE: /, 'r_other_finished_material->write_material_1( r_other_finished_material ).' COLOR COL_TOTAL. NEW-LINE.
  r_other_finished_material->write_material_1( r_other_finished_material ).

  WRITE: /, 'r_other_finished_material->write_material_2( r_other_finished_material ).' COLOR COL_TOTAL. NEW-LINE.
  r_other_finished_material->write_material_2( r_other_finished_material ).

  " Seems redundant but the call denies that
  WRITE: /, 'r_material->write_material_1( r_finished_material )' COLOR COL_NEGATIVE. NEW-LINE.
  r_material->write_material_1( r_finished_material ).

  WRITE: /, 'r_material->write_material_2( r_finished_material ).' COLOR COL_NEGATIVE. NEW-LINE.
  r_material->write_material_2( r_finished_material ).

  WRITE: /, 'r_material->write_material_1( r_other_finished_material ).' COLOR COL_NEGATIVE. NEW-LINE.
  r_material->write_material_1( r_other_finished_material ).

  WRITE: /, 'r_material->write_material_2( r_other_finished_material ).' COLOR COL_NEGATIVE. NEW-LINE.
  r_material->write_material_2( r_other_finished_material ).

  WRITE: /, 'r_finished_material->write_material_1( r_other_finished_material ).' COLOR COL_NEGATIVE. NEW-LINE.
  r_finished_material->write_material_1( r_other_finished_material ).

  WRITE: /, 'r_finished_material->write_material_2( r_other_finished_material ).' COLOR COL_NEGATIVE. NEW-LINE.
  r_finished_material->write_material_2( r_other_finished_material ).

  WRITE: /, 'r_other_finished_material->write_material_1( r_finished_material ).' COLOR COL_NEGATIVE. NEW-LINE.
  r_other_finished_material->write_material_1( r_finished_material ).  WRITE: /, 'r_other_finished_material->write_material_2( r_finished_material ).' COLOR COL_NEGATIVE. NEW-LINE.
  r_other_finished_material->write_material_2( r_finished_material ).

Saída:

protected output

 Refinando o conceito de PROTECTED

Como pode perceber pelo código acima, dados protegidos nem sempre estão protegidos assim. Por isso, vamos refinar a definição de dados e métodos protegidos dada anteriormente.

Tudo o que é PROTECTED  de uma classe pode ser acessado de outras classes, desde que estas sejam classes filhas da primeira. Isso significa que dados protegidos de um objeto SÃO PÚBLICOS para outros objetos da mesma classe ou de classes filhas.

Update 21/Janeiro/2014 – Como apontou o Custódio em comentários, o mesmo vale para componentes protegidos.

Talvez você pense que isso é uma falha do ABAP, mas se testar o mesmo exemplos em outras linguagens como Java terá exatamente o mesmo resultado.

Fonte

Disse no começo deste post que decidi escrever este post quando percebi que o que entendia não era exatamente a verdade. Eu refinei meu conceito de orientação a objetos pesquisando perguntas para responder na SCN e achei a thread “Why is this possible in ABAP Objects?“. Está aí mais um exemplo de tantos outros que provam porque é importante participar da SCN. Logo esta é mais uma prova que se você não tem cadastro na SCN ou simplesmente não participa, é um profissional SAP totalmente limitado pelo seu tempo de estudo e experiência.

Existem até outras formas de se “burlar” o conceito de PROTECTED, esta eu encontrei somente no processo de revisão deste post.

Qual era seu conceito de PROTECTED?

Agora que estudou o código de exemplo, responda: “Você melhorou o conceito que tinha sobre PROTECTED?”. Comente abaixo a resposta.

Fábio Pagoti

Formado em Sistemas de Informação pela Universidade de São Paulo. Comecei no mundo da programação com Java mas logo caí no mundo ABAP. Estagiei na Nestlé por 2 anos e foi lá onde conheci o Furlan. Depois de efetivado fui morar no Canadá por 1 ano onde pude aprender a área de testes em desenvolvimento de software. Hoje sou consultor e instrutor ABAP, amante de projetos Open Source, Wordpress, Data Mining e da esfera SAP. Siga-me no twitter: @fabiopagoti

Você pode gostar...

8 Resultados

  1. Mauricio Cruz disse:

    Li o post e os comentários no SCN. Eu tb achava que o controle era por instância, e não pela classe… Interessante que isso se replica em outras linguagens, então aposto que muita gente deve ter esse conceito de que protected vale por instância.

    Procurei um site onde eu estudava C++ para dar uma olhada, e o cara também explica direitinho: http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/ “Private members can only be accessed by member functions of the same class.”. Em momento nenhum ele fala de instância!

    Impressionante como um entendimento errado/incompleto afeta tudo que a gente lê depois sobre o tema. Ainda bem que agora sabemos a verdade! 🙂

    Valeu por compartilhar Fábio!

    • Fábio Pagoti disse:

      Tem toda razão Maurício. E mesmo sem dizer “instância” em nenhum momento eu anteriormente já associava aos objetos pois ora, eles são independentes – na maioria dos casos.

      Fica ainda mais fácil de fazer besteira caso não se crie classes com responsabilidades distintas (como a classe ‘writer’ no exemplo do post).

      Obrigado por compartilhar o link do C++!

      Abraços,

    • Fábio Pagoti disse:

      Caraca! Eu nem sabia que dava para definir text symbols em classes. Geralmente minhas classes com ALV são locais e acabo usando os do programa mesmo. Aprendi mais uma coisa. Obrigado Fawcs!

      Abraços!

  2. Fala Fabio,

    Acopanhei a discussao ontem na SCN e pra ser bem sincero achei que tava todo mundo falando um monte de abobrinha. Mas esse seu post me ajudou a entender o problema. Voce pode aproveitar o post e mudar sua definicao de PRIVATE, pois o mesmo se aplica nesse caso. Mudei o attributo v_volum de PROTECTED para PRIVATE e seu programa continua funcionando exatamente igual. Claro, porque a visibilidade PRIVATE segue o mesmo conceito de PROTECTED: por classe, nao por instancia.

    Abraco,
    Custodio

    • Fábio Pagoti disse:

      Oi Custodio! Várias mitos comentando neste post!

      Fico feliz que tenha ajudado. Para ser sincero este post na SCN soa como uma pergunta bem básica mas na verdade é algo que considero avançado dentro de orientação a objetos. Só fui perceber o problema depois da alguns comentários com código.

      Sim, você tem toda a razão no que disse: vale a mesma regra para componentes privados – eles são públicos para objetos da mesma classe.

      Abraços!

  3. Fawcs disse:

    Hoje me deu uma idéia, e se eu acessar a referencia da variavel privada?.
    O ABAP não só deixa você retornar a referencia do atributo privado, como também deixa você manipular essa variavél do lado de fora!.

    Bom, segue a brincadeira!

    REPORT zfaw_test_reference.

    CLASS lcl_teste DEFINITION.
    PUBLIC SECTION.
    METHODS:
    get_priv EXPORTING ex_priv TYPE char1,
    get_priv_by_ref EXPORTING data TYPE REF TO data.
    PRIVATE SECTION.
    DATA: priv TYPE char1 VALUE ‘2’.
    ENDCLASS.

    CLASS lcl_teste IMPLEMENTATION.
    METHOD get_priv.
    ex_priv = priv.
    ENDMETHOD.
    METHOD get_priv_by_ref.
    GET REFERENCE OF me->priv INTO data.
    ENDMETHOD.
    ENDCLASS.

    DATA: obj TYPE REF TO lcl_teste,
    data_ref TYPE REF TO data,
    char TYPE char1.
    FIELD-SYMBOLS: TYPE any.

    START-OF-SELECTION.

    BREAK-POINT.

    CREATE OBJECT obj.

    obj->get_priv(
    IMPORTING
    ex_priv = char ).
    WRITE: / ‘Before get by reference: ‘ , char.

    obj->get_priv_by_ref( IMPORTING data = data_ref ).

    ASSIGN data_ref->* TO .

    = 3.

    obj->get_priv(
    IMPORTING
    ex_priv = char ).

    WRITE: / ‘After get by reference: ‘ , char.