Материалы, представленные в этом разделе, основаны на понимании следующей информации:
Списки управления доступом позволяют управлять доступом к определенным свойствам, методам и событиям классов. Списки управления доступом задают список классов, которым вы предоставляете доступ этим членам класса.
Этот метод обеспечивает большую гибкость и управление в проекте системы классов. Например, используйте списки управления доступом для определения отдельных классов, но не разрешайте доступ к членам класса из-за пределов системы классов.
Укажите классы, которым разрешен доступ к конкретному члену класса в операторе атрибута доступа представителя. Для примера:
methods (Access = {?ClassName1,?ClassName2,...})
Используйте класс meta.class
Объект для ссылки на классы в списке доступа. Чтобы задать несколько классов, используйте массив ячеек meta.class
объекты. Используйте имя пакета при обращении к классам, которые находятся в пакетах.
Примечание
Задайте meta.class
объекты явным образом (созданные с ?
оператор), а не как значения, возвращенные функциями или другими выражениями MATLAB.
Предоставление доступа к списку классов ограничивает доступ только к:
Определяющий класс
Классы в списке
Подклассы классов в списке
Включение определяющего класса в список доступа предоставляет все подклассы определяющего доступа к классу.
MATLAB разрешает ссылки на классы в списке доступа только при загрузке класса. Если MATLAB не может найти класс, включенный в список доступа, этот класс эффективно удаляется из доступа.
MATLAB заменяет неразрешенные meta.class
записи в списке с пустыми meta.class
объекты.
Пустой список доступа (то есть пустой массив ячеек) эквивалентен private
доступ.
Сгенерируйте meta.class
объекты, использующие только ?
оператор и имя класса. Значения, присвоенные атрибутам, не могут содержать никаких других выражений MATLAB, включая функции, которые возвращают разрешенные значения атрибутов:
meta.class
объекты
Массивы ячеек meta.class
объекты
Значения public
, protected
, или private
Задайте эти значения явно, как показано на примере кода в этом разделе.
Эти примеры классов показывают поведение свойства, которое предоставляет доступ для чтения (GetAccess
) к классу. The GrantAccess
класс дает GetAccess
на NeedAccess
класс для Prop1
свойство:
classdef GrantAccess properties (GetAccess = ?NeedAccess) Prop1 = 7 end end
The NeedAccess
класс задает метод, который использует значение GrantAccess
Prop1
значение. The dispObj
метод определяется как Static
метод, однако, может быть обычным методом.
classdef NeedAccess methods (Static) function dispObj(GrantAccessObj) disp(['Prop1 is: ',num2str(GrantAccessObj.Prop1)]) end end end
Получите доступ к Prop1
является частным, поэтому MATLAB возвращает ошибку, если вы пытаетесь получить доступ к свойству вне определения класса. Для примера из командной строки:
a = GrantAccess; a.Prop1
Getting the 'Prop1' property of the 'GrantAccess' class is not allowed.
Однако MATLAB позволяет доступ к Prop1
по NeedAccess
класс:
NeedAccess.dispObj(a)
Prop1 is: 7
Классы, которым предоставлен доступ к методу, могут:
Вызовите метод с помощью образца определяющего класса.
Задайте свой метод с таким же именем (если не подкласс).
Переопределите метод в подклассе, только если суперкласс, определяющий метод, включает сам себя или подкласс в список доступа.
Эти примеры классов показывают поведение методов, вызываемых из методов других классов, которые находятся в списке доступа. Класс AcListSuper
дает AcListNonSub
классовый доступ к своему m1
метод:
classdef AcListSuper methods (Access = {?AcListNonSub}) function obj = m1(obj) disp ('Method m1 called') end end end
Потому что AcListNonSub
находится в списке доступа m1
его методы могут вызывать m1
использование образца AcListSuper
:
classdef AcListNonSub methods function obj = nonSub1(obj,AcListSuper_Obj) % Call m1 on AcListSuper class AcListSuper_Obj.m1; end function obj = m1(obj) % Define a method named m1 disp(['Method m1 defined by ',class(obj)]) end end end
Создайте объекты обоих классов:
a = AcListSuper; b = AcListNonSub;
Вызовите AcListSuper
m1
метод с использованием AcListNonSub
метод:
b.nonSub1(a);
Method m1 called
Вызовите AcListNonSub
m1
метод:
b.m1;
Method m1 defined by AcListNonSub
Включение определяющего класса в список доступа для метода предоставляет доступ ко всем подклассам, выведенным из этого класса. Когда вы производите от класса, который имеет метод со списком доступа, и этот список не включает определяющий класс:
Методы подкласса не могут вызвать метод суперкласса.
Методы подкласса могут вызвать метод суперкласса косвенно с помощью образца класса, который находится в списке доступа.
Подклассы не могут переопределить метод суперкласса.
Методы классов, которые находятся в списке доступа метода суперкласса, но не являются подклассами, могут вызывать метод суперкласса.
Для примера, AcListSub
является подклассом AcListSuper
. The AcListSuper
класс определяет список доступа для метода m1
. Однако этот список не включает AcListSuper
, так подклассы AcListSuper
не имеют доступа к методу m1
:
classdef AcListSub < AcListSuper methods function obj = sub1(obj,AcListSuper_Obj) % Access m1 via superclass object (***NOT ALLOWED***) AcListSuper_Obj.m1; end function obj = sub2(obj,AcListNonSub_Obj,AcListSuper_obj) % Access m1 via object that is in access list (is allowed) AcListNonSub_Obj.nonSub1(AcListSuper_Obj); end end end
Попытка вызвать суперкласс m1
метод из sub1
метод приводит к ошибке, поскольку подклассы не находятся в списке доступа для m1
:
a = AcListSuper; c = AcListSub; c.sub1(a);
Cannot access method 'm1' in class 'AcListSuper'.
Error in AcListSub/sub1 (line 4)
AcListSuper_Obj.m1;
Можно вызвать суперкласс из подкласса, который не имеет доступа к этому методу, используя объект класса, который находится в списке доступа к суперклассу.
The AcListSub
sub2
метод вызывает метод класса (AcListNonSub
), который находится в списке доступа для m1
. Этот метод, nonSub1
, имеет доступ к суперклассу m1
метод:
a = AcListSuper; b = AcListNonSub; c = AcListSub; c.sub2(b,a);
Method m1 called
Когда подклассы не включены в список доступа для метода, эти подклассы не могут определять метод с таким же именем. Это поведение не совпадает со случаями, в которых метод Access
явно объявляется как private
.
Например, добавление следующего метода к AcListSub
при попытке создать экземпляр класса возникает ошибка определения класса.
methods (Access = {?AcListNonSub}) function obj = m1(obj) disp('AcListSub m1 method') end end
c = AcListSub;
Class 'AcListSub' is not allowed to override the method 'm1' because neither it nor its
superclasses have been granted access to the method by class 'AcListSuper'.
The AcListNonSub
класс находится в m1
список доступа к методу. Этот класс может задать метод, который вызывает m1
метод с использованием объекта AcListSub
класс. Пока AcListSub
не находится в списке доступа для метода m1
, это подкласс AcListSuper
.
Например, добавьте следующий метод к AcListNonSub
класс:
methods function obj = nonSub2(obj,AcListSub_Obj) disp('Call m1 via subclass object:') AcListSub_Obj.m1; end end
Вызов nonSub2
метод приводит к выполнению суперкласса m1
метод:
b = AcListNonSub; c = AcListSub; b.nonSub2(c);
Call m1 via subclass object: Method m1 called
Такое поведение согласуется с поведением любого объекта подкласса, который может заменить объект его суперкласса.
Класс, содержащий метод, объявленный как Abstract
- абстрактный класс. В обязанности подклассов входит реализация абстрактного метода с помощью сигнатуры функции, объявленной в определении класса.
Когда абстрактный метод имеет список доступа, только классы в списке доступа могут реализовать метод. Подкласс, которого нет в списке доступа, не может реализовать абстрактный метод, так что подкласс сам является абстрактным.