Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

Estado
subtletrue
colourGreen
titletlpp - language

Composition Setup
import.css=/download/attachments/327912/newLayout.css
Portuguese
Section
Assim como em outras linguagens modernas, TLPP permite que uma aplicação estabeleça um comportamento particular para operações entre dois objetos.
Isso significa que tendo dois objetos, obj1 e obj2, por exemplo, pode-se realizar operações do tipo:
obj1 + obj2
obj1 - obj2
obj1 * obj2
obj1 / obj2
obj1 == obj2
Adicionalmente, também é possível oferecer uma string resultante quando um objeto for empregado em contexto textual, como, por exemplo, fazer um conout do objeto: conout(obj1).A sintaxe de sobrecarga reserva a palavra OPERATOR para esse propósito, sendo antecedida de ADD, SUB, MULT, DIV, COMPARE ou TOSTRING, naturalmente conduzindo à uma das sobrecargas mencionadas acima.Assim sendo, não é permitido que o nome do método seja iniciado com o prefixo "operator"Objetos em TLPP podem utilizar métodos polimórficos.

Por definição, todos os métodos em TLPP são do tipo virtual. 

Métodos redefinidos na classe filha tem a capacidade de mudar o comportamento da implementação feita na classe pai.

A redefinição é simples. Basta que a classe filha tenha um método com o mesmo nome que está na classe pai.

Nesse caso, quando o método é chamado em qualquer lugar da hierarquia de classes, ele assume o comportamento definido pelo objeto efetivamente instanciado.



Bloco de código
languagecpp
firstline1
titleSobrecargapolimorfismo.tlpp
linenumberstrue
#include "tlpp-core.th"

Class ComplexNumber
   public data a
   public data b
 namespace test.tlpp.example.polymorphism

Class A
  public method newNew()
  // Eu publicvou method create(parm1, parm2)
   public OPERATOR Add (parm1)
 responder com o nome da classe que está instanciada
  public OPERATORmethod SubinstanceOf(parm1)
 as character
 public OPERATOR Mult(parm1)
   public OPERATOR Div(parm1)
   public OPERATOR Compare(parm1)
   public OPERATOR ToString()
endclass

Method new() class ComplexNumber
Return self

Method create(parm1, parm2) class ComplexNumber
   self:a := parm1
   self:b := parm2
Return Self


// Esse será o método invocado ao executar a soma de objetos do tipo ComplexNumber
Operator Add(parm1) class ComplexNumber
   Local ret := ComplexNumber():New()
   ret:a := self:a + parm1:a
   ret:b := self:b + parm1:b
Return ret

Operator Sub(parm1) class ComplexNumber
   Local ret := ComplexNumber():New()
   ret:a := self:a - parm1:a
   ret:b := self:b - parm1:b
Return ret

Operator Mult(parm1) class ComplexNumber
   Local ret := ComplexNumber():New()
   ret:a := self:a * parm1:a - (self:b * parm1:b)
   ret:b := (self:a * parm1:b) + (self:b * parm1:a)
Return ret

Operator Div(parm1) class ComplexNumber

   Local conj := ComplexNumber():New()
   Local ret  := ComplexNumber():New()
   
   // Conjugado do denominador 
   conj:a :=   parm1:a 
   conj:b := - parm1:b

   // Multipica numerador e denominador pelo conjugado
   ret  := self * conj
   conj := parm1 * conj 


   // Divide o resultado da multiplicacao do numerador pela parte real do denominador 
   ret:a := ret:a / conj:a
   ret:b := ret:b / conj:a

Return ret

Operator Compare(parm1) class ComplexNumber
   
   If (self:a > parm1:a .OR. self:b > parm1:b)
      Return 1
   EndIf

   If (self:a < parm1:a .OR. self:b < parm1:b)
      Return -1
   EndIf

Return 0

Operator ToString() class ComplexNumber
Return cValtoChar(self:a) + " + " + cValToChar(self:b) + "i"

Function U_ComplexNumber()
   
   Local obj  := ComplexNumber():Create(1, 2)
   Local obj2 := ComplexNumber():Create(3, 4)
   Local objRet
   
   objRet := obj + obj2
   Conout(objRet)
   
   objRet := obj - obj2
   Conout(objRet)
   
   objRet := obj * obj2
   Conout(objRet)

   objRet := obj / obj2
   Conout(objRet)

   If (obj < obj2)
      conout("Eu vi que o primeiro objeto é menor do que o segundo")
   EndIf

Return

Resultado do Exemplo

4 + 6i
-2 + -2i
-5 + 10i
0.44 + 0.08i
Eu vi que o primeiro objeto é menor do que o segundo
// E eu vou perguntar de quem é a instância
  public method whoami() as character
EndClass

Class B from A
  public method New()
  public method whoami() as character
EndClass

Class C from B
  public method New()
  public method whoami() as character
EndClass

// Os construtores A, B, C
// ---------------------------------------------------

method new() class A
Return self

method new() class B
Return self

method new() class C
Return self


// O instanceOf, somente implementado em A
// ---------------------------------------------------

method instanceof() class A
Local cWho := ::whoami() // quem vai ser chamado ? 
Return cWho



// Os três whoami, cada um com o seu comportamento
// ---------------------------------------------------

method whoami() class A
Return "class A"

method whoami() class B
Return "class B"

method whoami() class C
Return "class C"


// Quando for testar, me chame assim: test.tlpp.example.polymorphism.u_test01()
// --------------------------------------------------------------------------------

Function u_test01()

  Local objA, objB, objC as Object

  // Um objeto de cada classe
  objA := A():New()
  objB := B():New()
  objC := C():New()

  // Vamos ver as respostas polimórficas?
  Conout(objA:instanceOf()) // A resposta será 'class A'
  Conout(objB:instanceOf()) // A resposta será 'class B'
  Conout(objC:instanceOf()) // A resposta será 'class C'

  /** Lembre-se que o segredo está na função polimórfica whoami **/

Return .T.
   

Resultado do Exemplo

class A
class B
class C