主要内容

类成员访问

基本知识

本节所介绍的材料建立在对以下信息的理解基础上:

相关的话题

术语和概念

访问类成员的可能值

访问控制列表的应用程序

访问控制列表使您能够控制对特定类属性、方法和事件的访问。访问控制列表指定一个类列表,您可以向这些类成员授予访问权。

这种技术在类系统的设计中提供了更大的灵活性和控制。例如,使用访问控制列表定义单独的类,但不允许从类系统外部访问类成员。

指定对类成员的访问

在成员访问属性语句中指定允许访问特定类成员的类。例如:

方法(Access = {?ClassName1,?ClassName2,……})

使用课程meta.class对象引用访问列表中的类。要指定多个类,请使用单元格数组meta.class对象。在引用包中的类时使用包名。

请注意

指定meta.class对象(使用?operator),而不是函数或其他MATLAB表达式返回的值。

如何MATLAB解释属性值

  • 授予对类列表的访问权限仅限制访问:

    • 定义类

    • 列表中的类

    • 列表中类的子类

  • 在访问列表中包含定义类将给出定义类访问的所有子类。

  • MATLAB仅在类加载时才解析访问列表中的类引用。如果MATLAB无法找到包含在访问列表中的类,则该类将有效地从访问中删除。

  • MATLAB取代未解决的问题meta.class列表中的项为空meta.class对象。

  • 空访问列表(即空单元格数组)相当于私人访问。

指定元类对象

生成meta.class对象,只使用?操作符和类名。赋给属性的值不能包含任何其他MATLAB表达式,包括返回允许属性值的函数:

  • meta.class对象

  • 单元格阵列meta.class对象

  • 的值公共受保护的,或私人

显式地指定这些值,如本节中的示例代码所示。

带有访问列表的属性

这些示例类显示授予读访问权限的属性的行为(GetAccess)到一个班级。的GrantAccess类提供了GetAccessNeedAccess类的Prop1属性:

classdefGrantAccess属性(GetAccess = ?NeedAccess) Prop1 = 7结束结束

NeedAccess类定义了一个方法,该方法使用GrantAccessProp1价值。的dispObj方法定义为静态方法,但是,它可以是一个普通的方法。

classdefNeedAccess方法(静态)函数dispObj (GrantAccessObj) disp ([Prop1是:num2str (GrantAccessObj.Prop1)])结束结束结束

获得访问Prop1是私有的,因此如果您试图从类定义之外访问属性,MATLAB将返回一个错误。例如,在命令行中:

a = GrantAccess;a.Prop1
不允许获取“GrantAccess”类的“Prop1”属性。

但是,MATLAB允许访问Prop1NeedAccess类:

NeedAccess.dispObj (a)
Prop1是:7

具有访问列表的方法

被授予方法访问权的类可以:

  • 使用定义类的实例调用该方法。

  • 定义自己同名的方法(如果不是子类的话)。

  • 仅当定义方法的超类在访问列表中包含方法本身或子类时,才在子类中重写方法。

这些样例类显示了从访问列表中其他类的方法调用的方法的行为。类AcListSuper给出了AcListNonSub类的访问m1方法:

classdefAcListSuper方法Access = {?AcListNonSub})函数Obj = m1(Obj) disp (方法m1被调用结束结束结束

因为AcListNonSub的访问列表中m1,其方法可以调用m1的实例AcListSuper

classdefAcListNonSub方法函数obj = nonSub1(obj,AcListSuper_Obj)在AcListSuper类上调用m1AcListSuper_Obj.m1;结束函数Obj = m1(Obj)定义一个名为m1的方法disp ([方法m1定义为类(obj)])结束结束结束

创建两个类的对象:

a = AcListSuper;b = AcListNonSub;

调用AcListSuperm1方法使用AcListNonSub方法:

b.nonSub1(一个);
方法m1调用

调用AcListNonSubm1方法:

b.m1;
由AcListNonSub定义的方法m1

不可访问的子类

在方法的访问列表中包含定义类将授予对从该类派生的所有子类的访问权。当你从一个类中派生出一个带有访问列表的方法,而这个列表也有包括定义类:

  • 子类方法不能调用父类方法。

  • 子类方法可以使用访问列表中的类实例间接调用父类方法。

  • 子类不能重写父类方法。

  • 在超类方法访问列表中,但不是子类的类的方法可以调用超类方法。

例如,AcListSub的子类AcListSuper.的AcListSuper类定义方法的访问列表m1.但是,这个列表不包括AcListSuper的子类AcListSuper没有获取方法m1

classdefAcListSub < AcListSuper方法函数obj = sub1(obj,AcListSuper_Obj)通过超类对象访问m1(***不允许***)AcListSuper_Obj.m1;结束函数obj = sub2(obj,AcListNonSub_Obj,AcListSuper_obj)%通过访问列表中的对象访问m1(允许)AcListNonSub_Obj.nonSub1 (AcListSuper_Obj);结束结束结束

不直接调用超类方法

试图调用超类m1方法。sub1方法的访问列表中没有子类,因此将导致错误m1

a = AcListSuper;c = AcListSub;c.sub1(一个);
不能访问类“AcListSuper”中的方法“m1”。AcListSub/sub1错误(第4行);

间接调用超类方法

可以使用父类方法访问列表中的类的对象,从无权访问该方法的子类调用父类方法。

AcListSubsub2方法调用类的方法(AcListNonSub)的访问列表m1.这种方法,nonSub1,具有对超类的访问权限m1方法:

a = AcListSuper;b = AcListNonSub;c = AcListSub;c.sub2 (b);
方法m1调用

没有重定义超类方法

当一个方法的访问列表中没有包含子类时,这些子类不能定义同名的方法。这种行为与该方法的情况不同访问显式声明为私人

方法中添加以下方法AcListSub类定义在尝试实例化类时产生错误。

方法Access = {?AcListNonSub})函数Obj = m1(Obj) disp(“AcListSub m1方法”结束结束
c = AcListSub;
类'AcListSub'不允许重写方法'm1',因为它和它的超类都没有被类'AcListSuper'授予对方法的访问权。

从列出的类通过子类调用超类

AcListNonSub类在m1方法访问列表。类可以定义调用m1方法的对象AcListSub类。而AcListSub不在方法的访问列表中m1的子类AcListSuper

例如,将以下方法添加到AcListNonSub类:

方法函数obj = nonSub2(obj,AcListSub_Obj) disp(通过子类对象调用m1:) AcListSub_Obj.m1;结束结束

调用nonSub2方法导致执行超类m1方法:

b = AcListNonSub;c = AcListSub;b.nonSub2 (c);
通过子类对象调用m1:方法m1被调用

此行为与任何子类对象的行为一致,子类对象可以替代其超类的对象。

带有访问列表的抽象方法

包含声明为方法的类摘要是一个抽象类。子类负责使用类定义中声明的函数签名实现抽象方法。

当抽象方法具有访问列表时,只有访问列表中的类才能实现该方法。不在访问列表中的子类不能实现抽象方法,因此该子类本身是抽象的。

相关的话题