Super:Super:AlgumaCoisa()

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Super:Super:AlgumaCoisa()

Mensagem por JoséQuintas »

Tem isso no Harbour?
Tem como escolher uma das classes herdadas superiores através de super:super ou super: ?
(escolher entre roitna da classe herdada, ou rotina que a classe herdada havia herdado de outra)

Obs. Acho que cheguei no nível 5 de herança, e precisava algo da classe do nível 4.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Super:Super:AlgumaCoisa()

Mensagem por JoséQuintas »

Não, não é pra complicar, é pra facilitar.
Por enquanto meu cadastro de mídia está assim:

Código: Selecionar todos

PROCEDURE PAUXMIDIA
   LOCAL oFrm := AUXMIDIAClass():New()
   
   IF .NOT. AbreArquivos( { "jptabel" } )
      RETURN
   ENDIF
   SELECT jptabel
   SET FILTER TO jptabel->axTabela == "MIDIA."
   oFrm:Execute()
   CLOSE DATABASES
   RETURN 

CREATE CLASS AUXMIDIAClass INHERIT AUXILIARClass
   DATA cTabelaAuxiliar INIT "MIDIA."
   END CLASS
E alguns outros cadastros genéricos estão parecidos.
Mas este, assim como outros cadastros já receberam, vai receber um método Exclui() próprio, pra verificar se o código está sendo usado antes de excluir.
Pelo menos na parte final é chamar o Super;Exclui() que pega o Exclui() da classe principal, que só pede confirmação e exclui o registro atual.

Mas se precisar de um método da classe intermediária, como fazer?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Super:Super:AlgumaCoisa()

Mensagem por JoséQuintas »

A classe que foi herdada pelo anterior é esta:

Código: Selecionar todos

CREATE CLASS AUXILIARClass INHERIT FrmCadastroClass
   DATA   cTabelaAuxiliar INIT "NAOTEM"
   METHOD Especifico( lExiste )
   METHOD TelaDados( lDigita )
   METHOD Valida( cCodigo, lShow )
   METHOD GridSelection()
   END CLASS
   
METHOD GridSelection() CLASS AUXILIARClass
   LOCAL oTBrowse, nSelect := Select(), cOrdSetFocus
   
   oTBrowse := { ;
      { "NOME",   "jptabel->axDescri" }, ;
      { "CODIGO", "jptabel->axCodigo" } }
   SELECT jptabel
   SELECT jptabel
   cOrdSetFocus := OrdSetFocus( "descricao" )
   FazBrowse( oTBrowse,, ::cTabelaAuxiliar )
   IF LastKey() != K_ESC .AND. .NOT. Eof()
      KEYBOARD jptabel->axCodigo + Chr( K_ENTER )
   ENDIF
   OrdSetFocus( cOrdSetFocus )
   SELECT ( nSelect )
   RETURN NIL

METHOD Especifico( lExiste ) CLASS AUXILIARClass
   LOCAL GetList := {}
   LOCAL maxCodigo := jptabel->axCodigo

   IF ::cOpc == "I"
      maxCodigo := "*NOVO*"
   ENDIF   
   @ Row()+1, 20 GET maxCodigo PICTURE "@K 999999" VALID iif(maxCodigo == "*NOVO*",.t.,vZeros(@maxCodigo) .AND. Val(maxCodigo) > 0 )
   Mensagem( "Digite codigo, <F9> pesquisa, <ESC> volta" )
   READ
   Mensagem()
   IF LastKey() == K_ESC .OR. ( Val(maxCodigo) == 0 .AND. maxCodigo != "*NOVO*" )
      GOTO ::nUltRec
      RETURN .f.
   ENDIF
   SEEK ::cTabelaAuxiliar + maxCodigo
   IF .NOT. ::EspecificoExiste( lExiste, Eof() )
      RETURN .f.
   ENDIF
   ::cChave := { maxCodigo }
   RETURN .t.
   
METHOD TelaDados( lDigita ) CLASS AUXILIARClass
   LOCAL GetList := {}
   LOCAL maxCodigo := jptabel->axCodigo
   LOCAL maxDescri := jptabel->axDescri
   LOCAL maxInfInc := jptabel->axInfInc
   LOCAL maxInfAlt := jptabel->axInfAlt
   
   lDigita   := iif( lDigita == NIL, .f., lDigita )
   IF lDigita
      maxCodigo := ::cChave[1]
      ::nNumTab := 1
   ENDIF
   DO WHILE .t.
      ::ShowTabs()
      DO CASE
      CASE ::nNumTab == 1
         @ Row()+1, 1  SAY "Codigo...........:" GET maxCodigo  WHEN .f.
         @ Row()+2, 1  SAY "Descricao........:" GET maxDescri  PICTURE "@!" VALID .NOT. Empty( maxDescri )
         @ Row()+2, 1  SAY "Inf.Inclusao.....:" GET maxInfInc  WHEN .f.
         @ Row()+1, 1  SAY "Inf.Alteracao....:" GET maxInfAlt  WHEN .f.
      ENDCASE
      IF .NOT. lDigita
         CLEAR GETS
         EXIT
      ENDIF
      Mensagem( "Digite campos, <F9> Pesquisa, <ESC> Sai" )
      READ
      Mensagem()
      ::nNumTab += 1
      IF LastKey() == 27
         EXIT
      ENDIF
      IF ::nNumTab > Len(::acTabName)
         EXIT
      ENDIF
   ENDDO
   IF .NOT. lDigita
      RETURN NIL
   ENDIF
   ::nNumTab := 1
   IF LastKey() == K_ESC
      RETURN NIL
   ENDIF
   IF ::cOpc == "I"
      maxCodigo := ::cChave[1]
      IF maxCodigo == "*NOVO*"
         GOTO BOTTOM
         maxCodigo := StrZero( Val( jptabel->axCodigo ) + 1, 6 )
      ENDIF   
      Inclui(.t.)
      REPLACE jptabel->axTabela WITH ::cTabelaAuxiliar, jptabel->axCodigo WITH  maxCodigo, jptabel->axInfInc WITH LogInfo()
      SKIP 0
      UNLOCK
   ENDIF
   Bloqueia(.t.)
   REPLACE jptabel->axDescri WITH maxDescri
   IF ::cOpc == "A"
      REPLACE jptabel->axInfAlt WITH LogInfo()
   ENDIF   
   SKIP 0
   UNLOCK
   RETURN NIL
   
METHOD Valida( cCodigo, lShow ) CLASS AUXILIARClass
   LOCAL lOk := .t., nRow := Row()
   MEMVAR m_Prog
   lShow := iif( lShow == NIL, .t., lShow )
   IF lShow
      @ nRow, 32 SAY EmptyValue( jptabel->axDescri )   
   ENDIF
   cCodigo := StrZero( Val( cCodigo ), 6 )
   IF .NOT. Encontra( ::cTabelaAuxiliar + cCodigo, "jptabel", "numlan" ) 
      MsgWarning( "Codigo nao cadastrado!" )
      lOk := .f.
   ENDIF
   IF lShow
      @ nRow, 32 SAY jptabel->axDescri
   ENDIF
   RETURN lOk
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Super:Super:AlgumaCoisa()

Mensagem por JoséQuintas »

E essa herda de outra que faz a navegação do cadastro, que herda de outra que faz a parte visual.
Só está separado em classes "por assunto".
Uma classe cuida do visual, outra cuida da navegação do cadastro.
Sobra para o cadastro o que é específico, como liberar acesso conforme senha, validações em geral, telas específicas, etc.

Nesse fonte dá pra eliminar ::nNumTab, já que esse cadastro não precisa de TABS pra multijanelas.
Aliás... esse é o lado ruim de classes: a compilação /w3 /es2 não consegue analisar partes inúteis.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Super:Super:AlgumaCoisa()

Mensagem por JoséQuintas »

Uma outra com algo mais:

Código: Selecionar todos

PROCEDURE PAUXPRODEP
   LOCAL oFrm := AUXPRODEPClass():New()
   
   IF .NOT. AbreArquivos( { "jpconfi", "jptabel", "jpitem", "jpnumero", "jpsenha", "jptabel", "jpreguso" } )
      RETURN 
   ENDIF   
   SELECT jptabel
   SET FILTER TO jptabel->axTabela == "PRODEP"
   oFrm:Execute()
   CLOSE DATABASES
   RETURN 

CREATE CLASS AUXPRODEPClass INHERIT FrmCadastroClass
   DATA cTabelaAuxiliar INIT "PRODEP"
   METHOD Intervalo( nLini, nColi, nOpc, mieprodep )
   END CLASS

METHOD Intervalo( nLini, nColi, nOpc, mieprodep )  CLASS AUXPRODEPClass
   LOCAL acTxtOpc := { "Todos", "Especifico" }
   LOCAL GetList := {}
   
   WAchoice( nLini, nColi, acTxtOpc, @nOpc, "Depto de produto" )
   IF nOpc == 2
      wOpen( nLini, nColi + 10, nLini + 3,  nColi + 50, "Depto de produto" )
      @ nLini + 2, nColi + 12 GET mieProDep PICTURE "@K 999999" VALID ::Valida( @mieProDep )
      Mensagem( "Digite Departamento de Produto, <F9> Pesquisa, <ESC> Sai" )
      READ
      wClose()
   ENDIF
   RETURN nOpc
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Super:Super:AlgumaCoisa()

Mensagem por JoséQuintas »

Só pra classe intermediária é que não encontrei, mas não sei se é seguro fazer isso.
Pra usar da classe principal é normal, super: funciona.

Classe principal

Código: Selecionar todos

CREATE CLASS CadastroClass
   METHOD Exclui()
   END CLASS

METHOD Exclui CLASS CadastroClass
   IF MsgYesNo( "Confirma exclusão" )
       Bloqueia(.t.)
       DELETE
       SKIP 0
      UNLOCK
   ENDIF
   RETURN NIL
Classe que recebe herança

Código: Selecionar todos

CREATE CLASSS ProdutoClass INHERIT CadastroClass
   METHOD Exclui()
   END CLASS

METHOD Exclui() CLASS ProdutoClass
   IF produto->Qtde != 0
      MsgExclamation( "Não pode excluir produto com saldo" )
      RETURN NIL
   ENDIF
   Super:Exclui()
   RETURN NIL
Classe() é a classe.
Classe():New() é o método New() da classe.
Pra passar um parâmetro pro método New(), teria que estar nele. New( 10 )
Deve ser uma das diferenças entre Harbour x xHarbour.
Não sei se poderia ser considerado erro.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Super:Super:AlgumaCoisa()

Mensagem por JoséQuintas »

Fiz um teste aqui:

O New() é a criação da classe, e o Init() a inicialização, não sei se CONSTRUCTOR afeta alguma coisa.
Mas o Init() não recebe parâmetro. Neste exemplo, ::nNumero retorna NIL, porque INIT() foi executado mas não tem parâmetro.
A não ser que alterem, somente o New() que é garantido pra iniciar com valores.

Código: Selecionar todos

#include "hbclass.ch"

PROCEDURE Main
   oClasse := TesteClass( 10 ):New()
   ? oClasse:nNumero
   RETURN
   
CREATE CLASS TesteClass
   VAR nNumero INIT 0
   METHOD Init( nNumero )
   END CLASS

METHOD Init( nNumero ) CLASS TesteClass
   ::nNumero := nNumero
   RETURN NIL
Detalhe curioso: se não iniciar a classe com New(), o método Init() não é executado.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Super:Super:AlgumaCoisa()

Mensagem por JoséQuintas »

Sobre classes intermediárias.
Encontrei a resposta nos fontes da gtwvg.

Por exemplo, separei a parte de callback da wvgwindow, e chamei de wvgCallback.
E peguei por herança na wvgwindow.

Mas o Destroy() da wvgWindow eliminava as rotinas de Callback.
Pra não duplicar código, coloquei no Destroy() da wvgWindow uma chamada pra ::wvgcallback:Destroy()

Isso permitiu chamar o método específico da classe wvgCallback.

Obs.
Por enquanto só estou tentando entender a wvg. Não tá fácil entender.
Essa separação ajuda por dividir o fonte "por assunto".
E a wvgWindow é a base pra tudo, então o fonte é extenso.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder