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