Classes em Advpl – Parte 01

Vamos sair um pouco da linha teórica dos posts anteriores, e entrar em outro assunto legal de desenvolvimento: A orientação a objetos, com foco no ADVPL.

Introdução

O paradigma da orientação a objetos é a melhor estratégia parar representar de forma mais fiel o mundo real do domínio de um problema em um conjunto de componentes de software. Este modelo, quando corretamente aplicado, permite um alto nível de abstração do algoritmo e uma implementação limpa, especializada e flexível, onde as classes representam a estrutura de atributos (propriedades) e sua ações (métodos).

Um pouco de teoria

Não há como abordar diretamente este tema sem antes contar um pouco das características atuais da orientação a objetos em ADVPL, ainda mais para leitores que já trabalham com OOP (Object Oriented Programming) em outras linguagens.

A orientação a objeto em ADVPL exige a prototipagem de propriedades e métodos, inclusive existem diretivas até para prototipagem das propriedades, porém dada a natureza da dinâmica do ADVPL, fazer a tipagem das propriedades é informativa, e a prototipagem é feita no fonte, e não em headers (arquivos com extensão “.ch”). A implementação dos métodos é feita no mesmo fonte onde foi feita a prototipagem, e quando um outro fonte vai consumir uma determinada classe, não existe a necessidade de refazer a prototipagem neste fonte ou usar algum #include, a resolução da existência da classe é dinâmica, isto é, realizada em tempo de execução. Isto dá bastante flexibilidade, mas o programador precisa estar atento ao que deve ser informado nas propriedades e nos parâmetros dos métodos.

Nas classes implementadas diretamente no ADVPL, todas as propriedades são públicas e permitem leitura e escrita, bem como seus métodos. Pode ser usada a herança, porem sempre herança simples, e o escopo é invariavelmente público. Você pode reimplementar métodos na herança, mas não propriedades, e existe uma forma de, dentro de um método re-implementado em uma classe filha, chamar o método da classe pai. Vamos entrar em exemplos dessa natureza, mas primeiro vêm o arroz com feijão.

Exemplo – Classe APHELLO

Partindo da premissa que você tenha acesso a um ambiente do ERP Microsiga Protheus, com um IDE / TDS para compilar código ADVPL, crie um novo fonte para testes, chamado APHELLO.PRW, acrescente-o ao seu projeto ( crie um novo apenas para testes), e entre com o código abaixo, sem copiar a numeração de linha — colocada neste exemplo apenas para facilitar a explicação do código neste post.

01. #include “protheus.ch”
02.
03. USER FUNCTION APTST()
04. Local oObj := APHello():New(“Olá mundo Advpl”)
05. oObj:SayHello()
06. Return
07.
08. CLASS APHELLO
09. Data cMsg as String
10. Method New(cMsg) CONSTRUCTOR
11. Method SayHello()
12. ENDCLASS
13.
14. METHOD NEW(cMsg) CLASS APHELLO
15. self:cMsg := cMsg
16. Return self
17.
18. METHOD SAYHELLO() CLASS APHELLO
19. MsgInfo(self:cMsg)
20. Return .T.

Após compilar este fonte, você pode chamar a função U_APTST diretamente a partir do Smartclient, e deve ser apresentado na sua interface uma caixa de diálogo contendo o texto “Olá mundo Advpl” e um botão “OK” logo abaixo.

Agora, vamos entender o que aconteceu em cada pedaço deste código:

Na linha 01, o uso do #include ‘protheus.ch’ (ou ‘totvs.ch’) possibilita a utilização das diretivas de orientação a objeto e declaração de classes, entre outras.

Na linha 03, declaramos a User Function APTST, que será a função Advpl que vai consumir a classe APHELLO e demonstrar seu uso.

Na linha 04 declaramos uma variável local (oObj), que recebe a instância da classe APTST. Para tal, realizamos uma chamada do método construtor, usando o nome da classe seguido de “()”, como se a mesma fosse uma função, porém seguido de “:” e a chamada do construtor ( NEW ), informando como parâmetro uma string, que será armazenada pelo construtor na propriedade cMsg da instância atual.

Na linha 05, chamamos o método SayHello() para a instância da classe armazenada nesta variável, havendo então o resultado de tela esperado.

Entre as linhas 08 e 12, temos o bloco de declaração ou prototipação da classe, onde declaramos a propriedade cMSg, e os métodos New() e SayHello(). Como eu já havia mencionado, eu posso informar na declaração da propriedade o tipo esperado de seu conteúdo, mas atualmente para classes em ADVPL isto é meramente informativo(*).

O funcionamento, por dentro

A implementação de cada método é similar à implementação de uma função, apenas devemos colocar o sufixo CLASS , seguido do nome da classe ao qual o método se refere. Dentro dos métodos, quando queremos fazer referência a qualquer propriedade da classe, usamos a variável “self”, que na orientação a objetos do Advpl é uma variável que contém a instância da classe em uso, o que permite por exemplo que eu tenha um parâmetro com o mesmo nome de uma propriedade e referencie ambos de formas distintas.

Uma instância de qualquer classe, armazenada em uma variável do tipo “O” (Objeto), ao ser atribuída ou ser passada como parâmetro, sempre aponta para uma referência da instância, da mesma forma que um bloco de código ou array.

O método construtor, normalmente convencionado como “New”, retorna implicitamente a instância da classe atual contida na variável “self” no escopo da instância. Cada outro método fora o construtor pode ter seu retorno próprio, da mesma forma que qualquer função escrita em ADVPL.

Conclusão

Parar um primeiro exemplo e introdução ao assunto, eu acho que até aqui já ficou legal, senão o post fica quilométrico, e esse tema será detalhado em posts subsequentes. No próximo post sobre o assunto, vamos ver — com exemplos — a criação de uma classe com herança no ADVPL.

Até o próximo post, pessoal 😉

Referências

ORIENTAÇÃO A OBJETOS. In: WIKIPÉDIA, a enciclopédia livre. Flórida: Wikimedia Foundation, 2014. Disponível em: <http://pt.wikipedia.org/w/index.php?title=Orienta%C3%A7%C3%A3o_a_objetos&oldid=40611318>. Acesso em: 1 dez. 2014.

Observações

(*) A declaração da tipagem para classes ADVPL, declaradas com CLASS … ENDCLASS atualmente é meramente informativa, porém existem classes no ADVPL, como as classes Client e Server de WebServices, onde a tipagem é consistida pela camada de funções de Framework ADVPL criadas para este fim.

Anúncios

2 comentários sobre “Classes em Advpl – Parte 01

  1. Muito obrigado pelo Post!

    Não sei se você já planejou, mas seria legal falar também de boas práticas de performance na OO em ADVPL, como as funções de “limpeza de memória”.

    Continue o bom trabalho! Já indiquei para todo mundo aqui da equipe.

    Curtido por 1 pessoa

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s