无需关注,原文查看
在类的属性中,有一些是属于中间变量,外部不需要知道这些数据的值,因此需要对访问的权限进行控制,避免一个类中的行为干涉到其他类,这样的方法也叫“封装”。
一般来说,权限分为三种,public(默认),private,和protected,public说明该属性全部可以直接访问,private说明该属性只能被该类中的方法访问,子类以及外界无法访问,protected说明该类方法和子类的类方法能够访问。
public属性
只要没有特别说明,都是公有属性,这时任何方式都可以访问。
private属性
% Point.m
classdef Point < handle
properties (Access = private) % 设置 x 为私有
x = 0
end
properties (Access = {?Point2} ) % 设置为仅 Point2类可访问
y = 0
end
properties (Hidden,Dependent) % s设置为隐藏
r
end
methods
function obj = Point(x,y) % 可以使用nargin得到复杂初始化
obj.x = x;
obj.y = y ;
end
function r = get.r(obj) % get方法获取r的信息
r = sqrt(obj.x^2+obj.y^2);
end
function set.x(obj,var) % 用set 方法可以限制随意赋值
if var >= 0
obj.x = var;
else
error('x应为正数');
end
end
end
end
function disp(obj)
disp(['三维坐标为(' num2str(obj.x) ',' num2str(obj.y) ',' num2str(obj.z) ')']);
end
出问题的在Point2中的disp方法,因为无法访问私有属性obj.x,但是不是说这个属性没有被继承,它还是存在于Point2中。
protected属性
classdef Point < handle
properties (Access = protected)
x = 0
end
properties (Access = {?Point2} )
y = 0
end
properties (Hidden,Dependent)
r
end
methods
normalize(obj);
function obj = Point(x,y) % 可以使用nargin得到复杂初始化
obj.x = x;
obj.y = y ;
end
function disp(obj) % 自定义显示方法
disp( ['obj.disp was called.'])
end
function r = get.r(obj) % get方法获取r的信息
r = sqrt(obj.x^2+obj.y^2);
end
function set.x(obj,var) % 用set 方法可以限制随意赋值
if var >= 0
obj.x = var;
else
error('x应为正数');
end
end
end
end
此时disp方法不会出错,因为子类能够访问protected属性
但是在类的外部是无法访问到x的。
Hidden和 Dpendent属性
Hidden表示隐藏属性,不影响访问,只是在disp显示的时候默认不会显示出来,这个用于隐藏不重要的信息,不希望显示出来。Dpendent属性不会分配内存,只会在需要它的时候才会计算出来,需要和get方法一起用。以上面的 r 为例,r是二维点到原点的距离,不用赋初始值,在访问它的时候才会计算出来。 set和get方法以后再讲。
function r = get.r(obj) % get方法获取r的信息
r = sqrt(obj.x^2+obj.y^2);
end
上面我们可以看到 x和y都不是公有属性所以不会被显示,但是r并没有声明成私有或保护,也不会被显示,因为在类定义中其被声明成了 Hidden,不会被显示到外界,但是依然可以访问。
更细致的权限控制
- 只允许指定类可以访问,对其他类和外界为私有
properties (Access = {?Point2} )
- 只允许访问不允许修改
properties (SetAccess = private )
- 只允许修改不允许访问
properties (GetAccess = private )
上面只是将 Get和Set权限分开了,也可以设置成private和protected以及指定类访问。