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