Лекция: Дополнительные возможности системы Matlab.
#$+Объекты и классы. Переопределение операций.
MATLAB позволяет реализовать концепцию объектно-ориентированного программирования. В MATLAB можно создавать и манипулировать объектами, которые скрывают реальные данные за контролируемыми методами работы с ними, допускают переопределение операций и дают возможность наследовать их свойства производным объектам-потомкам. Однако, последний принцип объектно-ориентированного программирования, полиморфизм (возможность вызывать методы классов-потомков через интерфейсы базовых классов), в MATLAB не реализован. Конкретнее, в MATLAB нет ничего подобного механизму виртуальных функций в языке программирования C++.
Все пять основных типов MATLAB (числовые и разреженные массивы, массивы ячеек, структуры и текстовые строки) представляют собой встроенные классы, а переменные- объекты этих классов. Пользователь имеет возможность вводить свои классы, а также переопределять и доопределять методы всех существующих классов.
Для создания нового класса объектов нужно спроектировать структуру MATLAB, которая будет хранить данные, принадлежащие объекту, и определить функции-методы работы с этими объектами. Эти функции определяются в обычных М-файлах, которые должны быть помещены в специальную папку, имя которой начинается с символа '@', а в остальном должно совпадать с именем структуры (класса), причем эта папка должна входить в папку, определенную в пути MATLAB-path. Саму папку-контейнер методов добавлять в путь MATLAB не нужно.
Язык программирования MATLAB не имеет деклараций, в том числе деклараций новых классов и типов. Поэтому любой объект — представитель некоторого класса создается в момент вызова функции-конструктора этого класса. Следовательно, для создания объекта нужно создать хотя бы один метод (конструктор) в упомянутой папке-контейнере его класса.
Все поля структуры, хранящей данные класса являются скрытыми (private), то есть их поля доступны только из методов данного класса, напрямую в выражениях их использовать нельзя.
Рассмотрим пример конструктора, создающего объекты класса «полином». Этот конструктор должен находиться в файле @polynom/polynom.m.
function p = polynom(a)
%POLYNOM Polynomial class constructor.
% p = POLYNOM(v)
if nargin = = 0
p.c = [];
p = class(p, 'polynom');
elseif isa(a,'polynom')
p = a;
Else
p.c = a(:).';
p = class(p,'polynom');
End
Данный конструктор создает полином из заданного вектора, содержащего коэффициенты полинома при убывающих степенях x. Если же в конструктор не передавать никакого аргумента, то будет создан «пустой» полином.
Сначала в конструкторе проверяется количество аргументов, и если оно равно нулю, то создается пустой полином. Точнее, создается структура p, содержащая единственное поле c, которое и будет содержать пустой вектор коэффициентов полинома. Затем из этой структуры конструируется сам объект при помощи встроенной функции class(). У этой функции есть два обязательных параметра. Первый — структура, которая будет представлять данные объекта, а второй — текстовая строка, содержащая имя создаваемого класса. Оно должно совпадать с именем конструктора и папки, его содержащей (с добавлением символа '@' в начале имени папки).
Если при вызове конструктора аргумент был задан, то проверяется тип этого аргумента. В том случае, когда был задан объект того же класса (так называемый copy-constructor), создается его копия при помощи оператора присваивания. Проверка класса переданного объекта осуществляется по его имени, при помощи функции isa() (является).
Наконец, если передан был обычный массив, то он копируется в поле p.c создаваемой структуры и, затем, из нее конструируется объект класса так же, как и в первом случае.
Подобная последовательность действий является обязательной для конструктора объектов. Естественно, структура, хранящая данные объекта, может быть создана сколь угодно сложной — с произвольным набором полей.
Отметим, что за пределами методов данного класса, функциями class() и isa() тоже можно активно пользоваться. В этом случае, первая из них может принять только один аргумент — объект и возвращает текстовую строку — имя класса заданного объекта. Например, для заданного вещественного вектора эта функция вернет строку 'double'.
Часто бывает необходимо преобразовать объект одного класса к другому классу. Например, может понадобиться преобразовать созданный нами полином обратно в вектор его коэффициентов. Чтобы обеспечить такую возможность, нужно создать для исходного класса (полинома в нашем примере) специальную функцию-конвертор. Имя этой функции (и имя ее m-файла) должно совпадать с именем класса, к которому она будет преобразовывать исходный объект. Для нашего примера понадобиться следующая функция :
function c = double(p)
%@polynom/double.m.
c = p.c;
Теперь, в сессии MATLAB мы можем преобразовывать вектора в полиномы и обратно:
" P = polynom([1 -2 7]);
" double(p)
ans =
1 -2 7
Другим частым преобразованием является преобразование к текстовому виду (метод char()) для нужд распечатки объекта. В примере с полиномом этот метод (@polynom/char.m) мог бы порождать строку 'x^3 — 2*x + 7'.
Преобразование к тексту используется в другом методе, которой желательно реализовать в каждом создаваемом новом классе. Это метод display() — он вызывается всякий раз, когда MATLAB нужно распечатать содержимое объекта. Главным образом это происходит, когда в среде MATLAB введено выражение не завершенное точкой с запятой.