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

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:

Project folder

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.

Using 4D interface

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

.style: Integer

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: MyClass Class Constructor({$parameterName : type; ...}) // code // code
  • Class constructor to define the properties of the objects.
  • Sintaxe
  • 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.

tip

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.

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)

Valor retornado

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): Integer
$0:=$x+$y

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)->$result : Integer

Exemplo 1

// Class: Rectangle
property name : Text
property height; width : Integer

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

Exemplo 2

Este exemplo utiliza a expressão return``:

Parâmetros

Class constructor

Sintaxe

// Class: MyClass
// Class constructor of MyClass
// code

A class constructor function, which can accept parameters, can be used to define a user class.

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

Só pode haver uma função de construtor numa classe (caso contrário, é devolvido um erro). Um construtor pode utilizar a palavra-chave Super para chamar o construtor da superclasse.

É possível criar e digitar propriedades de instância dentro do construtor (ver exemplo). Em alternativa, se os valores das propriedades de instância não dependerem de parâmetros passados ao construtor, pode defini-los utilizando a palavra-chave property.

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"}

property

Sintaxe

property <propertyName>{; <propertyName2>;...}{ : <propertyType>}

A palavra-chave property pode ser utilizada para declarar uma propriedade dentro de uma classe usuário. Uma propriedade de classe tem um nome e um tipo.

A declaração de propriedades de classe melhora as sugestões do editor de código, as funcionalidades de antecipação de tipos e a detecção de erros.

As propriedades são declaradas para novos objectos quando se chama a função new(). No entanto, não são automaticamente adicionadas aos objectos (só são adicionadas quando lhes é atribuído um valor).

Os nomes de propriedades devem estar em conformidade com as regras de nomeação de propriedades.

O tipo de propriedade pode ser um dos seguintes tipos suportados:

SintaxeConteúdos
TextValor texto
DateValor data
HoraValor Hora
ParâmetrosValor booleano
IntegerValor inteiro longo
RealValor real
PonteiroValor ponteiro
ImagemValor imagem
BlobValor BLOB
CollectionValor colecção
Diferente deValor variant
ObjectObject with default class (4D.Object)
4D.<className>Objecto do nome da classe 4D
cs.<className>Objeto do nome da classe usuário
cs.<namespace>.<className>For a class constructor function, the Current method name command returns: <ClassName>:constructor, for example "MyClass:constructor".
info

A palavra-chave property só pode ser utilizada em métodos classe e fora de qualquer bloco Function ou Class Constructor.

Exemplo

Sintaxe

Num método:

var $o : cs. MyClass
$o:=cs. MyClass.new() //$o:{}
$o.name:="John" //$o:{"name" : "John"}
$o.age:="Smith" //erro com a sintaxe de verificação

Function get e Function set

Sintaxe

Sintaxe
Function set <name>($parameterName : type)
// código

As funções obter e conjunto de funções são acessores que definem propriedades computadas na classe. Uma propriedade calculada é uma propriedade nomeada com um tipo de dados que oculta um cálculo. Quando um valor de propriedade computado é acessado, 4D substitui o código do acessor correspondente:

  • quando a propriedade for lida, a função get é executada,
  • quando a propriedade for escrita, o conjunto de funções `` é executado.

Se a propriedade não for acedida, o código nunca é executado.

As propriedades computadas são concebidas para tratar dados que não precisam de ser guardados na memória. São geralmente baseados em propriedades persistentes. Por exemplo, se um objecto de classe contém como propriedade persistente o preço bruto e o taxa de IVA, o preço líquido pode ser tratado por uma propriedade computada.

No arquivo de definição da classe, as declarações de propriedades computadas utilizam as palavras-chave Function get (o getter ) e Function set (o setter ), seguidas do nome da propriedade. Os nomes de propriedades devem seguir as regras de nomeação de propriedades.

A função get devolve um valor do tipo de propriedade e A função set recebe um parâmetro do tipo de propriedade. Ambos os argumentos devem estar em conformidade com os parâmetros da função .

Quando ambas as funções são definidas, a propriedade calculada é read-write. Se apenas for definida uma Function get, a propriedade calculada é só de leitura. Neste caso, é devolvido um erro se o código tentar modificar a propriedade. Se apenas um Function set estiver definido, 4D devolve undefined quando a propriedade é lida.

O tipo da propriedade calculada é definido pela declaração de tipo $return do getter . Pode ser de qualquer tipo de propriedade válida.

Atribuir undefined a uma propriedade de objecto apaga o seu valor, preservando o seu tipo. Para o efeito, a função get é chamada primeiro para obter o tipo de valor e, em seguida, a função set é chamada com um valor vazio desse tipo.

Exemplo 1

//Class: Person.4dm
property firstName; lastName : Text

Class constructor($firstname : Text; $lastname : Text)
This.firstName:=$firstname
This.lastName:=$lastname

Function get fullName() -> $fullName : Text
$fullName:=This.firstName+" "+This.lastName

Function set fullName( $fullName : Text )
$p:=Position(" "; $fullName)
This.firstName:=Substring($fullName; 1; $p-1)
This.lastName:=Substring($fullName; $p+1)
//num método projecto
$fullName:=$person.fullName // A função get fullName() é chamada
$person.fullName:="John Smith" // A função set fullName() é chamada

Exemplo 2

Function get fullAddress()->$result : Object

$result:=New object

$result.fullName:=This.fullName
$result.address:=This.address
$result.zipCode:=This.zipCode
$result.city:=This.city
$result.state:=This.state
$result.country:=This.country

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.

Polygon.4dm

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. In 4D, it can be used in different contexts.

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 ) -&#062; Object | Null

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

OB Instance of

OB Instance of ( object ; class ) -&#062; Boolean

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