Saltar para o conteúdo principal
Versão: 19

Classes

Visão Geral

A linguagem 4D é compatível com o conceito de classes. Numa linguagem de programação, a utilização de uma classe permite definir um comportamento do objecto com propriedades e funções associadas.

Uma vez definida uma classe de usuário, pode instanciar objectos desta classe em qualquer parte do seu código. Cada objecto é uma instância da sua classe. A class can extend another class, and then inherits from its functions.

O modelo de classe em 4D é semelhante às classes em JavaScript, e baseado numa cadeia de protótipos.

Por exemplo, se criar criar uma classe Pessoa com a seguinte definição:

//Class: Person.4dm Class constructor($firstname : Text; $lastname : Text)
This.firstName:=$firstname
This.lastName:=$lastname Function sayHello()->$welcome : Text
$welcome:="Hello "+This.firstName+" "+This.lastName

Ou em um método, criar uma "Pessoa":

var $person : cs.Person //object of Person class  
var $hello : Text
$person:=cs.Person.new("John";"Doe")
// $person:{firstName: "John"; lastName: "Doe" }
$hello:=$person.sayHello() //"Hello John Doe"

Gestão de classes

Definição de classe

A user class in 4D is defined by a specific method file (.4dm), stored in the /Project/Sources/Classes/ folder. O nome do arquivo é o nome da classe.

Ao nomear classes, deve ter em mente as seguintes regras:

  • Um nome de classe deve estar em conformidade com as regras de nomenclatura de propriedade.
  • Nomes de classe diferenciam minúsculas de maiúsculas.
  • Não se recomenda dar o mesmo nome a uma classe e a uma tabela de base de dados, a fim de evitar qualquer conflito.

Por exemplo, se quiser definir uma classe chamada "Polígono", precisa criar o seguinte arquivo:

  • Pasta Project
    • Project
      • Sources
        • Classes
          • Polygon.4dm

Eliminação de uma classe

Para eliminar uma classe existente, pode:

  • no seu disco, remover o arquivo de classe .4dm da pasta "Classes",
  • no Explorador 4D, selecionar a classe e clicar em ou escolher Mover para Lixo a partir do menu contextual.

Utilização da interface 4D

Os arquivos de classe são automaticamente armazenados no local apropriado quando criados através da interface 4D, quer através do menu File , quer através do Explorer.

Pode criar um novo arquivo de classe para o projecto seleccionando Novo > Class... no menu 4D Developer File ou a partir da barra de ferramentas.

Também pode utilizar o atalho Ctrl+Shift+Alt+k .

Explorador

Na página de Métodos do Explorador, as classes são agrupadas na categoria Classes.

Para criar uma nova classe, pode:

  • seleccionar a categoria Classes e clicar no botão .
  • seleccionar Nova Classe... no menu de acção na parte inferior da janela do Explorer, ou no menu contextual do grupo Classes.
  • seleccionar Novo > Classe... a partir do menu contextual da página inicial do Explorador.

Suporte de código de classe

Nas várias janelas 4D (editor de código, compilador, depurador, explorador de tempo de execução), o código de classe é basicamente tratado como um método de projecto com algumas especificidades:

  • No editor de código:
    • uma aula não pode ser executada
    • uma função de classe é um bloco de código
    • Ir para a definição sobre um membro objecto procura por declarações de classe Função; por exemplo, "$o.f()" encontrará "Função f".
    • As referências de pesquisa na declaração de função de classe procura a função utilizada como membro objecto; por exemplo, "Função f" encontrará "$o.f()".
  • No Explorador e Depurador de Tempo de Execução, as funções de classe são exibidas com o \<ClassName> construtor ou \<ClassName>.\<FunctionName> formato.

Lojas de classe

As classes disponíveis são acessíveis a partir das suas class stores. Estão disponíveis duas class stores:

  • cs para class stores dos usuários
  • 4D para class stores incorporadas

cs

cs -> classStore

ParâmetroTipoDescrição
classStoreobject<-Class store de usuário para o projeto ou componente

O comando cs devolve a loja de classes de utilizadores para o projecto ou componente actual. Devolve todas as classes de usuários definidas no projecto ou componente aberto. Como padrão, apenas as classes ORDA do projecto estão disponíveis.

Exemplo

Se quiser criar uma nova instância de um objecto de myClass:

$instance:=cs.myClass.new()

4D

4D -> classStore

ParâmetroTipoDescrição
classStoreobject<-Class store 4D

O comando 4D devolve a classe store para as classes 4D incorporadas disponíveis. Fornece acesso a APIs específicas, tais como CryptoKey.

Exemplo

Se quiser criar uma nova chave na classe CryptoKey :

$key:=4D. CryptoKey.new(New object("type";"ECDSA";"curve";"prime256v1"))

Objecto de classe

Quando uma classe for definida no projeto, ela é carregada no ambiente de linguagem 4D. Uma classe é um objecto em si, de classe"Classe" . Um objecto classe tem as seguintes propriedades e função:

Além disso, um objecto de classe pode fazer referência a um objecto construtor (opcional).

Um objecto de classe é um objecto partilhado e pode por isso ser acedido a partir de diferentes processos 4D simultaneamente.

Herança

Se uma classe herdar de outra classe (ou seja, a classe estende a palavra-chave é utilizada na sua definição), a classe mãe é a sua superclasse ``.

Quando 4D não encontrar uma função ou uma propriedade numa classe, procura-a na sua superclasse; se não for encontrada, 4D continua a procurar na superclasse da superclasse, e assim sucessivamente até não haver mais superclasse (todos os objectos herdados da superclasse "Objecto").

Palavras-chave de classe

As palavras-chave 4D específicas podem ser utilizadas nas definições de classes:

  • Função <Name> para definir as funções de classe dos objectos.
  • Class constructor para definir as propriedades dos objetos.
  • A classe estende-se a <ClassName> para definir a herança.

Function

Sintaxe

Function <name>({$parameterName : type; ...}){->$parameterName : type}
// code

As funções de classe são propriedades específicas da classe. São objectos da classe 4D. Function .

No ficheiro de definição de classe, as declarações de função utilizam a palavra-chave Função , e o nome da função. O nome da função deve estar em conformidade com as regras de nomeação de propriedades.

Dica: Começar o nome da função com um caractere de sublinhado ("_") excluirá a função dos recursos de preenchimento automático no editor de código 4D. For example, if you declare Function _myPrivateFunction in MyClass, it will not be proposed in the code editor when you type in "cs. MyClass. ".

Imediatamente a seguir ao nome da função, os parâmetros da função podem ser declarados com um nome e um tipo de dados atribuídos, incluindo o parâmetro de retorno (opcional). Por exemplo:

Function computeArea($width : Integer; $height : Integer)->$area : Integer

Numa função de classe, o comando This é utilizado como instância de objecto. Por exemplo:

Function setFullname($firstname : Text; $lastname : Text)
This.firstName:=$firstname
This.lastName:=$lastname Function getFullname()->$fullname : Text
$fullname:=This.firstName+" "+Uppercase(This.lastName)

For a class function, the Current method name command returns: <ClassName>.<FunctionName>, for example "MyClass.myMethod".

No código da aplicação, as funções de classe são chamadas como métodos membros das instâncias do objeto e podem receber parâmetros se existirem. As seguintes sintaxes são suportadas:

  • utilização do operador (). Por exemplo, myObject.methodName("hello")
  • use of a "4D. Function" class member method:

Aviso de segurança de thread: Se uma função de classe não for thread-safe e for chamada por um método com o atributo "Pode ser executado num processo preemptivo":

  • o compilador não gera qualquer erro (o que é diferente dos métodos normais),
  • um erro é lançado por 4D apenas em tempo de execução.

Parâmetros

Os parâmetros da função são declarados utilizando o nome do parâmetro e o tipo de parâmetro, separados por dois pontos. O nome do parâmetro deve estar em conformidade com as regras de nomenclatura de propriedades. Os parâmetros (e tipos) múltiplos são separados por ponto e vírgula (;).

Function add($x; $y : Variant; $z : Integer; $xy : Object)

Se o tipo não for indicado, o parâmetro será definido como Variant.

You declare the return parameter (optional) by adding an arrow (->) and the return parameter definition after the input parameter(s) list. Por exemplo:

Function add($x : Variant; $y : Integer)->$result : Integer

You can also declare the return parameter only by adding : type, in which case it will automatically be available through $0. Por exemplo:

Function add($x : Variant; $y : Integer): Integer
$0:=$x+$y

A sintaxe 4D clássica para parâmetros de métodos pode ser utilizada para declarar parâmetros de funções de classe. Ambas as sintaxes podem ser misturadas. Por exemplo:

Function add($x : Integer)
var $2; $value : Integer
var $0 : Text
$value:=$x+$2
$0:=String($value)

Exemplo

// Class: Rectangle
Class constructor($width : Integer; $height : Integer)
This.name:="Rectangle"
This.height:=$height
This.width:=$width

// Function definition
Function getArea()->$result : Integer
$result:=(This.height)*(This.width)
// In a project method

var $rect : cs. Rectangle
var $area : Real

$rect:=cs. Rectangle.new(50;100)
$area:=$rect.getArea() //5000

Class constructor

Sintaxe

// Class: MyClass
// Class constructor of MyClass
// código

Uma função class constructor, que pode aceitar parâmetros, pode ser usada para definir uma classe usuário.

In that case, when you call the new() function, the class constructor is called with the parameters optionally passed to the new() function.

For a class constructor function, the Current method name command returns: <ClassName>:constructor, for example "MyClass:constructor".

Exemplo

// Class: MyClass
// Class constructor of MyClass
Class Constructor ($name : Text)
This.name:=$name
// In a project method
// You can instantiate an object
var $o : cs.MyClass
$o:=cs.MyClass.new("HelloWorld")
// $o = {"name":"HelloWorld"}

Class extends <ClassName>

Sintaxe

// Class: ChildClass Class extends <ParentClass>

A palavra-chave Class extends é utilizada na declaração da classe para criar uma classe de utilizador que é filha de outra classe de utilizador. A classe filha herda todas as funções da classe mãe.

A extensão de classe deve respeitar as seguintes regras:

  • Uma classe de usuário não pode estender uma classe incorporada (excepto as classes 4D.Object e ORDA que são estendidas por defeito para as classes de utilizador).
  • Uma classe de usuário não pode estender uma classe de usuário de outro projeto ou componente.
  • Uma classe usuário não se pode estender a si própria.
  • Não é possível estender classes de forma circular (ou seja, "a" estende "b" que estende "a").

A violação de uma regra deste tipo não é detectada pelo editor de código ou pelo intérprete, apenas o compilador e o verificam a sintaxe e, neste caso, emitem um erro.

Uma classe estendida pode chamar o construtor de sua classe pai usando o comando Super.

Exemplo

Este exemplo cria uma classe chamada Square a partir de uma classe chamada Polygon.

//Class: Square

//path: Classes/Square.4dm

Class extends Polygon


Class constructor ($side : Integer)

// It calls the parent class's constructor with lengths
// provided for the Polygon's width and height
Super($side;$side)
// In derived classes, Super must be called before you
// can use 'This'
This.name:="Square"

Function getArea()
C_LONGINT($0)
$0:=This.height*This.width

Super

Sintaxe

Super {( param{;...;paramN} )} {-> Object} 
ParâmetroTipoDescrição
parammisto->Parâmetro(s) a passar para o construtor pai
Resultadosobject<-Pai do objecto

A palavra-chave Super permite efectuar chamadas para a superclasse ``, ou seja, a classe-mãe.

Super tem dois objectivos diferentes:

  1. Dentro de um código de construtor , Super é um comando que permite chamar o construtor da superclasse. Quando utilizado num construtor, o comando Super aparece sozinho e deve ser utilizado antes da palavra-chave This ser utilizada.
  • Se todos os construtores de classe na árvore de herança não forem correctamente chamados, é gerado o erro -10748. É o programador 4D que se certifica de que as chamadas são válidas.
  • Se o comando This for chamado num objecto cujas superclasses não tenham sido construídas, é gerado o erro -10743.
  • Se Super for chamado fora do âmbito de um objecto ou num objecto cujo construtor de superclasse já tenha sido chamado, é gerado o erro -10746.
// dentro do construtor myClass
var $text1; $text2 : Text
Super($text1) //chama o construtor da superclasse com um parâmetro de texto
This.param:=$text2 // usa o segundo parâmetro
  1. No interior de uma função de membro da classe , Super designa o protótipo da superclasse e permite chamar uma função da hierarquia da superclasse.
Super.doSomething(42) //chamada a função "doSomething"  
//declarada em superclasses

Exemplo 1

Este exemplo ilustra a utilização de Super num construtor de classe. O comando é chamado para evitar a duplicação das partes do construtor que são comuns às classes Rectangle e Square .

// Classe: Rectângulo
Class constructor($width : Integer; $height : Integer)
This.name:="Rectangle"
This.height:=$height
This.width:=$width


Function sayName()
ALERT("Hi, I am a "+This.name+".")

// Definição da função
Function getArea()
var $0 : Integer
$0:=(This.height)*(This.width)
//Classe: Square

Classe extends Rectangle

Construtor da classe ($side : Integer)

// Chama o construtor da classe pai com comprimentos
// fornecidos para a largura e altura do Rectangle
Super($side;$side)
// Em classes derivadas, Super tem de ser chamado antes de
// poder usar 'This'
This.name:="Square"

Function getArea()
C_LONGINT($0)
$0:=This.height*This.width

Exemplo 2

Este exemplo ilustra a utilização de Super num método de membro da classe. Criou a classe Rectangle com uma função:

//Classe: Rectângulo

Function nbSides()
var $0 : Text
$0:="I have 4 sides"

Também criou a classe Square com uma função que chama a função da superclasse:

//Classe: Quadrado

Class extends Rectangle

Function description()
var $0 : Text
$0:=Super.nbSides()+" que são todos iguais"

Depois pode escrever num método projecto:

Parâmetros

This

Sintaxe

This -> Object
ParâmetroTipoDescrição
Resultadosobject<-Objecto actual

A palavra-chave This devolve uma referência ao objecto actualmente processado. Em 4D, ele pode ser usado em contextos diferentes.

Na maioria dos casos, o valor de This é determinado pela forma como uma função é chamada. Não pode ser definido por atribuição durante a execução e pode ser diferente de cada vez que a função é chamada.

Quando uma fórmula é chamada como método membro de um objecto, o seu This é definido como o objecto ao qual o método é chamado. Por exemplo:

$o:=New object("prop";42;"f";Formula(This.prop))
$val:=$o.f() //42

Quando se utiliza uma função construtora de classe (com a função new() ), a sua Esta está ligada ao novo objecto que está a ser construído.

//Class: ob Class Constructor  

// Create properties on This as
// desired by assigning to them
This.a:=42
// num método 4D  
$o:=cs.ob.new()
$val:=$o.a //42

Quando chamar o construtor da superclasse num construtor utilizando a palavra-chave Super , esteja atento que This não deve ser chamado antes do construtor da superclasse, caso contrário é gerado um erro. Ver este exemplo.

Em qualquer caso, This refere-se ao objecto em que o método foi chamado, como se o método estivesse no objecto.

//Class: ob Function f()
$0:=This.a+This.b

Depois pode escrever num método projecto:

$o:=cs.ob.new()
$o.a:=5
$o.b:=3
$val:=$o.f() //8

Neste exemplo, o objecto atribuído à variável $o não tem a sua própria propriedade f , herda-a da sua classe. Uma vez que f é chamado como um método de $o, o seu Este refere-se a $o.

Comandos de classe

Vários comandos da linguagem 4D permitem-lhe lidar com funcionalidades de classe.

OB Class

OB Class ( object ) -> Object | Null

OB Class devolve a classe do objecto passado como parâmetro.

OB Instance of

OB Instance of ( object ; class ) -> Boolean

OB Instância de devolve true se o objecto pertencer à classe ou a uma das suas classes herdadas, e false caso contrário.