Содержание


Обзор языка программирования Vala

Часть 2. Объектно-ориентированное программирование на языке Vala

Comments

Серия контента:

Этот контент является частью # из серии # статей: Обзор языка программирования Vala

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Обзор языка программирования Vala

Следите за выходом новых статей этой серии.

Классы и интерфейсы

Синтаксис определения класса, как ссылочного типа данных, типичен для объектно-ориентированных языков:

class <имя_класса> : <имя_супер_класса>, <имя_интерфейса>
{
  ...
}

Интерфейс не позволяет напрямую создавать свои экземпляры – требуется реализация его абстрактных методов. Определение интерфейса:

interface <имя_интерфейса> : <имя_супер_интерфейса>
{
  ...
}

Пространства имён

Реализация концепции пространства имён практически не отличается от реализации в родственных языках, таких как C++ и C#.

namespace NS_Name { ... }

определяет пространство имён NS_Name. Внутри фигурных скобок может содержаться любой код за исключением директив using.

Пространства имён могут быть вложенными:

namespace NS_Name1
{
  namespace NS_Name2
  {
    ...
  }
}

В этом случае префикс-квалификатор записывается как "NS_Name1.NS_Name2".

Делегаты

Делегат – это особый тип указателя на функцию, обеспечивающий передачу фрагмента кода как объекта. Ключевое слово delegate позволяет определить тип для функций с заданной сигнатурой. Например, для функций, принимающих целочисленный аргумент и не возвращающих значения, можно создать тип-делегат:

delegate void DlgType( int a );

После этого делегат используется следующим образом:

void fun1( int a ) { stdout.printf("%d\n",a); } // требуемая сигнатура
...
void fun2( DlgType d, int a ) // функция использует делегат
{
  d(a);
}
...
fun2( fun1, 3 );

При вызове функции fun2 ей передаётся указатель на функцию fun1 и числовое значение 3. Далее в теле fun2 вызывается через делегата функция fun1, которой передаётся числовое значение.

Также вы можете создавать локальные переменные этого типа:

DlgType d1 = fun1;   // инициализация ссылкой на функцию с требуемой сигнатурой
DlgType d2 = (a)=>{stdout.printf("%d\n",a);} // инициализация ссылкой на ламбда-функцию

Пример программы

Перейдём к практике. Рассматриваемый ниже исходный код взят с авторского сайта Vala и слегка подкорректирован для удобства работы. Это программа просмотра текстовых файлов в отдельном окне с панелью инструментов, панелями прокрутки и всплывающим окном выбора файла, в общем, со всеми элементами графического интерфейса пользователя.

01: using Gtk;
02:
03: public class TextFileViewer : Window
04: {
05:   private TextView text_view;
06:
07:   public TextFileViewer() 
08:   {
09:     this.title = "Просмотр текстового файла";
10:     this.position = WindowPosition.CENTER;
11:     set_default_size( 500, 400 );
12:
13:     var toolbar = new Toolbar();
14:     var open_button = new ToolButton.from_stock( STOCK_OPEN );
15:     toolbar.add( open_button );
16:     open_button.clicked.connect( on_open_clicked );
17:
18:     this.text_view = new TextView();
19:     this.text_view.editable = false;
20:     this.text_view.cursor_visible = false;
21:
22:     var scroll = new ScrolledWindow( null, null );
23:     scroll.set_policy( PolicyType.AUTOMATIC, PolicyType.AUTOMATIC );
24:     scroll.add( this.text_view );
25:
26:     var vbox = new VBox( false, 0 );
27:     vbox.pack_start( toolbar, false, true, 0 );
28:     vbox.pack_start( scroll, true, true, 0 );
29:     add( vbox );
30:   }
31:
32:   private void on_open_clicked() 
33:   {
34:     var file_chooser = new FileChooserDialog( "Открыть файл", this,
                                 FileChooserAction.OPEN,
                                 STOCK_CANCEL, ResponseType.CANCEL,
                                 STOCK_OPEN, ResponseType.ACCEPT, null );
35:     if( file_chooser.run() == ResponseType.ACCEPT ) 
36:     {
37:       open_file( file_chooser.get_filename() );
38:     }
39:     file_chooser.destroy();
40:   }
41:
42:   private void open_file( string filename ) 
43:   {
44:     try 
45:     {
46:       string text;
47:       size_t size;
48:       FileUtils.get_contents( filename, out text, out size );
49:       this.text_view.buffer.set_text( text, (int) size );
50:     } catch( Error e ) 
51:       {
52:         stderr.printf( "Ошибка: %s\n", e.message );
53:       }
54:   }
55:
56:   public static int main( string[] args ) 
57:   {
58:     Gtk.init( ref args );
59:     var window = new TextFileViewer();
60:     window.destroy.connect( Gtk.main_quit );
61:     window.show_all();
62:     Gtk.main();
63:     return 0;
64:   }
65: }

При компиляции потребуется библиотека gtk+, поэтому необходимо проверить, установлена ли она в вашей системе.

Важное замечание: документацию (на английском языке) по всем классам, методам и атрибутам, используемым в данной программе, можно найти на специализированном сайте документации по Vala (слева в списке пакетов-библиотек выберите тот, который вам нужен). Например, в нашем случае следует обратиться к странице по gtk+-2.0, найти на ней класс Window и т.д. Полезную информацию также можно извлечь из файлов описания API-интерфейсов (код на языке C), расположенных в каталоге /usr/share/vala/vapi.

После директивы, объявляющей использование библиотеки Gtk (строка 1), начинается определение класса с открытым доступом (public) TextFileViewer, являющегося подклассом Window (строка 3).

Наш новый тип объекта – класс TextFileViewer – содержит один закрытый (private) член-переменную text_view (строка 5) и четыре члена-метода, из которых два являются открытыми (public) – конструктор TextFileViewer (строка 7) и точка входа в программу main (строка 56) – и два закрытыми (private), недоступными извне – функции on_open_clicked (строка 32) и open_file (строка 42). По их именам можно понять, что они делают.

Те, кто знаком с языками C++ и C#, обратят внимание на отсутствие деструктора. Дело в том, что задачу управления памятью Vala берет на себя, но при необходимости вы можете написать собственный деструктор. Синтаксис точно такой же, как в упомянутых выше языках: префикс "тильда" (~) и имя класса. В рассматриваемом примере деструктор выглядел бы так:

~TextFileViewer() { ... }

В методах часто используется ключевое слово this, известное всем ОО-программистам, которое позволяет ссылаться на текущий объект, конкретный экземпляр данного класса.

В строках 9–11 определяются характеристики окна: заголовок, положение, размеры.

Строки 13–16 – создание панели инструментов и размещение на ней кнопки открытия файла. Здесь следует отметить функцию связывания события "щелчок по кнопке" и метода обработки этого события on_open_clicked (строка 16).

В строках 18–20 внутренняя переменная класса text_view инициализируется вновь создаваемым объектом TextView – панелью просмотра текста, без возможности редактирования и без вывода курсора.

Панель с возможностью прокрутки в обоих направлениях (ScrolledWindow) создаётся и связывается с только что организованной областью просмотра текста в строках 22–24.

Далее в строках 26–29 создаётся контейнер VBox. В него упаковывается сначала панель инструментов (строка 27), заполняющая всё пространство по ширине, но без возможности увеличения размера по вертикали, затем панель просмотра текста с прокруткой (строка 28), которая заполняет всю ширину контейнера и может увеличивать свой размер по вертикали. Созданный контейнер вписывается в главное окно приложения.

Со строки 32 начинается метод-обработчик щелчка по кнопке. Здесь создаётся, инициализируется и запускается панель выбора открываемого файла, в которой можно либо выбрать нужный файл и щёлкнуть по кнопке Open (Открыть), либо отказаться от выбора, щёлкнув по кнопке Cancel (Отмена). В любом случае эта панель закрывается, а соответствующий объект удаляется (строка 39).

Строки 42–54 – метод open_file, непосредственно выполняющий процедуру открытия заданного файла. Отметим, что вызывается этот метод из предыдущей функции on_open_clicked (см. строку 37).

Завершающим в определении класса является "главный" метод main – точка входа в программу (строки 56–64). Разумеется, он должен быть общедоступным (public). Здесь инициализируется Gtk-среда (строка 58), создаётся экземпляр нашего класса (строка 59), выполняется связывание закрытия и удаления данного окна с gtk-функцией завершения приложения (строка 60), активизируются и выводятся все элементы в иерархии контейнера (строки 61 и 62).

Компиляция программы выполняется с помощью команды:

valac --pkg gtk+-2.0 text-file-viewer.vala

Отметим использование ключа компилятора --pkg, который позволяет включить в программу vapi-интерфейсы для связывания с соответствующим пакетом. В данном случае включается файл gtk+-2.0.vapi, обеспечивающий связь с библиотекой gtk+.

Ниже приведены иллюстрации работы программы в среде Gnome (рисунки 1–3).

Рисунок 1. Окно программы после запуска
Рисунок 1. Окно программы после запуска
Рисунок 1. Окно программы после запуска
Рисунок 2. Панель выбора файла
Рисунок 2. Панель выбора файла
Рисунок 2. Панель выбора файла
Рисунок 3. Просмотр текстового файла
Рисунок 3. Просмотр текстового файла
Рисунок 3. Просмотр текстового файла

Впрочем, если у вас установлены все требуемые библиотеки, то программа будет работать и в среде KDE (рисунок 4).

Рисунок 4. Просмотр текстового файла в KDE
Рисунок 4. Просмотр текстового файла в KDE
Рисунок 4. Просмотр текстового файла в KDE

Подводя итог, можно отметить лаконичность и компактность исходного кода, которую обеспечивает язык Vala при написании объектно-ориентированных программ с графическим интерфейсом, а также "защиту" прикладного разработчика от необходимости разбора многочисленных деталей реализации этого интерфейса.

Заключение

Итак, мы изучили возможности объектно-ориентированного программирования в языке Vala. Следующая, заключительная статья цикла будет посвящена расширенным возможностям языка, а также применению штатных инструментальных средств и утилит.


Ресурсы для скачивания


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux
ArticleID=466536
ArticleTitle=Обзор языка программирования Vala: Часть 2. Объектно-ориентированное программирование на языке Vala
publish-date=02042010