Mas é sensacional.
Só imaginar classe como um conjunto de funções/variáveis, pra executar determinada tarefa.
E herança seria poder modificar uma função da classe, ou adicionar recursos/variáveis, etc.
Vou mostrar um relatório de clientes transformado em classe, e depois usar a herança pra modificar esse mesmo relatório pra imprimir produtos.
É nessa última hora que vemos como a herança é simples mas poderosa.
Este fonte eu fiz tudo num só PRG. Postando aqui em blocos só pra efeito de leitura.
A chamada dos relatórios é igual pra todos
#include "hbclass.ch"
Procedure Main
use jpcadas // clientes
Do Relatorio1
Do Relatorio2
Do Relatorio3
use jpitem // produtos
Do Relatorio4
Close Databases
Return
Primeiro o relatório básico
Procedure Relatorio1
Local nLin, nPag
Set Printer To ("lixo1.txt")
Set Device To Print
nLin := 66
nPag := 0
Goto Top
Do While .Not. Eof()
If nLin > 64
@ 0, 0 Say "TITULO"
@ 0, 132-7 Say "Pag." + StrZero(nPag,3)
@ 1, 0 Say Replicate("-",132)
nLin := 3
Endif
@ nLin, 0 Say jpcadas->cdCodigo
@ nLin, pCol()+2 Say jpcadas->cdNome
@ nLin, pCol()+2 Say jpcadas->cdEndereco
nLin += 1
Skip
Enddo
Set Printer To
Set Device To Screen
Run ("notepad.exe lixo.txt")
Return
Agora transformado em funções
Procedure Relatorio2
cTxtFile := "lixo2.txt"
nLin := 66
nPag := 0
Set Printer To (cTxtFile)
Set Device To Print
Goto Top
Do While .Not. Eof()
If nLin > 64
Cabecalho(@nPag,@nLin)
Endif
Detalhe(@nLin)
Skip
Enddo
Set Printer To
Set Device To Screen
ShowRelat(cTxtFile)
Function Cabecalho(nPag,nLin)
nPag += 1
@ 0,0 Say "Titulo"
@ 0,132-7 Say "Pag."+StrZero(nPag,3)
@ 1,0 Say Replicate("-",132)
nLin := 3
Return NIL
Function Detalhe(nLin)
@ nLin, 0 Say jpcadas->cdCodigo
@ nLin, pCol()+2 Say jpcadas->cdNome
@ nLin, pCol()+2 Say jpcadas->cdEndereco
nLin += 1
Return NIL
Function ShowRelat(cTxtFile)
Run ("notepad.exe " + cTxtFile)
Return NIL
Agora transformado em classe
Note que :: se refere a variáveis/funções locais da classe, usava Self: no começo, mas com :: o código fica mais legível.
Procedure Relatorio3
Relatorio():Execute("lixo3.txt")
Return NIL
Create Class Relatorio
Data nLin
Data nPag
Data cTxtFile
Method Cabecalho()
Method Detalhe()
Method Execute()
Method ShowRelat()
EndClass
Method Cabecalho() Class Relatorio
::nPag += 1
@ 0, 0 Say "Titulo"
@ 0, 132-7 Say "Pag."+StrZero(::nPag,3)
@ 1, 0 Say Replicate("-",132)
::nLin := 3
Return NIL
Method Detalhe() Class Relatorio
@ ::nLin, 0 Say jpcadas->cdCodigo
@ ::nLin, pCol()+2 Say jpcadas->cdNome
@ ::nLin, pCol()+2 Say jpcadas->cdEndereco
Return NIL
Method ShowRelat() Class Relatorio
Run ("notepad.exe " + ::cTxtFile)
Return NIL
Method Execute(cTxtFile) Class Relatorio
Set Printer To (cTxtFile)
Set Device To Print
::cTxtFile := cTxtFile
::nLin := 66
::nPag := 0
Goto Top
Do While .Not. Eof()
If ::nLin > 64
::Cabecalho()
Endif
::Detalhe()
::nLin += 1
Skip
Enddo
Set Printer To
Set Device To Screen
::ShowRelat()
Return NIL
Agora o uso da classe com herança usada para produtos ao invés de clientes
Note que a classe nova foi criada a partir da anterior, só foi modificado o método Detalhe(), que é o que interessa modificar.
Procedure Relatorio4
RelatorioProduto():Execute("lixo4.txt")
Create Class RelatorioProduto INHERIT Relatorio
Method Detalhe()
EndClass
Method Detalhe()
@ 0, 0 Say jpitem->ieItem
@ 1, pCol()+2 Say jpitem->ieDescri
Return NIL
A principal vantagem é pegar algo que funcione e modificar somente o que interessa.
A classe de relatório funciona, então alterando só o detalhe vai continuar funcionando.
Notem como o fonte 4 ficou pequeno. É a partir daí que valeu a pena o trabalho.
A mesma classe poder ser usada pra qualquer arquivo, e qualquer layout.
Considerações:
- "#include hbclass.ch" é necessário onde se cria a classe. No fonte que apenas usa classe pronta não é necessário.
- Dentro da criação da classe é necessário colocar os nomes dos métodos
- Nos métodos, necessário colocar o nome da classe a que se refere
- Quando a classe usa alguma variável ou função dela mesma, necessário usar Self:nome ou ::nome
- No caso do último fonte, a classe herda a anterior, então a outra classe precisa estar linqueditada junto.
- Esta classe de relatório é só um simples exemplo. Não serve pra uso normal, porque faltam os títulos das colunas. Mas testei antes de postar, e todos funcionam.
Acaba sendo mais interessante do que ficar usando macros, ou funções que se complicam cada vez mais.
O fonte de classe fica mais organizado e fácil de entender, depois que se pega o jeito.