matlab_OOP

Posted on Oct 22, 2021

[toc]

matlab中面向对象程序设计

统一建模语言(UML):Unified Modeling Language:对程序的一种图像表达方式,matlab要求每个类的定义保存为一个同名的文件,在matlab中建立实体对象的方式是:调用类的构造函数(Constructor)。构造函数和类同名;构造函数返回值构造出来的新的对象。

classdef Point2D < handle
	properties
	end
	methods
	end
end

类定义中包含一个属性block和一个方法block

constructor构造方法:负责产生并返回类的对象,通常还可以用来初始化对象的属性。

类的属性

  • 使用dot运算符来访问对象的属性
  • 属性的默认值(DefaultValue):在property定义中 直接赋值,或使用表达式赋值,在类定义在matlab装载时执行一次,还可以在constructor对属性变量做初始化。
  • 常量(Constant)属性:在对象生存周期中值保持不变的属性
classdef A < handle
	properties(Constant)
		R = pi / 180
	end
end

如果不显示给定常量属性一个特定的值,则默认为empty double,另,constant property不用创建对象就可以直接使用类中的常量。

A.R % A是类名而不是对象名
  • 非独立(Dependenet)属性:其值依赖于其他的属性,一旦其他属性改变,该属性也做相应的变化。对象内部没有给属性分配物理存储空间,每次该属性被访问时,其值将被动态地计算,方法由get提供。
classdef Point2D < handle
	properties
		x
		y
	end
	properties(Dependent)
		r
	end
	methods
		function obj = Point2D(x0, y0)
			obj.x = x0;
			obj.y = y0;
		end
		function r = get.r(obj) 	% Dependent 属性要放在get方法中
			r = sqrt(obj.x^2 + obj.y^2);
			disp('get.r called');
		end
	end
end

设置为dependent好处:支持dot和向量化操作,若r是一个matrix或vector,在类的外部,可以直接进行矢量操作;若r是一个结构体,可以直接使用dot访问r内部的其他fields。

classdef View < handle
	properties
		hFig
		hEdit
	end
	properties(Dependent)
		text
	end
	methods
		function obj = View()
			obj.hFig = figure();
			obj.hEdit = uicontrol('style','edit','parent',obj.hFig);
		end
		function str = get.text(obj)
			str = get(obj.hEdit, 'String');
		end
	end
end
  • 隐藏(Hiidden)属性

隐藏的效果是在命令行中查看对象的信息时,该属性不会被显示出来。(隐藏类的内部细节)

classdef A < handle
	properties(Hidden)
		var
	end
	methods(Hidden)
		function internalFunc(obj)
			disp('I am a hidden function');
		end
	end
end

类的方法

  • 调用类的方法:1. 使用OOP的dot语法obj.normalize(); 2. 使用传统的函数语法调用成员normalize(obj)
  • 点调用和函数式低矮用类方法区别
    1. p1.normalize符合面向对象风格,程序的可读性高;
    2. 使用dot语法清楚地告诉matlab要调用的是成员方法还是函数。确定用户到底是在调用函数还是类方法,是dispatcher的工作,唯有在执行时,dispatcher才会参与工作;
    3. 使用dot语法,matlab的语法检查器回及时帮助用户检查语法错误。
  • 方法的签名:函数签名 = 函数名 + 所属类
  • 使用disp方法定制对象的显示:可以通过定义类的disp方法(也叫覆盖override)来定制对象在命令行上的输出内容。包含定制disp方法的类的对象,在命令行被用户查询时,会优先调用类的disp方法。

类的构造函数(Constructor)

是一种特殊的成员方法,和类的名称相同,用来创造类的实例。constructor只能有一个返回值,且必须时新创建的对象。

matlab是弱解释性语言,不能通过参数数目的不同来决定调用哪个参数,类似的功能只能放到函数体中,通过判断参数的个数(nargin)来实现,根据nargin的不同选择不同的代码。

不带任何参数的构造函数为Default Constructor。

类的继承

matlab中可以用isa查询一个对象是否属于一个特定的类。UML中继承用空心三角箭头表示。

  • 在子类方法中调用父类同名方法

    句柄是一种抽象的思想:隐藏了内核实现的细节,同时为调用提供了方便,保证了内核的安全。子类和父类成员方法可以有相同的名字,并且在子类方法内部可以调用父类的同名方法,在子类中,除同名方法外的其他地方不能调用父类的同名方法。

    调用语法:superMethod@superClass(this, otherArguments)

  • 多态:建立在继承的基础上,同名的方法被不同的对象调用,能产生不同的行为(形态)。

类之间的基本关系:继承、组合和聚集

handle类的set和get方法

  • set:set方法给对象属性的赋值提供了一个中间层,可以检查赋值是否符合要求或者检查赋值的类型。还可以在set方法中做一些其他工作,如LOG记录每次属性被赋的值。
classdef A < handle
	properties
		a
	end
	methods
		function set.a(obj, val)
			if val >= 0
				obj.a = val;
			else
				error('a must be positive');
			end
		end
	end
end

load一个对象时,属性set方法会被MATLAB调用,如果这时对象的某些属性值仍是默认值,这些属性会经过set方法,被验证有效性。

  • get:get方法提供了对成员属性查询操作的一个中间层。可以使程序向后兼容。
classdef Record < handle
	properties(Dependent, Hidden)
		data % 需要把data的名字改成timeStamp(旧属性 -> 新属性)
	end
	properties
		timestamp
	end
	methods
		function set.data(obj, val)
			obj.timeStamp = val;
		end
		function val = get.data(obj)
			val = obj.timeStamp;
		end
	end
end

属性和方法的访问权限

Access = public、protected、private,属性的访问权限还可以被细分为赋值SetAccess和查询GetAccess的权限。