Материал, представленный в этом разделе, основывается на понимании следующей информации:
Списки управления доступом позволяют вам управлять доступом к определенным свойствам класса, методам и событиям. Списки управления доступом задают список классов, к которым вы предоставляете доступ к этим членам класса.
Этот метод обеспечивает большую гибкость и управление в дизайне системы классов. Например, используйте списки управления доступом, чтобы задать отдельные классы, но не предоставить доступ к членам класса снаружи системы класса.
Задайте классы, которым позволяют получить доступ к конкретному члену класса в членском операторе атрибута доступа. Например:
methods (Access = {?ClassName1,?ClassName2,...})
Используйте класс объект meta.class
относиться к классам в списке доступа. Чтобы задать больше чем один класс, используйте массив ячеек объектов meta.class
. Используйте имя пакета при обращении к классам, которые находятся в пакетах.
Задайте объекты meta.class
явным образом (созданный с оператором ?
), не как значения, возвращенные функциями или другими выражениями MATLAB.
Предоставление доступа к списку классов ограничивает доступ к только:
Класс определения
Классы в списке
Подклассы классов в списке
Включая класс определения в списке доступа дает все подклассы доступа к классу определения.
MATLAB разрешает ссылки на классы в списке доступа только, когда класс загружается. Если MATLAB не может найти класс, который включен в список доступа, тот класс эффективно удален из доступа.
MATLAB заменяет неразрешенные записи meta.class
в списке с пустыми объектами meta.class
.
Пустой список доступа (то есть, массив пустой ячейки) эквивалентен доступу private
.
Сгенерируйте объекты meta.class
с помощью только оператор ?
и имя класса. Значения, присвоенные атрибутам, не могут содержать никакие другие выражения MATLAB, включая функции, которые возвращают позволенные значения атрибута:
объекты метакласса
Массивы ячеек объектов meta.class
Значения public
, protected
или private
Задайте эти значения явным образом, как показано в примере кода в этом разделе.
Эти демонстрационные классы показывают поведение свойства что доступ для чтения предоставлений (GetAccess
) к классу. Класс GrantAccess
дает GetAccess
классу NeedAccess
для свойства Prop1
:
classdef GrantAccess properties (GetAccess = ?NeedAccess) Prop1 = 7 end end
Класс NeedAccess
задает метод, который использует значение значения Prop1
GrantAccess
. Метод 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
к itsm1
методу:
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;
Вызовите метод m1
AcListSuper
с помощью метода AcListNonSub
:
b.nonSub1(a);
Method m1 called
Вызовите метод m1
AcListNonSub
:
b.m1;
Method m1 defined by AcListNonSub
Включая класс определения в списке доступа для метода предоставляет доступ ко всем подклассам, выведенным от того класса. Когда вы выводите от класса, который имеет метод со списком доступа, и тот список не включает класс определения:
Методы подклассов не могут вызвать метод суперкласса.
Методы подклассов могут вызвать метод суперкласса косвенно с помощью экземпляра класса, который находится в списке доступа.
Подклассы не могут заменить метод суперкласса.
Методы классов, которые находятся в списке доступа метода суперкласса, но которые не являются подклассами, могут вызвать метод суперкласса.
Например, AcListSub
является подклассом AcListSuper
. Класс 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;
Можно вызвать метод суперкласса от подкласса, который не имеет доступа к тому методу с помощью объекта класса, который находится в списке доступа метода суперкласса.
Вызовы метода sub2
AcListSub
метод класса (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'.
Класс 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
, является абстрактным классом. Это - ответственность подклассов реализовать абстрактный метод с помощью функциональной подписи, объявленной в определении класса.
Когда абстрактный метод имеет список доступа, только классы в списке доступа могут реализовать метод. Подкласс, который не находится в списке доступа, не может реализовать абстрактный метод так, чтобы подкласс был самостоятельно абстрактен.