Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
de contedos
Introduo 1.1
Conveno 1.1.3
Bsicos 1.3
Comentrios 1.3.3
Tipo de dados 1.3.4
Tipos valor 1.3.4.1
Strings 1.3.4.2
Arrays 1.3.4.3
Tipos referncia 1.3.4.4
Operadores 1.3.5
Estruturas de controle 1.3.6
Elementos da linguagem 1.3.7
Mtodos 1.3.7.1
Delegaes 1.3.7.2
Structs 1.3.7.5
Classes 1.3.7.6
Interfaces 1.3.7.7
Contrutor 1.4.2
Destrutor 1.4.3
Sinais 1.4.4
Propriedades 1.4.5
Herana 1.4.6
Classes abstratas 1.4.7
Interfaces 1.4.8
2
Definindo pr-requisitos 1.4.8.1
Polimorfismo 1.4.9
Genricos 1.4.13
Construo estilo GObject 1.4.14
ArrayList 1.5.4.1
HashMap 1.5.4.2
HashSet 1.5.4.3
Posse 1.5.10
Referncia no possuda 1.5.10.1
Ponteiros 1.5.12
Classes sem objeto 1.5.13
3
Compilao e comando de vinculao using 1.7.2.1
vapigen 1.8.2
4
Introduo
Tutorial de Vala
5
Introduo
6
O que vala?
O que Vala?
Vala uma linguagem de programao que habilita tcnicas modernas serem usadas para escrever aplicaes que
rodam na plataforma Gnome, particulamente Glib e GObject. Esta plataforma tem bastante tempo um ambiente de
programao completo, com certas caractersticas como um sistema de tipos dinmico e gerenciamento de memria
assistida. Antes de Vala, o nico caminho para programar para a plataforma era com a apis nativas da mquina c, que
expe com muita frequncia detalhes indesejados, com uma linguagem de alto nvel que tem um assistente de mquina
virtual, tais como as linguagens Python ou o Mono/c#, ou alternativamente, com c++ atravs de uma wrapper library.
Vala diferente de todas estas outras tcnicas, como suas sadas so cdigos gerados em C que podem ser compiladas
para executar sem a necessidade de suporte a bibliotecas extras alm da plataforma Gnome. Isto tem muitas
consequncias, porm mais importante:
Programas escritos em Vala devem ter performance amplamente similar daqueles escritos diretamente em C, sendo
mais fcil e rpido escrever e manter.
Uma aplicao em vala no pode fazer nada que no possa ser feito em C. Enquanto Vala introduz vrias
funcionalidades na linguagem que no esto acessveis em C, estas so todas mapeadas para contruo em C,
embora sejam frequentemente aquelas que so difceis ou muito demorado para escrever diretamente.
Assim sendo, enquanto Vala uma linguagem moderna com todos os recursos que voc esperaria, ela ganha seu poder
de uma plataforma existente, e deve de certa forma obedecer algumas regras por ela estabelecida.
7
Para quem este tutorial
Vala compartilha muitas sintaxes com C#, porm o tutorial ir tentar evitar descrever caractersticas em termos de
similaridades ou diferenas com C# ou Java, com o objetivo de faze-lo mais acessvel.
O que ser bem til uma compreeno razovel de C, ao passo que isso no seja necessrio para entender Vala.
importante perceber que programas em Vala so executados como C, e ir frequentemente interagir com biblitecas em C.
Ter uma compreenso razovel de C ir ajudar a criar um entendimento aprofundado em Vala mais facilmente.
8
Conveno
Convenes
O cdigo ser em texto monoespaado , e os comandos sero todos prefaciados com o caractere $ do prompt.
9
Primeiro programa
O primeiro programa
stdout.printf("Ol, Mundo\n");
return 0;
}
}
Essa linha identifica o comeo da definio da classe. As classes em Vala so muito similares em conceito com outras
linguagens. Uma classe basicamente um tipo de objeto, das quais as instancias podem ser criadas, todas tendo as
mesmas propriedades. A implementao de um tipo classificado feita pela biblioteca gobject, esses detalhes no so
importantes para uso geral.
O importante que essa classe especificamente descrita como sendo uma subclasse da GLib.Object. Isto porque a
Vala permite outros tipos de classe, mas nos casos gerais o tipo que voc quer. De fato, alguns recursos do Vala s so
permitidos se sua classe descendente de um Object, proveniente da GLib.
Esse o comeo da definio de um mtodo. Um mtodo uma funo relacionada a um tipo de objeto e que pode ser
executada num objeto daquele tipo. O mtodo esttico significa que esse mtodo pode ser chamado sem uma instancia
em particular. O fato do mtodo ser chamado main e ter a assinatura significa que o Vala vai reconhece-lo como o ponto
de entrada do programa.
O mtodo main no precisa ser definido dentro de uma classe. Porem, caso seja, precisa ser esttico. No importa se
pblico ou privado. O retorno pode ser inteiro(int) ou vazio(void). Com um retorno vazio(void) o programa vai terminar
implicitamente com o cdigo de retorno 0. O arranjo de caracteres para captura de argumentos de linha de comando
opcional.
stdout.printf("Ol, Mundo\n");
stdout um objeto no namespace GLib que certifica o Vala de que voc tem o acesso requerido. Essa linha instrui o Vala
a executar o mtodo chamado printf do objeto stdout, com uma string Ol, Mundo como argumento. No Vala, essa sempre
a sintaxe usada para chamar um mtodo num objeto, ou pra acessar os dados de um objeto. \n a sequencia de
escape para uma nova linha.
return 0;
A funo da palavra return de retornar um valor para quem chamou e terminar a execuo do mtodo main que
tmbem termina a execuo do programa. O valor retornado pelo mtodo main tido como cdigo de sada do programa.
10
Primeiro programa
11
Compilao e execuo
Compilar e executar
Assumindo que voc tem o Vala instalado, o que voc precisa fazer pra compilar e rodar o programa :
$ valac OlaMundo.vala
$ ./OlaMundo
valac o compilador Vala, o qual vai compilar o seu cdigo Vala em binrio. O binrio resultante vai ter o mesmo nome
que o cdigo fonte e pode ser executado diretamente na maquina. Voc provavelmente j imaginar a sada do programa.
12
Bsicos
13
Arquivos-fonte e compilao
Arquivos-fonte e compilao
Cdigo vala escrito em arquivos com exteno .vala. Ele no refora a estrutura tanto quanto linguagens como Java -
no existem conceitos de pacotes ou classes nos arquivos. Invs disso a estrutura definida pelo texto dentro de cada
arquivo, descrevendo a localizao lgica do cdigo com construtores como namespaces. Quando voc quer compilar
cdigo Vala, voc descreve ao compilador uma lista de arquivos requeridos, e Vala entende como eles se encaixam.
A vantagem disso que voc pode por quantas classes ou funes voc quiser dentro do arquivo, at combinando partes
de diferentes namespaces juntas. Isso no necessriamente uma boa ideia. Existem certas convenes que voc
provavelmente quer seguir. Um bom exemplo de como estruturar um projeto em Vala o prprio projeto Vala.
Todos os arquivos fonte para o pacote so supridos como parmetros da linha de comando para o compilador Vala
valac , junto com as bandeiras(flags) do compilador. Por exemplo:
ir produzir um binrio com o nome compiler que vincula com o pacote libvala. De fato, como o compilador valac
produzido!
Se voc quer que o binrio tenha um nome diferente ou se voc passou multiplos arquivos fonte ao compilador voc pode
especificar o nome do executvel explicitamente com o parmetro -o :
Se voc passar o parmetro -C ao valac, ele no compilar seu programa em arquivo binrio. Invs disso a sada ser o
cdigo C para cada cdigo fonte Vala correspondente, nesse caso source1.c e source2.c. Se voc olhar o conteudo
desses arquivo voc pode ver programar uma classe em Vala equivalente a mesma tarefa em C, porm bem mais
sucinto. Voc vai tambm perceber que essa classe registrada dinamicamente na execuo. Isso um bom exemplo do
poder da plataforma GNOME, mas como foi dito antes, voc no precisa saber sobre isso para usar Vala.
Se voc quer ter um arquivo header em C para o seu projeto voc pode usar o parmetro -H :
14
Viso geral da sintaxe
O escopo definido usando chaves). Um objeto ou referncia s vlido entre { e } . Estes so tambm os
delimitadores usados para definir classes, mtodos, blocos de cdigo, etc, ento eles automaticamente tm seus prrpios
escopos. Vala no estrita sobre aonde as vriaveis so declaradas.
Um identificador definido pelo tipo e nome, ex. int c significa um inteiro chamado c. No caso dos tipos valor isso
tambm cria um objeto de dado tipo. Para tipos referncia esses tipos apenas definem uma nova referencia que
inicialmente no aponta a lugar nenhum.
Nomes de identificadores podem ser qualquer combinao de letras ([a-z], [A-Z]), sublinha e dgitos. Todavia, para definir
ou referir a um identificador com um nome que comea com um digito ou uma palavra-chave, voc deve prefixar com um
caractere @ . Esse caractere no considerado parte do nome. Por exemplo voc pode nomear um mtodo foreach
escrevendo @foreach , mesmo sendo uma palavra-chave reservada do Vala. Voc pode omitir o caractere @ quando for
interpretado como um nome de identificador inequivocamente, como em foo.foreach() .
Tipos referencia so instanciados usando o operador new e o nome de um mtodo de construo, o qual usualmente o
nome do tipo, ex. Object o = new Object() cria um novo Object e faz o uma referncia a ele.
15
Comentrios
Comentrios
Vala permite que comentrios sejam registrados no cdigo de diferentes formas.
/**
* Comentrio de documentao
*/
Esses so manipulados da mesma forma que na maioria das outras linguagens e ento precisa de pouca explicao. Os
comentrios de documentao no so especiais para Vala, mas uma ferramenta de gerao de documentao como o
Valadoc ir reconhece-los.
16
Tipo de dados
Data Types
Falando amplamente existem dois tipos de dado em Vala: tipos referencia e tipos valor. Esses nomes descrevem como
instancias dos tipos so passadas pelo sistema - Um tipo valor copiado quando designada para um novo identificador,
um tipo referencia no copiada, invs disso o novo identificador simplesmente uma nova referencia para o mesmo
objeto.
Uma constante definida colocando const antes do tipo. A conveno de nome das constante TUDO_EM_CAIXA_ALTA .
17
Tipos valor
Tipos valor
Vala suporta uma variedade de tipos simples como a maioria das outras linguagens fazem.
/* tipos atmicos */
unichar c = 'u';
float percentile = 0.75f;
const double MU_BOHR = 927.400915E-26;
bool the_box_has_crashed = false;
/* definindo um struct */
struct Vector {
public double x;
public double y;
public double z;
}
/* definindo um enum */
enum WindowType {
TOPLEVEL,
POPUP
}
A maioria desses tipos podem ter tamanhos diferentes em plataformas diferentes, com exceo dos tipos guaranteed-size
integer(Inteiros de tamanho garantido). O operador sizeof retorna o tamanho que varivel de um dado tipo ocupa em
bytes:
Voc pode determinar os valores mximos e mnimos de um tpo numrico com .MIN e .MAX, ex. 'int.MIN' e int.MAX .
18
Strings
Strings(Conjuntos de caracteres)
O tipo de dados para strings(conjuntos de caracteres) string . As strings em Vala so codificadas em UTF-8 e
imutveis.
Vala oferece um recurso chamado verbatim strings. Strings quais as sequencias de escape (como o \n ) no so
interpretadas, quebras de linhas sero preservadas e sinais de citao no precisam ser mascarados. Elas so cercadas
com trs sinais de citao. Possveis identaes aps uma quebra de linha so parte da string tambm.
string verbatim = """Essa uma to falada "verbatim string". Verbatim strings no processam sequncias de escape, co
mo \n, \t, \\, etc. Elas podem conter citaes e abranger mltiplas linhas.""";
Strings prefixadas com '@' so templates de string. Elas podem evaluate variveis embutidas e expresses prefixadas
com '$':
int a = 6, b = 7;
string s = @"$a * $b = $(a * b)"; // => "6 * 7 = 42"
Os operadores de igualdade == e != comparam o contedo das duas strings, contrario ao comportamento do Java que
nesse caso checaria a igualdade referencial.
Voc pode recortar uma string com [inicio:fim] . Valores negativos representam posies relativas ao fim da string:
Note que os ndices em Vala comeam com 0 como na maioria das outras linguagens de programao. Apartir do Vala
0.11 voc pode acessar um nico byte de uma string com [ndice] :
Porem, voc no pode designar um novo valor em byte para essa posio, uma vez que as strings em Vala so imutveis.
Muitos dos tipos bsicos tem mtodos razoveis para anlisar e converter para strings, por exemplo:
Dois mtodos teis para escrever e ler strings de/para o console (e para suas primeiras exploraes com Vala) so
stdout.printf() e stdin.read_line():
stdout.printf("Hello, world\n");
stdout.printf("%d %g %s\n", 42, 3.1415, "Vala");
string input = stdin.read_line();
int number = int.parse(stdin.read_line());
19
Strings
Atualmente, ele pode receber um nmero arbitrrio de argumentos de tipos diferentes, no qual o primeiro argumento
uma format string, seguindo as mesmas regras das strings no formato do C.
Se voc precisa emitir uma mensagem de erro voc pode usar o stderr.printf() invs do stdout.printf().
Em adio o operador in pode ser usado para determinar quando uma string contm outra, ex.
20
Arrays
Arrays (Arranjos/Vetores)
Um array declarado dando o tipo seguido por [] e criado usando o operador new ex. int[] a = new int[10] para
criar um arranjo de nmeros inteiros(integer). O tamanho do array pode ser obtido pela varivel membro(atributo) length
ex. int count = a.length . Note que se voc escrever Object[] a = new Object[10] nenhum objeto vai ser criado, s o
array pra armazenar-los.
Cortando um array vai resultar numa referencia para o dado requerido, no uma cpia. Porem, designando um recorte
para uma varivel owned (como feito abaixo) vai resultar em uma cpia. Se voc quer evitar uma copia, voc precisa
designar o recorte a um array unowned ou passar diretamente para um argumento (argumentos so, por definio, no
prprios):
Esse tipo de array representado por um nico bloco de memria contguo. Arrays multi-dimensionais irregulares ( [][] ,
tambm conhecido como "arranjos empilhados/arrays empilhados"), aonde cada linha pode ter um tamanho diferente,
ainda no so suportados.
Para encontrar o tamanho de cada dimeno em um array multi-dimensional, o membro length vira um array,
armazenando o tamanho de cada respectiva dimenso.
Por favor note que voc no pode obter um array mono-dimensional de um array multidimensional, nem mesmo recortar
um array multidimensional:
Voc pode inserir elementos dinamicamente no array com o operador += . Todavia, isso s funciona para arrays locais ou
privados. O array automaticamente realocado se for necessrio. Internamente essa realocao acontece com os
tamanhos crescendo em potencia de 2 pela eficincia de tempo de execuo. Porem, .length guarda o numero atual de
elementos, no o tamanho interno.
21
Arrays
int[] e = {};
e += 12;
e += 5;
e += 37;
Voc pode redimensionar um array chamando resize() nele. Isso vai manter o contedo original(o quanto couber).
Voc pode mover elementos dentro do array chamando move(src, dest, length) nele. A posio original vai ser preenchida
com 0.
Se voc colocar os colchetes quadrados aps o indentificador junto com um indicador do tamanho voc vai ter um array
de tamanho fixo. Arrays com tamanho fixo so alocados no stack (se usado como varivel local) ou alocado in-line (se
usado como campo) e voc no pode os realocar depois.
Vala no faz nenhuma verificao de limite do acesso dos arrays na execuo. Se voc precisa de mais segurana deve
usar uma estrutura de dados mais sofisticada como um ArrayList. Voc vai aprender mais sobre isso depois na sesso
sobre coleces.
22
Tipos referncia
Tipo Referncia
Os tipos referencias so todos os tipos declarados como uma classe, independente de ser descendente de um objeto
Glib(Object). Vala vai assegurar que quando voc passar um objeto por referencia o sistema guardar o nmeros de
referencias ativas para gerenciar a memoria para voc. O valor de uma referencia que no aponta para lugar nenhum
null . Mais sobre classes e seus recursos na sesso sobre programao orientada a objetos.
23
Converso de tipo esttico
int i = 10;
float j = (float) i;
Vala suporta outro mecanismo de converso chamado dynamic casting(converso dinmica) que faz checagem de tipo no
tempo de execuo e descrito na sesso sobre programao orientada a objetos.
24
Tipagem por inferncia
Inferncia de tipos
Vala has a mechanism called type inference, whereby a local variable may be defined using var instead of giving a type,
so long as it is unambiguous what type is meant. The type is inferred from the right hand side of the assignment. It helps
reduce unnecessary redundancy in your code without sacrificing static typing:
Vala tem um mecanismo chamado type inference(inferncia de tipo), na qual uma varivel local pode ser definida usando
var invs de determinar um tipo, enquanto no for ambguo que tipo pretendido. O tipo inferido pelo lado direito da
designao. Isso ajuda a reduzir uma redundncia desnecessria no seu cdigo sem sacrificar a tipagem esttica.
Isso funciona apenas para variveis locais. Inferncia de tipo especialmente til para tipos com argumentos de tipo
genrico (mais disso depois). Compare
vs.
25
Definindo novo tipo com base em outro
/* definindo um apelido para um tipo bsico (equivalente ao typedef int Integer em C)*/
[[SimpleType](/SimpleType)] public struct Integer : uint { }
/* Define um novo tipo de um container como GLib.List com elementos do tipo GLib.Value */
public class ValueList : GLib.List<GLib.Value> {
26
Operadores
Operadores
=
atribuio. O operando esquerdo deve ser um identificador, e o direito deve resultar em um valor ou referncia
apropriadamente.
+, -, /, *, %
aritimtica bsica, aplicada aos operandos esquerdo e direito. O operador + tambm pode concatenar strings.
operao aritimtica entre o operador esquerdo e direito, where the left must be an identifier, para qual o resultado
atribudo.
++, --
operaes de incremento e decremento com atribuio implicita. Esses tomam s um argumento, que deve ser um
identificador de um tipo simples de dado.
O valor ser mudado e atribuido de volta ao identificador. Esses operadores podem ser dispostos como prefixo ou
psfixos, - com o primeiro o valor calculado da declarao ser o valor recm calculado, com o ltimo o valor original
retornado.
operaes bitwise: or(ou), exclusive or(ou exclusivo), and(e), not(no). O segundo conjunto inclui atribuio e anlogo s
verses aritimticas. Eles podem ser aplicadas a qualquer tipo valor simples. (No existe operador de atribuio associado
com ~ porque esse o operador unrio. A operao equivalente a = ~a ).
<<, >>
operaes bit shift, desloca o operando esquerdo o nmero de bits de acordo com o operando direito.
<<=, >>=
operaes bit shift, desloca o operando esquerdo o numero de bits de acordo com o operando direito. O operando
esquerdo deve ser um identificador, o qual o resultado atribudo.
==
teste de igualdade. Resulta em um valor booleano(bool) dependendo se os operandos esquerdo e direito so iguais. No
caso dos tipos valor isso significa que seus valores so iguais, no caso dos tipos referencia que os objetos so da mesma
instncia. Uma exceo a essa regra o tipo string , que testada em igualdade por valor.
27
Operadores
teste de inigualdade. Resulta em um valor bool dependendo se os operandos esquerdo e direito so diferentes na
maneira descrita. Eles so vlidos para valores simples de dados, e para o tipo string . Para strings esses operadores
comparam a ordem lexogrfica.
!, &&, ||
operadores lgicos: not(no), and(e), or(ou). Essas operaes podem ser aplicadas a valores booleanos - o primeiro toma
um valor dos outros dois.
? :
operador de condio ternria. Resulta em uma condio e retorna a sub-expresso da esquerde ou direita baseado e,
qual condio verdadeira ou falsa: condio ? valor se for verdade : valor se for falso
??
operador null coalescing: a ?? b equivalente a a != null ? a : b . Esse operador til para prover um valor padro no
caso da referncia ser nula(null):
in
checa se o operando direito contem o operando esquerdo. Esse operador funciona em arrays, strings, colees ou
qualquer outro tipo que possua o mtodo contains(). Para strings ele executa uma busca de substring.
Operadores no podem ser sobrecarregados em Vala. Existem operadores extras que so vlidos no contexto de
expresses lambda e outras tarefas especficas - estes so explicados no contexto onde so aplicveis.
28
Estruturas de controle
Estruturas de controle
while (a > b) { a--; }
vai diminuir a repetidamente, checando antes de cada iterao que a maior que b.
vai diminuir a repetidamente, checando aps cada iterao que a maior que b.
vai inicializar a em 0, ento imprimir a repetidamente at a deixar de ser menor que 10, incrementando a aps cada
iterao.
vai imprimir cada inteiro num array, ou outra coleo itervel. O significado de "itervel" vai ser descrito depois.
Todos os quatro tipos precedentes de repetio(loop) podem ser controlados com as palavras-chave break e continue .
Uma instruo break faz a repetio terminar imediatamente, enquanto continue ir pular direto para o teste da
iterao.
executa uma parte do cdigo baseada no conjunto de condies. A primeira condio decide que cdigo ser executado,
se a maior que 0 ele no testar se menor que 0. Qualquer numero de blocos else if permitido, e zero ou um bloco
else.
switch (a) {
case 1:
stdout.printf("one\n");
break;
case 2:
case 3:
stdout.printf("two or three\n");
break;
default:
stdout.printf("unknown\n");
break;
}
Uma declarao switch executa exatamente uma ou zero sees do cdigo com base no valor passado. Em Vala no
existe queda(fall through) nos os casos(cases), exceto nos casos vazios. Para assegurar isto, cada caso no-vazio deve
finalizar com uma declarao break , return ou throw . possvel usar uma declarao switch com strings.
Uma nota para programadores C: condies sempre devem ser um valor booleano. Isso significa que se voc quer checar
uma varivel null ou 0 voc precisa fazer isso explicitamente:
29
Estruturas de controle
30
Elementos da linguagem
Elementos da linguagem
31
Mtodos
Mtodos
Funes so chamadas mtodos em Vala, independente de serem definidos dentro ou fora de uma classe. A partir de
agora ns irmos chama-las pelo termo mtodo.
Esse cdigo define um mtodo, tendo o nome mtodo_nome, recebendo dois argumentos, um inteiro e outro Objeto (O
primeiro passado por valor, o segundo por referncia como descrito). O mtodo retornar um inteiro, que no caso 1.
Todos mtodos Vala so funes C, e portanto recbem um nmero arbitrrio de argumentos e retornam um valor (ou
nenhum se o mtodo declarado void(vazio)). Eles podem retornar mais valores aproximados caso sejam postos dados
em lugares conhecidos ao cdigo chamado. Detalhes de como fazer isso esto na seo "Direes dos parmetros" na
parte avanada desse tutorial.
A nomenclatura convncional para mtodos em Vala tudo_em_caixa_baixa com sublinhas separando palavras. Isso
pode ser um pouco desconhecido para programadores Java ou C# que esto acostumado com nome de mtodos em
CamelCase ou camelCaseMesclado. Mas com esse estilo voc vai ser consistente com outras bibliotecas Vala e
C/GObject.
No possvel ter mltiplos mtodos com o mesmo nome mas diferentes assinaturas dentro do mesmo
escopo(sobrecarga de mtodos):
Isso se deve ao fato de que bibliotecas produzidas em Vala tem preteno de serem usaveis por programadores C
tambm. Invs disso voc pode fazer algo assim em Vala:
Por escolher um nome diferente voc pode evitar um conflito de nomes. Em linguagens que suportam sobrecarga de
mtodos usada geralmente para prover mtodos convenientes com menos parmetros para encadear os mtodos mais
comuns:
Nesse caso voc pode usar o recurso argumento padro do Vala para parmetros dos mtodos para alcanar um
comportamento similar com um nico mtodo. Voc pode definir valores padres para os ltimos parmetros de um
mtodo, para que voc no precise passa-los explicitamente para uma chamada de mtodo:
f(2);
f(2, "oi");
f(2, "oi", 0.75);
32
Mtodos
possvel at definir mtodos com a quantidade de vriaveis como argumento (varargs) como o stdout.printf(), entretanto
no necessriamente recomentado. Voc aprender como fazer isso depois.
Vala performa um teste bsico de nulidade nos parmetros dos mtodos e nos valores de retorno. Se permitido que um
parmetro ou um retorno seja null , o tipo deve ser psfixado com um modificador ? . Essa informao extra ajuda o
compilador a executar checagens estticas e a adicionar afirmaes no tempo de execuo a cerca das pr-condies
dos mtodos, os quais podem ajudar a evitar problemas relacionados a erros como derefernciao de uma referncia
nula(null).
Nesse exemplo texto , foo e o retorno podem ser null , entretanto, bar no pode ser null .
33
Delegaes
Delegaes
delegate void DelegateType(int a);
Delegaes representam mtodos, permitindo pedaos de cdigo serem passados como objetos. O exemplo acima define
um novo tipo chamado DelegateType no qual representa mtodos recebendo um int e no retornando valor. Qualquer
mtodo que se encaixe nessa assinatura pode ser atribudo uma vriavel do tipo ou passada como um argumento do
mtodo desse tipo.
void f1(int a) {
stdout.printf("%d\n", a);
}
void main() {
f2(f1, 5); // Passando um mtodo como argumento de delegao outro mtodo
}
Esse cdigo executar o mtodo f2, passando por referencia o mtodo f1 e o nmero 5. f2 ento executar o mtodo f1,
passando o nmero.
Delegaes podem ser criadas localmente tambm. O mtodo membro tambm pode ser designado uma delegao, ex.
class Foo {
34
Mtodos annimos/Closures
Mtodos annimos/Closures
(a) => { stdout.printf("%d\n", a); }
Um mtodo annimo, tmbem conhecido como uma expresso lambda, funo literal ou closure, pode ser definida em
Vala com o operador => . A lista de parmetros fica a esquerda do operador, e o escopo do mtodo direita.
Um mtodo annimo por si s como como acima no faz muito sentido. Ele s til se designado diretamente a vriavel
de um tipo delegado ou passado como um argumento outro mtodo.
Tenha em mente que nem o parmetro nem o tipo de retorno informado explicitamente. Invs disso os tipos so inferidos
pela assinatura da delegao usada.
void main() {
PrintIntFunc p1 = (a) => { stdout.printf("%d\n", a); };
p1(10);
void main() {
int[] data = { 3, 9, 2, 7, 5 };
// Um mtodo annimo passado como um segundo argumento:
my_sorting_algorithm(data, (a, b) => {
if (a < b) return -1;
if (a > b) return 1;
return 0;
});
}
Mtodos annimos so closures) reais. Isso significa que voc pode acessar variveis locais de um mtodo exterior dentro
da expresso lambda:
IntOperation curried_add(int a) {
return (b) => a + b; // 'a' uma vriavel externa
}
void main() {
stdout.printf("2 + 4 = %d\n", curried_add(2)(4));
}
Nesse de adio com currying(veja Currying) retorna um mtodo recm criado que preserva o valor de a. Esse mtodo
retornado chamado diretamente depois com 4 como argumento resultante na soma de dois nmeros.
35
Mtodos annimos/Closures
36
Namespaces
Namespaces
namespace NameSpaceName {
// ...
}
Tudo entre as chaves dessa declarao est no namespace NameSpaceName e precisa ser refernciada como tal.
Qualquer cdigo fora desse namespace deve usar nomes qualificados para qualquer coisa dentro do nome do
namespace, ou estar em um arquivo com a declarao using para importar esse namespace:
using NameSpaceName;
// ...
Por exemplo, se o namespace Gtk importado com using Gtk; voc pode escrever Window invs de Gtk.Window. Um
nome completamente qualificado poder ser necessrio apenas em casos de ambiguidade, por exemplo entre GLib.Object
e Gtk.Object.
O namespace GLib importado por padro. Imagine uma linha invsivel using GLib; no nicio de cada arquivo Vala.
Qualquer coisa que voc no colocar em um namespace separado vai incorporar um namespace annimo global. Se voc
precisa referenciar o namespace global explicitamente devido a ambiguidade voc pode fazer isso com o prefixo
global:: .
Namespaces podem ser encadeados, tanto encadeando uma declarao dentro de outra quanto por dar um name na
forma Namespace1.NameSpace2.
Diversos outros tipos de definies podem declarar estar dentro de um namespace seguindo a mesma conveno de
nomenclatura, ex.
class NameSpace1.Teste { ... } . Note que fazendo isso, o namespace da definio ser o da declarao encadeada mais
37
Structs
Structs
struct NomeStruct {
public int a;
}
define um tipo struct , ex. um tipo valor composto. Uma struct Vala pode ter mtodos de uma forma limitada e tambm
pode ter membros privados, de tal forma que o modificador de acesso public requirido explicitamente.
struct Cor {
public double vermelho;
public double verde;
public double azul;
}
38
Classes
Classes
class ClassName : SuperClassName, InterfaceName {
}
define uma classe, ex. um tipo referncia. Em contraste com os structs, instncias de classes so alocadas no heap.
Existe muito mais sintaxes relacionada as classes, as quais sero mais discutidas integralmente em sees sobre
programao orientada a objetos.
39
Interfaces
Interfaces
interface InterfaceName : SuperInterfaceName {
}
define uma interface, ex. um tipo no instnciavel. Para criar uma instncia de uma interface voc deve primeiro
implementar seus mtodos abstratos em uma class no-abstrata. As interfaces do Vala so mais poderosas que em Java
ou C#. De fato, elas podem ser usadas como mixins(em ingls). Os detalhes das interfaces so descritos na seo de
orientao a objetos.
40
Atributos de cdigo
Atributos de cdigo
Atributos de cdigos instruem ao compilador Vala detalhes de como o cdigo deve funcionar na plataforma desejada. Sua
sintaxe [NomeDoAtributo] ou [NomeDoAtributo(param1 = valor1, param2 = valor2, ...)] .
Eles so usados mais usados para bindings nos arquivos vapi, [CCode(...)] sendo o atributo mais proeminente aqui.
Outro exemplo o atributo [DBus(...)] para exportar interfaces remotas pelo D-Bus
41
Programao orientada a objetos
Uma definio de classe dita que tipo de dado cada objeto de seu tipo possi, quais outros objetos ele tem referncia, e
quais mtodos podem ser executados nela. Uma definio pode incluir o nome de outra classe a qual a nova deve ser
uma subclasse. A instancia de uma classe tambm uma instancia de todas as super classes da classe, por ela derivar
todos os mtodos e dados, entretanto ela pode no ser capaz de acessar toda a super classe. Uma classe pode tambm
implementar qualquer quantidade de interfaces, quais so um conjunto de definies de mtodos que devem ser
implementados pela classe - uma instancia de uma classe tambm uma instancia de cada interface implementada por
sua classe ou super classe.
Classes em Vala podem tambm ter membros estticos. Esse modificador permite que qualquer dado ou mtodo seja
pertencente a classe como um todo, invs de ser especifica de sua instancia. Tais membros podem ser acessados sem a
posse de uma instancia de uma classe.
42
Bsicos
Bsicos
Uma simples classe pode ser definida como a seguir:
/* Fields */
public int first_data = 0;
private int second_data;
/* Constructor */
public TestClass() {
this.second_data = 5;
}
/* Method */
public int method_1() {
stdout.printf("private data: %d", this.second_data);
return this.second_data;
}
}
Esse cdigo vai definir um novo tipo (que ser registrado automaticamente com o sistema de tipos da biblioteca gobject)
que contem trs membros. Existem tambm dois membros dado, um inteiro definido no comeo, e um mtodo chamado
method\1, que retorna uma integer. A declarao de classe dita que essa classe uma subclasse de GLib.Object, e
portanto instncias dela tambm so Objects, e contm tambm todos os membros desse tipo. O fato dessa classe
descender do GObject tambm significa que existem recursos especiais em Vala que podem ser usados para acessar
fcilmente alguns recursos do Object.
Essa classe descita como public (por padro, classes so internal ). A implicao disso que pode ser referenciada
diretamente pelo cdigo de fora do arquivo - se voc um programador C da glib/gobject, voc vai reconhecer isso como
sendo equivalente a definir interfaces de classes em um header que outro cdigo pode incluir.
Esses membros tambm so descritos como public ou private , pblico e privado respectivamente. O membro
first_data public , ento visvel diretamente para qualquer usuario da classe, e pode ser modificado sem conter uma
instncia estando ciente disso. O segundo dado membro private , sendo assim s pode ser referenciado por um cdigo
pertencente a esta classe. Vala suporta quatro modificadores de acesso diferentes:
Modificador Descrio
private
Acesso limitado a definio da classe/estrutura(struct). Esse o padro se nenhum modificador
de acesso especificado.
protected Acesso limitado a definio da classe e qualquer classe que herde dela
O construtor incializa uma nova instncia da classe. Ele tem o mesmo nome da classe, pode ter zero ou mais argumentos
e definido sem tipo de retorno.
A parte final dessa classe uma definio de mtodo. Esse mtodo chamado method\1, e retornar um inteiro. Como
esse mtodo no esttico, ele s pode ser executado numa instncia dessa classe, e pode acessar membros da
instncia. Ele pode fazer isso pela referncia this , que sempre aponta para a instncia em que o mtodo chamado. A
no ser que exista ambiguidade, o identificador this pode ser omitido se desejado.
43
Bsicos
44
Contrutor
Contrutor
Vala suporta dois construtores de esquemas levemente diferentes: o estilo de construo do estilo Java/C# qual iremos
focar agora, e o estilo GObject que ser descrito na seo no final do captulo.
Vala no suporta sobrecarga de construtores pela mesma razo que sobrecarga de mtodos no permitida, o que
significa que uma classe no pode ter mltiplos construtores com o mesmo nome. Porm, isso no um problema porque
Vala suporta construtores nomeados. Se voc quer oferecer mltiplos construtores voc pode dar diferentes nomes
adicionais:
public Button() {
}
A nicializao anloga:
new Button();
new Button.with_label("Click me");
new Button.from_stock(Gtk.STOCK_OK);
void main() {
var p1 = new Point.rectangular(5.7, 1.2);
var p2 = new Point.polar(5.7, 1.2);
}
45
Destrutor
Destrutor
Mesmo Vala gerenciando a memria por voc, voc pode necessitar do seu prprio destrutor caso decida fazer uma
gerncia manual da memria com ponteiros (mais sobre isso depois) ou se voc precisa liberar outros recursos. A sintaxe
a mesma do C# e C++:
Desde que o gernciamento de memria do Vala baseado na contagem de referncias invs de coleo de lixo(garbage
collection), destrutores so deterministicos e podem ser usados para implementar o padro RAII para gerenciar os
recursos (fechamento de fluxos, conexes de bancos de dados, ...).
46
Sinais
Sinais
Sinais so um sistema proveniente da classe Objeto da GLib, e so fcilmente acessveis ao Vala em todos os
descendentes dos Objetos. Um sinal reconhecvel por um programador C# como um evento, ou aos programadores
Java como uma alternativa implementar event listeners. Brevemente, um sinal um jeito simples de executar um
nmero arbitrrio de mtodos externamente identicos (ex. os com o mesmo sinal) aproximadamente no mesmo tempo. Os
mtodos atuais de execuo so internos ao gobject, e no importante aos programas Vala.
Um sinal definido como um membro de uma classe, e aparenta similar a um mtodo sem um corpo. Gerenciadores de
sinais podem ento cer adicionados ao sinal usando o mtodo connect() . Para finalizar, o exemplo a seguir tambm
introduz expresses lambda, uma forma til de escrever gerenciadores de sinais em Vala:
t1.sig_1.connect((t, a) => {
stdout.printf("%d\n", a);
});
t1.sig_1(5);
return 0;
}
}
Esse cdigo introduz uma nova classe chamada "Teste", usando uma sntaxe familiar. O primeiro mmbro dessa classe
um sinal, chamado "sig_1", que definido recebendo um inteiro. No mtodo principal do programa(main), ns primeiro
criamos uma instncia de Teste - Um requerimento desde que sinais sempre pertencem instncias da classe. Em
seguida, ns atribumos para nossa instncia um gerenciador de sinal "sig_1", no qual definimos uma expresso lambda.
A definio dita que o mtodo receber dois argumentos quais chamaremos "t" e "a", mas no provemos tipos. Nos
podemos ser concisos assim porque Vala j conhece a definio do sinal e pode compreender que tipos so requeridos.
A razo pela qual existem dois parmetros para gerir os sinais que quando um sinal emitido, o objeto ao qual ele
emitido passado como primeiro argumento ao gerenciador. O segundo argumento o que o sinal providencia.
Finalmente, ns ficamos impacientes e decidimos emitir um sinal. Ns fazemos fazemos isso chamando o sinal como se
fosse um mtodo da nossa classe, e isso permite ao gobject de tomar conta de encaminhar a mensagem a todos os
gerenciadores de sinais. Compreender os mecanismos usados para isso no um requerimento para se usar sinais em
Vala.
N.B.: Atualmente o modificador de acesso public a nica opo - todos os sinais podem ser conectados e emitidos por
qualquer parte do cdigo.
47
Propriedades
Propriedades
uma boa prtica de orientao objetos ocultar detalhes da implementao para os suarios de suas classes(Princpio
de ocultao de informaes(em ingls)), ento voc pode depois mudar os internos sem quebrar a API pblica. Uma
pratica tornar os campos privados e prover mtodos de acessos para pegar e determinar os seus valores(getters e
setters).
Isso funciona, mas Vala pode fazer melhor. O problema que esses mtodos so incomodos de se trabalhar. Vamos
supor que voc quer incrementar a idade da pessoa em um ano:
/* Propriedade */
public int idade {
get { return _idade; }
set { _idade = value; }
}
}
Essa sintaxe deve ser familiar a programadores C#. A propriedade tem um get e um set para inserir e retornar seu
valor. value uma palavra chave que representa o novo valor que deve ser atribudo a propriedade.
Agora voc pode acessar a propriedade como se ela fosse um campo pblico. Mas por trs das cenas o cdigo
executado pelos setters e getters.
Se voc s faz a implementao padro como mostrada acima voc pode escrever as propriedades de maneira mais
curta:
Com propriedades voc pode mudar o trabalho interno das classes sem mudar sua API pblica. Por exemplo:
48
Propriedades
Agora a idade calculada na hora pelo ano de nascimento. Note que voc pode fazer mais que acessar uma simples
variavel ou atribuio com os blocos get e set. Voc poderia fazer um acesso banco de dados, logs, atualizaes de
cache, etc.
Se voc quer fazer uma propriedade somente-leitura para os usuarios da classe voc deve fazer o setter privado:
Propriedades podem no apenas ter um nome mas tambm uma curta descrio(chamado nick) e uma descrio
longa(chamada blurb). Voc pode anotar esses com um atributo especial:
Propriedades e suas descries adicionais podem ser requeridas em tempo de execuo. Alguns programas como a
ferramenta grfica de design de interfaces de usuario Glade faz uso dessa informao. Dessa forma Glade pode mostrar
descries legveis por humanos para propriedades dos widgets GTK+.
Toda instancia de uma classe derivada da GLib.Object tem um sinal chamado notify . Esse sinal emitido toda vez que
uma propriedade de seus objetos muda. Ento voc pode conectar a esse sinal se estiver interessado nas notificaes de
mudanas em geral:
obj.notify.connect((s, p) => {
stdout.printf("A propriedade '%s' mudou!\n", p.nome);
});
s a origem do sinal ( obj nesse exemplo), p a informao da propriedade do tipo ParamSpac para a propriedade
mudada. Se voc s est interessado nas notificaes de mudana de uma nica propriedade voc pode usar essa
sintaxe:
alice.notify["idade"].connect((s, p) => {
stdout.printf("idade mudou\n");
});
Note que nesse caso voc precisa usar a representao verbal do nome da propriedade aonde sublinhas so substituidas
por traos: nome_da_propriedade se torna nome-da-propriedade nessa representao, que a conveno de nomeao de
propriedades nos GObjects.
49
Propriedades
A notificao de mudanas pode ser desabilitada com um atributo CCode imediatamente antes da declarao da
propriedade:
H outro tipo de propriedades chamado propriedades de construo(construct properties) que so descritos depois na
seo sobre construo no estilo gobject.
Nota: no caso de sua propriedade ser do tipo struct, para receber o valor da propriedade com Object.get(), voc tem que
declarar sua varivel como no exemplo abaixo
struct Cor
{
public uint32 argb;
int main()
{
Cor? c = null;
Forma f = new Forma();
f.get("c", out c);
}
Dessa forma, c uma referncia invs de uma instancia de Cor no stack. O que voc passou ao s.get() "Cor **" invs de
"Cor *".
50
Herana
Herana
Em Vala, uma classe pode derivar de uma ou zero outras classes. Na prtica provvel que este seja um, embora no
haja herana implcita como em linguagens como Java.
Quando se define uma classe que herda de outra, voc cria um relacionamento entre as classes onde as intncias da
subclasse tambm so instancias da superclasse. Isso significa que operaes em instancias da superclasse so tambm
aplicveis em instancias da subclasse. Sendo assim, quando uma instancia da superclasse requerida, uma instancia da
subclasse pode ser usada.
Quando se escreve a definio de uma classe possvel exercer controle preciso sobre quem pode acessar quais
mtodos e dados no objeto. O exemplo a seguir demostra um srie dessas opes:
public SubClasse() {
base(10);
}
}
dado um dado membro da SuperClasse. Vai ter um membro desse tipo em qualquer instncia da SuperClasse, e
declarado privado ento s vai ser acessvel pelo cdigo que parte da SuperClasse.
metodo_protegido um mtodo instancia da SuperClasse. Voc poder executar esse mtodo apenas em uma instancia
da SuperClasse ou em uma de suas subclasses, e s no cdigo que pertence a SuperClasse ou uma de suas subclasses
- Essa ultima regra o resultado do modificador protected .
metodo_publico_estatico tem dois modificadores. O modificador static significa que esse mtodo pode ser chamado
sem posse de uma instancia da SuperClasse ou uma de suas subclasses. Como resultado, esse mtodo no ter acesso
a referencia this quando for executada. O modificador public significa que esse mtodo pode ser chamado em
qualquer cdigo, no importando o relacionamento com a SuperClasse ou suas subclasses.
Dadas estas definies, uma instncia de SubClasse vai conter todos os trs membros da SuperClasse, mas ir somente
ser capaz de acessar membros no-privados. Cdigo externo s poder acessar o mtodo pblico.
Com base um construtor da subclasse pode encadear um construtor de sua classe base.
51
Classes abstratas
Classes abstratas
Existe outro modificador para mtodos, chamado abstract . Esse modificador permite que voc descreva um mtodo que
no atualmente implementado na classe. Invs disso, ele deve ser implementado pela subclasse antes de ser chamado.
Isso permite que voc defina operaes que podem ser chamadas em todas instncias de um tipo, enquanto ensegura-se
de que todos os tipos mais especficos provem sua prpria verso da funcionalidade.
Uma classe contendo mtodos abstratos deve ser declarada abstract (abstrata) tambm. O resultado disso previnir
qualquer instanciao do tipo.
A implementao de um mtodo abstrato deve ser marcada com override . Propriedades tambm podem ser abstratas.
52
Mtodos virtuais
Mtodos virtuais
Um mtodo virtual permite que sejam definidas implementaes padro para classes abstract (abstratas) e permitem
que uma classe filha sobreponha seu comportamento, isso diferente de esconder mtodos.
Como voc pode ver no exemplo acima, Discador uma classe abstrata( abstract ) definindo uma propriedade abstrata
e um mtodo abstrato, mas adiciona um mtodo virtual que pode ser sobreposto pela classe derivada. A classe
Contato implementa mtodos e propriedades abstratas de Discador , enquanto usa a implementao padro de
restaurar() por no definir uma nova. A classe ContatoCV implemeta todas as definies abstratas do Discador , mas
53
Interfaces
Interfaces
Uma classe em Vala pode implementar qualquer nmero de interfaces. Cada interface um tipo, como uma classe, mas
um que no pode ser instanciado. Por "implementar" uma ou mais interfaces, uma classe pode declarar suas instncias
como instncias da interface, e portanto pode ser usada em qualquer situao em que uma instncia dessa interface
esperada.
O procedimento para implementar uma interface o mesmo de herdar de classes com mtodos abstratos - se a classe
til ela deve prover implementaes para todos os mtodos que so descritos mas no ainda implementados
Esse cdigo descreve uma interface ITeste que requer GLib.Object como pai da classe implementadora e contem dois
membros. dado\_1 uma propriedade, como descrito acima, exceto que esteja declarado abstrata. Vala ir portanto no
implementar a propriedade, mas invs requerer que a classe implementando essa interface tenha uma propriedade
chamada dado_1 que tenha os dois acessores get e set - necessrio que seja abstrata( abstract ) pois as interfaces
no podem ter dados. O segundo membro metodo_1 um mtodo. Aqui declarado que esse mtodo deve ser
implementado pelas classes que implementam essa interface.
ITeste i = t;
i.metodo_1();
54
Definindo pr-requisitos
Definindo pr-requisitos
Interfaces em Vala podem no herdar de nenhuma outra interface, mas elas podem declarar outras interfaces como pr-
requisito, que funciona grosseiramente do mesmo jeito. Por exemplo, pode ser desejvel dizer que qualquer classe que
implemente uma interface List deva implementar tambm as interfaces Collection e Traversable . A sintaxe para isso
exatamente a mesma para descrever implementao de interfaces em classes:
A definio de List no pode ser implementada em uma classe sem Collection ser implementada tambm, ento Vala
obriga o seguinte estilo de declarao para uma classe desejando implementar List, aonde todas as interfaces
implementadas tambm devem ser descritas:
Interfaces Vala tambm podem ter classes como pr-requisito. Se um nome de classe dado na lista de pr-requisitos.a
interface s pode ser implementada em uma classe que deriva dessa classe. Isso usado frequentemente para garantir
que uma instncia da interface tambm uma subclasse de GLib.Object, e ento a interface pode ser usara, por exemplo,
como o tipo de uma propriedade.
O fato que interfaces no podem herdar de outras interfaces geralmente uma distino tcnica apenas - na pratica Vala
funciona da mesma forma que outras linguagens nesse ponto, mas com o recurso extra de pr-requisitos de classe.
55
Definindo padro de implementao em mtodos
Vala permite implementao de mtodos em interfaces, ento um mtodo com uma implementao padro deve ser
declarado como virtual . Devido a este fato interfaces Vala podem agir como mixins(em ingls).Isso uma forma restrita
de mltiplas heranas.
A interface Discavel define uma propriedade abstrata chamada atendendo , aonde qualquer classe implementando essa
interface pode monitorar o estado de uma chamada, detalhes sobre atender so um problema do implementador, mas
suspender define uma implementao padro para por atendendo em falso quando uma chamada for suspensa.
Quando compilar e executar, voc discobrir que a classe Fone no implementa o mtodo Discavel.suspender() , mas
capaz de usa-lo, ento o resultado a mensagem Suspeno concluda .
56
Definindo padro de implementao em mtodos
Nesse caso SmartPhone outra implementao ao Discavel , ento quando o mtodo suspender() chamado na
instncia de SmartPhone ele retornar falso e imprimir a mensagem Implementao SmartPhone.suspender ()! ,
escondendo completamente a implementao padro Discavel.suspender()
57
Propriedades
Propriedades
Uma interface pode definir propriedades que precisam ser implementadas para classes. A classe implementadora precisa
definir uma propriedade com a mesma assinatura e permisso de acesso ao get e set .
Como qualquer propriedade GObject, voc pode definir um corpo para o get e set da propriedade na classe
implementadora, quando nenhum corpo usado valores so set e get por padro. Se dados, voc precisa definir um
campo privado para guardar os valores da propriedade para ser usado dentro ou fora da classe.
A definio da interface Discavel , define uma propriedade atendendo . Nesse caso essa interface define um atendendo
com um protected set , permitindo uma propriedade somente leitura para qualquer objeto usando uma instncia de
Discavel , mas permite que os implementadores da classe escrevam valores nela, como a classe SmartPhone faz quando
58
Mixins e mtiplas heranas
Se voc definir um mtodo virtual em uma interface e implementar isso em uma classe, voc no pode sobrepor o
mtodo da interface sem deixar a classe derivada incapaz de acessar a implementao padro da interface. Considere o
caso a seguir:
59
Mixins e mtiplas heranas
Nesse caso, ns definimos uma interface Callable com uma implementao padro para abstract bool hang ()
chamada default_hang , ela pode ser um mtodo static ou virtual . Ento Caller a classe base implementando
Callable para as classes TechPhone e Phone , enquanto o mtodo hang () da Caller usa a implementao padro de
Callable . TechPhone no faz nada e pega Caller como classe base, usando a implementao padro do mtodo, mas
Phone sobrepe Caller.hang () e isso faz com que ele usa sua prpria implementao, permitindo sempre chama-lo
A implementao explicita de mtodos de interface permite que sejam implementadas duas interfaces que tenham os
mesmos mtodos (no propriedades) com o mesmo nome.
Exemplo:
interface Foo {
public abstract int m();
}
interface Bar {
public abstract string m();
}
void main () {
var cls = new Cls ();
message ("%d %s", ((Foo) cls).m(), ((Bar) cls).m());
}
60
Polimorfismo
Polimorfismo
Polimorfismo descreve o jeito no qual um mesmo objeto pode ser usado como se fosse mais de um tipo distinto. Diversas
das tcnicas aqui descritas sugerem como isso possvel em Vala: Uma instancia de uma classe pode ser usada como
em uma instancia de uma superclasse, ou de qualquer interface implementada, sem qualquer conhecimento do seu tipo.
Uma extenso lgica desse poder permitir que um subtipo haja diferente quando endereado exatamente da mesma
forma. Isso no um conceito muito fcil de explicar, ento vamos comear com um exemplo que mostrar o que
acontece se voc no buscar esse objetivo:
Essas duas classes implementam o mesmo mtodo chamado "method_1" e a SubClass portanto contm dois mtodos
chamados "method_1", por herdar uma da SuperClass . Cada um desses podem ser chamados como o cdigo a seguir
mostra:
Isso ir resultar em dois diferentes mtodos sendo chamados. A segunda linha acredita que "o1" seja uma SubClass e vai
chamar aquela verso do mtodo. A quarta linha espera que "o2" seja uma SuperClass e vai chamar o mtodo daquela
classe.
O problema que esse exemplo expe, que qualquer cdigo mantendo uma referncia SuperClass vai chamar o
mtodo descrito naquela classe, mesmo que o objeto seja uma subclasse. O jeito de mudar esse comportamento
usando mtodos virtuais. Considere a seguinte verso reescrita do ltimo exemplo:
Quando esse cdigo usado da mesma forma que antes, O mtodo "method_1" da SubClass ser chamado duas vezes.
Isso porque nos dissemos ao sistema que "method_1" um mtodo virtual, significando que se for sobreposto em uma
subclasse, essa nova verso sempre ser executada nas instncias dessa subclasse, independente do conhecimento do
instanciador.
Essa distino provavelmente familiar programadores de algumas linguagens, como C++, mas de fato o oposto do
estilo de linguagens como Java, no qual os passos devem ser tomados para prevenir que um mtodo seja virtual.
61
Polimorfismo
Voc provavelmente reconheceu tambm agora que quando um mtodo declarado como abstract ele tambm deve
ser virtual. Caso contrrio, no seria possvel executar dado mtodo numa instncia do tipo em que foi declarado. Quando
implementamos um mtodo abstrato numa subclasse, voc pode portanto escolher declarar a implementao como
override , assim passando a natureza do mtodo virtual, e permitindo que subtipos faam o mesmo se for desejado.
Tambm possvel implementar mtodos de interface de forma que as subclasses possam mudar a implementao. O
processo nesse caso declarar a implemetao inicial como mtodo virtual , e ento as subclasses podem sobrepor
quando necessrio.
Na hora de escrever uma classe, comum querer usar funcionalidades definida em uma classe que voc herdou. Isso
complicado quando o mesmo nome de mtodo usado mais de uma vez na arvore de heranas da sua classe. Para esse
propsito Vala prov a palavra chave base . O caso mais comum quando voc sobreps um mtodo virtual pra prover
funcionalidades extras, mas ainda quer que o mtodo da classe base seja chamado. O exemplo a seguir mostra esse
caso:
62
Ocultao de Mtodos
Ocultao de Mtodos
Ao usar o modificador new voc pode ocultar um mtodo herdado com um novo mtodo de mesmo nome. O novo
mtodo pode ter uma assinatura diferente. A ocultao de mtodos no deve ser confundida com a sobreposio de
mtodos(method overriding), porque a ocultao de mtodos no exibe comportamentos polimrficos.
Voc ainda pode chamar o mtodo original convertendo para a classe base ou interface:
void main() {
var bar = new Bar();
bar.my_method();
(bar as Foo).my_method();
}
63
Informao do tipo em tempo de execuo
Voc pode receber a informao de tipo de instncias Object com o mtodo get_type () :
Com o operador typeof () voc pode receber a informao de um tipo diretamente. Dessa informao de tipo voc pode
criar novas instncias com Object.new () :
Qual construtor ser chamado? o bloco constuct {} que ser descrito na seo sobre construes do estilo gobject.
64
Converso dinmica de tipo
Por exemplo,
Se por alguma razo a classe da instncia widget no a classe Button ou alguma de suas subclasses ou no
implementa a interface Button, b ser null . Essa converso equivalente :
65
Genricos
Genricos
Vala incli um sistema genrico de tempo de execuo, pelo qual uma particular instncia de uma classe pode ser restrita
com um tipo particular ou um conjunto de tipos escolhidos no tempo de construo. Essa restrio geralmente usada
para exigir que o dado guardado no objeto deve ser de um tipo particular, por exemplo a fim de implementar uma lista de
objetos de um certo tipo. No exemplo, Vala poderia ter certeza que somente o objeto de um tipo requerido pudesse ser
adicionado a lista, e que na reaquisio todos os objetos poderiam ser convertidos naquele tipo.
Em Vala, genricos so manipulados enquanto o programa est em execuo. Quando voc define uma classe que pode
ser restrito um tipo, existe apenas uma nica classe, com cada instncia personalizada individualmente. Isso contrasta
com C++ que cria uma nova classe para cada tipo de restrio requerido - um sistema similar a Vala usado em Java.
Isso tem vrias consequencias, as mais importantes: os membros estticos so compartilhados por um tipo como um todo,
independente das restries contidas em cada instncia, e dadas classe e subclasse, um genrico aprimorado por uma
subclasse pode ser usado como um genrico aprimorado pela classe.
O cdigo a seguir demonstra como utilizar o sistema genrico pra definir uma classe envoltria mnima(wrapper):
public G get_data() {
return this.data;
}
}
Essa classe "Wrapper" deve ser restrita com um tipo para ser instanciada - nesse caso o tipo ser identificado como "G", e
suas instncias de classe guardaro um objeto do tipo "G", e tero mtodos para receber ou enviar tal objeto. (A razo
para esse exemplo para explicar que atualmente uma classe genrica no pode usar propriedades de seu tipo restrito,
portanto invs disso essa classe tem mtodos get e set).
A fim de instnciar essa classe, um tipo deve ser escolhido, por exemplo o tipo embutido string (em Vala no existem
restries sobre quais tipos podem ser usados como genricos).
Como voc pode ver, quando o dado retornado do envoltrio, atribuido a um identificador sem tipo explicito. Isso
possvel porque Vala conhece o tipo de objeto que est em cada instncia do envoltrio, sendo assim ele pode fazer isso.
O fato que Vala no cria multiplas classes para voc pelas suas definies genricas significa que voc pode fazer o
cdigo a seguir:
void accept_object_wrapper(Wrapper<Glib.Object> w) {
}
...
var test_wrapper = new Wrapper<TestClass>();
accept_object_wrapper(test_wrapper);
...
66
Genricos
Desde que todas as instncias TestClass tambm so Object , o mtodo "accept_object_wrapper" ir aceitar qualquer
objeto que for passado, e tratar seus objetos envolvidos como instncias de GLib.Object .
67
Construo estilo GObject
propriedades de construo, uma chamada especial Object(...) e um bloco construct . Vamos dar uma olhada no
funcionamento:
/* Construction properties */
public string name { get; construct; }
public int age { get; construct set; }
construct {
// do anything else
stdout.printf("Welcome %s\n", this.name);
}
}
Com o esquema de construo do estilo GObject cada mtodo de construo s pode conter uma chamada Object (...)
para determinar os to falados propriedades de construo(construct properties). A chamada Object (...) recebe um
varivel nmero de argumentos nomeados na forma de propriedade: valor . Essas propriedades precisam ser declaradas
como construct ou set . Elas sero atribudas com os dados valores e depois todos blocos construct {} na hierarquia
do GLib.Object abaixo da nossa classe ser chamado.
O bloco construct garantido de ser chamadoquando uma instncia da classe criada, mesmo se ela for criada como
um subtipo. No tem parmetros ou retorno de valores. Dentro desse bloco voc pode chamar outros mtodos e atribuir
variveis membros que forem necessrias.
Propriedades de construo so definidas como propriedades get e set , e portanto podem executar cdigos arbitrrios
na atribuio. Se voc precisa fazer inicializaes baseado numa nica propriedade de construo, possvel escrever
um bloco construct personalizado para a propriedade, que ser executado imediatamente na atribuio, e antes de
outros cdigos de construo.
Se uma propriedade de construo declarada sem set ela ser uma to falada propriedade somente construo, que
significa que s pode ser atribuida na construo. No exemplo abaixo name uma propriedade somente construo.
Aqui temos um sumrio de vrios tipos de propriedades juntas com nomenclaturas usualmente encontradas na
documentao de bibliotecas baseadas em GObject.
68
Construo estilo GObject
Em alguns casos voc tambm vai querer executar algumas aes - no quando instncias das classes so criadas - mas
quando a classe propriamente dita criada na execuo dos GObject. Na terminologia dos GObject ns estamos falando
sobre os trechos de cdigo que rodam dentro da funo class_init para a classe em questo. Em Java isso conhecido
como static initializer blocks(Blocos de inicializao esttica). Em Vala isso se parece assim:
69
Recursos experimentais
Recursos esperimentais
Algumas caractersticas de Vala so experimentais. Isso significa que elas no esto totalmente testadas e podem estar
sujeitas a alteraes em verses futuras.
70
Relao encadeada
Relao encadeada
Este recurso permite que voc escreva expresses relacionais complexas como
if (0 < a && a < b && b < c && c < d && d < 255) {
// do something
}
if (1 < a < 5) {}
71
Expresso regular literal
O i direita faz com que a expresso no seja insensvel. Voc pode armazenar uma expresso regular em uma varivel
do tipo Regex:
var r = /(foo|bar|cow)/;
var o = r.replace ("this foo is great", -1, 0, "thing");
print ("%s\n", o);
m, as construes no "incio de linha" e no "fim de linha" coincidem imediatamente aps ou imediatamente antes de
qualquer nova linha na seqncia, respectivamente, bem como no incio e no final.
s, um metacaracter . No padro corresponde a todos os caracteres, incluindo nova linhas. Sem ele, as novas linhas
so excludas.
x, os caracteres de espao em branco no padro so totalmente ignorados, exceto quando escapados ou dentro de
uma classe de caracteres.
72
Modo no-nulo rigoroso
O compilador ir executar uma anlise de tempo de compilao esttica para garantir que nenhuma referncia nula seja
atribuda a uma referncia no-nula. Por exemplo, Isso no ser possvel:
o1 = o2;
o2 pode ser null e o1 foi declarado no-nulo, portanto, esta atribuio proibida. No entanto, voc pode substituir esse
comportamento com um elenco explcito no-nulo se tiver certeza de que o2 no nulo:
o1 = (!) o2;
Este modo rigoroso de no-nulo ajuda a evitar indesejaveis erros de derreferenciao em null(objetos nulos). Esse recurso
poderia chegar ao seu pleno potncial se a nulabilidade dos tipos de retorno nos bindings(vinculos de bibliotecas C)
fossem marcados corretamente, o que no sempre o caso.
73
Bibliotecas
Bibliotecas
A nvel do sistema, uma biblioteca Vala exatamente uma biblioteca C e, portanto, as mesmas ferramentas so usadas. A
fim de tornar o processo mais simples, e para que o compilador Vala possa entender o processo, h um nvel extra de
informaes especficas de Vala.
Esses arquivos sero explicados mais adiante nesta seo. Deve-se notar que os nomes das bibliotecas so os mesmos
nos arquivos especficos de Vala como nos arquivos pkg-config.
74
Usando bibliotecas
Usando bibliotecas
Usar uma biblioteca em Vala amplamente automatizado se voc usar o compilador valac. Os arquivos de biblioteca
especficos Vala compem o que conhecido como um pacote. Voc diz ao compilador que um pacote necessrio pelo
seu programa da seguinte maneira:
Este comando significa que seu programa pode usar qualquer uma das definies no arquivo gee-1.0.vapi, e tambm
qualquer em qualquer um dos pacotes que gee-1.0 depende. Essas dependncias seriam listadas em gee-1.0.deps se
houvesse alguma. Neste exemplo valac definido para construir todo o caminho para o binrio e, portanto, incorporar
informaes do pkg-config para ligar as bibliotecas corretas. por isso que os nomes do pkg-config tambm so usados
para nomes de pacotes Vala.
Os pacotes so geralmente usados com namespaces, mas no so tecnicamente relacionados. Isso significa que, mesmo
que seu aplicativo seja construdo com referncia ao pacote, voc ainda deve incluir as instrues using necessrias em
cada arquivo, conforme apropriado, ou usar os nomes totalmente qualificados de todos os smbolos.
Tambm possvel tratar uma biblioteca local (que no est instalada) como um pacote. Para comparao, a prpria Vala
usa uma verso interna de Gee. Quando o valac construdo ele cria um arquivo VAPI desta biblioteca interna e usa-o
aproximadamente da seguinte maneira:
Para obter detalhes sobre como gerar esta biblioteca, consulte a prxima seo ou o exemplo.
75
Criando uma biblioteca
76
Construindo bibliotecas com VAPI
Instrues especficas sobre como gerar bindings esto no Vala Bindings Tutorial
77
Ferramentas
Ferramentas
Vala possui vrios programas para ajud-lo a construir e trabalhar com aplicativos Vala. Para obter mais detalhes de cada
ferramenta, consulte o site.
valac
valac o compilador Vala. Sua funo principal transformar o cdigo Vala em cdigo C compilvel, embora tambm
possa automatizar todo o projeto de construo e link em casos simples.
Um exemplo simples:
O parmetro -o solicita que um arquivo de objeto seja criado, em vez de apenas produzir arquivos de origem C. A opo
--pkg diz que essa compilao precisa de informaes do pacote gee-1.0. No necessrio especificar detalhes sobre
quais bibliotecas ser necessrio vincular, o pacote tem essas informaes internamente. Finalmente, fornecida uma
lista de arquivos de origem. Se voc precisar de um processo de compilao mais complicado, use a opo -C para
gerar arquivos C em vez de um binrio e continuar o processo manualmente ou atravs de um script.
vapigen
vapigen uma ferramenta para fazer Bindings. Ele cria arquivos VAPI a partir de metadados de uma biblioteca e qualquer
informao extra necessria. Veja tambm Vala Bindings Tutorial.
78