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?
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:
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.
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!
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,
Isso me lembra: Are Text Symbols Public or Private?
http://zevolving.com/2013/02/abap-objects-access-text-from-super-class-text-symbol/
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!
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
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!
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.
sumiu os brackets do field-symbol, só alegria!