Предположим, что вы хотите переименовать свойство, но не хотите вызывать ошибки в существующем коде, которые относятся к исходному свойству. Например, переименуйте общественную собственность под названием OfficeNumber
к Location
. Вот исходное определение класса:
classdef EmployeeList properties Name Email OfficeNumber % Rename as Location end end
Использование скрытого зависимого свойства может достигнуть желаемых результатов.
В определении класса, устанавливает атрибуты свойства OfficeNumber
на Dependent
и Hidden
.
Создайте метод набора свойств для OfficeNumber
, который устанавливает значение свойства Location
.
Создайте свойство, получают метод для OfficeNumber
, который возвращает значение свойства местоположения Location
.
В то время как свойство OfficeNumber
скрыто, существующий код может продолжить получать доступ к этому свойству. Атрибут 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
только, чтобы гарантировать, что более старые сохраненные объекты осовременены при загрузке.
Класс PhoneBookEntry
использует комбинацию методов, чтобы поддержать совместимость с новыми версиями класса.
Предположим, что вы задаете класс, чтобы представлять запись в телефонной книге. Класс 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
Версия 2 класса PhoneBookEntry
В версии 2 класса PhoneBookEntry
вы разделяете свойство Address
в StreetAddress
, City
, State
и свойства ZipCode
.
С этими изменениями вы не могли загрузить объект версии 2 в предыдущем релизе. Однако версия 2 использует несколько методов, чтобы включить совместимость:
Сохраните свойство Address
(который используется в версии 1) как свойство Dependent
с частным SetAccess
.
Задайте свойство Address
, заставляют метод (get.Address
) создавать вектор char
, который совместим со свойством Address
версии 2.
Метод saveobj
вызывает метод get.Address
, чтобы присвоить данные объектов struct
, который совместим с предыдущими версиями. struct
продолжает иметь только поле Address
, созданное из данных в новом StreetAddress
, City
, State
и свойствах ZipCode
.
Когда метод loadobj
устанавливает свойство Address
, он вызывает метод набора свойств (set.Address
), который извлекает подстроки, требуемые StreetAddress
, City
, State
и свойствами ZipCode
.
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