Classes em Advpl – Parte 02

Continuando de onde paramos nas classes, vamos ver agora como criar duas classes em ADVPL, onde uma classe herdará a outra. Lembrando que ambas são casses cujo fonte é escrito em ADVPL e compilado no Repositório. Posteriormente vamos ver como codificar uma classe ADVPL herdando uma classe básica la linguagem ADVPL, implementada no TOTVS Application Server.

Mais um pouco de teoria

Quando criamos uma classe em Advpl herdando outra classe em Advpl, apenas especificamos na classe filha quem é a classe pai de onde herdamos todos os métodos e propriedades. Como não há escopo restrito para os métodos, todos os métodos são virtuais (isto é, podem ser re-implementados na classe filha).

E, é claro, de dentro de um método da classe filha, podemos chamar qualquer método das classes superiores. Em ADVPL não é permitido o recurso de herança múltipla ( onde uma classe filha pode herdar mais de uma classe pai simultâneamente).

Agora um pouco de código

Vamos implementar duas classes, uma classe pai e uma classe filha herdando a classe pai, e sobrescrevendo um de seus métodos. Vamos implementar um arroz com feijão e depois brincar um pouco com ela.

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. Pode copiar e colar que funciona 😉

#INCLUDE "protheus.ch"
// Fonte de teste da classe com herança
User Function APTST2() 
Local oObj
oObj := APFILHA():New(123)
oObj:SayValue()
Return
// -----------------------------------------------------------
// Classe superior para demonstração de herança
CLASS APPAI
 DATA nValue as Integer
 METHOD New(nNum) CONSTRUCTOR
 METHOD SayValue()
ENDCLASS
// Construtor da classe pai, recebe um valor e guarda. 
METHOD New(nNum) CLASS APPAI
::nValue := nNum
Return self
// Mostra o valor guardado na tela, identificando na tela que 
// o método da classe Pai foi utilizado 
METHOD SayValue() CLASS APPAI
MsgInfo(::nValue,"Classe Pai")
Return
// -----------------------------------------------------------
// Classe Filha, herda a classe pai 
CLASS APFILHA FROM APPAI
 METHOD NEW(nNum) CONSTRUCTOR
 METHOD SayValue( lPai )
ENDCLASS
// Construtor da filha chama construtor da classe pai
METHOD NEW(nNum) CLASS APFILHA
_Super:New(nNum)
return self
// Metodo para mostrar o valor, pergunta ao operador se 
// deve ser chamado o metodo da classe pai ou não. 
METHOD SayValue() CLASS APFILHA
If MsgYesNo("Chamar a classe pai ?")
 _Super:SayValue()
Else
 MsgInfo(::nValue,"Classe Filha")
Endif
Return

Após compilar este fonte, você pode chamar a função U_APTST2 diretamente a partir do Smartclient, e deve ser apresentado na sua interface uma caixa de diálogo perguntando se você quer chamar o método da classe pai. Caso você responda sim, deve ser mostrada uma caixa de diálogo contendo o valor 123 guardado na propriedade nValue da classe pai, onde o título da janela é “Classe Pai”. Caso contrário, será mostrada uma caixa de diálogo com o mesmo valor, onde a propriedade nValue da classe pai foi acessada de dentro do método da classe filha — repare no título diferenciado das caixas de diálogo das duas implementações. Agora vamos olhar com uma lupa.

Na declaração da classe APFILHA, após o nome da classe usarmos a instrução FROM, seguido do nome da classe pai, chamada APPAI. Dada a natureza dinâmica das classes Advpl, a classe APPAI usada na herança pode estar em outro fonte / arquivo.

Para chamar um método da classe superior, usamos a palavra reservada “_Super”. Ela deve ser usada apenas dentro da implementação (corpo) de um método, e deve ser escrita exatamente assim, com as letras maiúsculas e minúsculas desta forma (esta palavra reservada é case-sensitive), e somente pode ser usada para referenciar um método do nível superior (classe pai) da herança.

No caso da herança ADVPL, a classe filha não precisa chamar explicitamente o construtor da classe pai, mas isto é uma boa prática de desenvolvimento na orientação a objetos. Como a herança das classes ADVPL permite você herdar uma classe que herda de outra classe (CLASS APNETA FROM APFILHA), caso a classe APPAI possua um método que não foi reimplementado na classe APFILHA , mas a classe APNETA quer utilizá-lo, basta esta referenciar o método usando _Super. A busca nos níveis superiores da herança é recursiva e automática para métodos e propriedades.

Onde foi parar o self ?

No exemplo de classes do post anterior, dentro da implementação dos métodos, para referenciar uma propriedade da minha instância, foi usada a variável “self”, e no exemplo atual usamos “::”. A única diferença entre eles é a grafia. A sequencia de dois caracteres dois-pontos juntos “::” é um #translate de compilação, que é traduzido para “self:”. Utilizar o “::” ao invés de “self:” é a convenção de grafia mais usual.

Conclusão

A cada passo da orientação a objeto vamos estudar um pouco mais de como ela funciona, bem como as melhores formas de tirar proveito dessa tecnologia! No próximo post sobre Classes em ADVPL vamos ver as diferenças para codificar uma classe ADVPL que herda diretamente de uma classe de objeto de interface visual da linguagem!

Até o próximo post, pessoal 😉

Anúncios

3 comentários sobre “Classes em Advpl – Parte 02

    • Ainda não .. o escopo de todos os atributos é “publico”, isto é, você pode acessá-lo por fora da classe ou em qualquer nível de herança. Com o Totvs Application Server 12, eu acredito que a orientação a Objetos no AdvPL vai ganhar algumas funcionalidades interressantes 😀

      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