Предположим, что вы хотите переименовать свойство, но не хотите вызывать ошибок в существующем коде, которые ссылаются на исходное свойство. Для примера переименуйте общественную собственность под названием OfficeNumber
на Location
. Вот исходное определение класса:
classdef EmployeeList properties Name Email OfficeNumber % Rename as Location end end
Использование скрытого зависимого свойства может достичь желаемых результатов.
В определении класса установите OfficeNumber
атрибуты свойств к Dependent
и Hidden
.
Создайте метод набора свойств для OfficeNumber
который устанавливает значение Location
свойство.
Создайте метод получения свойств для OfficeNumber
который возвращает значение Location
свойство местоположения.
В то время как OfficeNumber
свойство скрыто, существующий код может продолжить доступ к этому свойству. The Hidden
атрибут не влияет на доступ.
Потому что OfficeNumber
является зависимым, нет избыточности в хранилище, требуемой путем добавления нового свойства. MATLAB® не хранит и не сохраняет зависимые свойства.
Вот обновленное определение класса.
classdef EmployeeList properties Name Email Location end properties (Dependent, Hidden) OfficeNumber end methods function obj = set.OfficeNumber(obj,val) obj.Location = val; end function val = get.OfficeNumber(obj) val = obj.Location; end end end
EmployeeList
ОбъектыМожно загрузить старые образцы EmployeeList
класс при наличии новой версии класса. Код, который относится к OfficeNumber
свойство продолжает работать.
Предположим, что вы хотите иметь возможность загружать новые EmployeeList
объекты в системы, которые все еще имеют старую версию EmployeeList
класс. Для достижения совместимости со старыми и новыми версиями:
Определите OfficeNumber
свойство как Hidden
, но не Dependent
.
Определите Location
свойство как Dependent
.
В этой версии EmployeeList
класс, OfficeNumber
свойство сохраняет значение, используемое Location
свойство. При загрузке объекта присваиваются значения трех исходных свойств (Name
, Email
, и OfficeNumber
), но не присваивает значение новому Location
свойство. Отсутствие Location
свойство в определении старого класса не является проблемой.
classdef EmployeeList properties Name Email end properties (Dependent) Location end properties (Hidden) OfficeNumber end methods function obj = set.Location(obj,val) obj.OfficeNumber = val; end function val = get.Location(obj) val = obj.OfficeNumber; end end end
Предположим, что вы изменяете класс так, чтобы значение свойства изменялось в его форме или типе. Ранее сохраненные объекты класса должны быть обновлены при загрузке, чтобы иметь соответствующее значение свойства.
Рассмотрим класс, который имеет AccountID
свойство. Предположим, что все номера счетов должны мигрировать с восьмизначных числовых значений на 12-элементные символьные массивы.
Вы можете принять это изменение путем реализации loadobj
способ.
loadobj
метод:
Тесты, чтобы определить, является ли load
функция прошла struct
или объект. Все loadobj
методы должны обрабатывать оба struct
и объект, когда есть ошибка в load
.
Тесты, чтобы определить, AccountID
ли номер содержит восемь цифр. Если это так, измените его на 12-элементный символьный массив путем вызова
paddAccID
способ.
После обновления AccountID
свойство, loadobj
возвращает MyAccount
объект, который MATLAB загружает в рабочую область.
classdef MyAccount properties AccountID end methods function obj = padAccID(obj) ac = obj.AccountID; acstr = num2str(ac); if length(acstr) < 12 obj.AccountID = [acstr,repmat('0',1,12-length(acstr))]; end end end methods (Static) function obj = loadobj(a) if isstruct(a) obj = MyAccount; obj.AccountID = a.AccountID; obj = padAccID(obj); elseif isa(a,'MyAccount') obj = padAccID(a); end end end end
Вам не нужно реализовывать saveobj
способ. Вы используете loadobj
только для обеспечения актуальности старых сохраненных объектов во время загрузки.
The PhoneBookEntry
класс использует комбинацию методов для поддержания совместимости с новыми версиями класса.
Предположим, что вы задаете класс, который будет представлять запись в телефонной книге. The PhoneBookEntry
класс задает три свойства: Name
, Address
, и PhoneNumber
.
classdef PhoneBookEntry properties Name Address PhoneNumber end end
Однако в будущих релизах класс добавляет больше свойств. Для обеспечения гибкости, PhoneBookEntry
сохраняет данные о свойствах в struct
используя его saveobj
способ.
methods function s = saveobj(obj) s.Name = obj.Name; s.Address = obj.Address; s.PhoneNumber = obj.PhoneNumber; end end
loadobj
метод создает PhoneBookEntry
объект, который затем загружается в рабочую область.
methods (Static) function obj = loadobj(s) if isstruct(s) newObj = PhoneBookEntry; newObj.Name = s.Name; newObj.Address = s.Address; newObj.PhoneNumber = s.PhoneNumber; obj = newObj; else obj = s; end end end
PhoneBookEntry
КлассВ версии 2 PhoneBookEntry
класс, вы разделяете Address
свойство в StreetAddress
, City
, State
, и ZipCode
свойства.
С этими изменениями вы не смогли загрузить объект версии 2 в предыдущем релизе. Однако в версии 2 используется несколько методов для обеспечения совместимости:
Сохраните Address
свойство (которое используется в версии 1) как Dependent
свойство с частными SetAccess
.
Задайте Address
Метод получения свойств (get.Address
) для создания char
вектор, совместимый с версией 2 Address
свойство.
The saveobj
метод вызывает get.Address
метод для назначения данных объекта struct
совместим с предыдущими версиями. The struct
продолжает иметь только Address
поле, построенное из данных в новой StreetAddress
, City
, State
, и ZipCode
свойства.
Когда loadobj
метод устанавливает Address
свойство, оно вызывает метод набора свойств (set.Address
), который извлекает подстроки, требуемые StreetAddress
, City
, State
, и ZipCode
свойства.
The Transient
(не сохранено) свойство SaveInOldFormat
позволяет вам задать, сохранять ли объект версии 2 как struct
или объект.
classdef PhoneBookEntry properties Name StreetAddress City State ZipCode PhoneNumber end properties (Constant) Sep = ', ' end properties (Dependent, SetAccess=private) Address end properties (Transient) SaveInOldFormat = false; end methods (Static) function obj = loadobj(s) if isstruct(s) obj = PhoneBookEntry; obj.Name = s.Name; obj.Address = s.Address; obj.PhoneNumber = s.PhoneNumber; else obj = s; end end end methods function address = get.Address(obj) address = [obj.StreetAddress,obj.Sep,obj.City,obj.Sep,... obj.State,obj.Sep,obj.ZipCode]; end function obj = set.Address(obj,address) addressItems = regexp(address,obj.Sep,'split'); if length(addressItems) == 4 obj.StreetAddress = addressItems{1}; obj.City = addressItems{2}; obj.State = addressItems{3}; obj.ZipCode = addressItems{4}; else error('PhoneBookEntry:InvalidAddressFormat', ... 'Invalid address format.'); end end function s = saveobj(obj) if obj.SaveInOldFormat s.Name = obj.Name; s.Address = obj.Address; s.PhoneNumber = obj.PhoneNumber; end end end end