Предположим, что вы хотите переименовать свойство, но не хотите вызывать ошибки в существующем коде, которые относятся к исходному свойству. Например, переименуйте общественную собственность под названием 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 элементами.
Можно вместить это изменение путем реализации a 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
сохраняет данные о свойстве в a 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
свойство.
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