基于MATLAB《数据结构与算法》延边大学信息管理专业(13级)崔基哲MATLAB类的定义Class创建举例用class创建双向链表线性表部分的MATLAB编程类的建立:class类的建立:class1.1类文件夹当要创建一个类时,我们应该将确认类文件放在什么位置。matlab为我们提供了两种方法:1.在matlab路径下创建一个文件夹,然后在文件夹中创建一个单独的自包含的类定义2.在matlab路径下,创建一个@+类名的文件夹,在其中创建一个类,同时我们可以将类的定义分散在多个文件中,也即该文件夹下都是该类的定义;和其他高级语言(java)类似,matlab还允许我们将这些类组织成包包为packages包文件夹的父文件夹必须在matlab路径下,但是包文件夹不必。包文件夹以‘+’开头,可以包含多个类定义或者其他的包。一个包文件夹定义了一个新的命名空间,所以我们可以重用类名。引用包中的类或者函数时需要包含包名称,例如packagefld1.ClassNameA(),packagefld2.packageFunction()。其他更多ClassFolders更多细节可参考matlab帮助中的ClassFolders部分(在搜索框中输入Class搜索)。1.2类定义要创建一个类,matlab会自动帮我们生成一个类框架,一般如下:classdef(attribute1=value,...)classname(superclass_name)propertiesPropNameendmethodsmethodNameendeventsEventNameendendClass的定义方法类名必须要与文件名相同,第一个括号中声明类的属性,类似于java中的public等关键词,更详细的解释可参考:ClassAttributes。第二个括号指明类是否需要继承父类,类似于java中的extends关键字或者C++中的‘:’。matlab支持多重继承,更详细的解释可参考:CreatingSubclasses—SyntaxandTechniques。在实现链表的过程中,我们需要继承handle类。完整的一个类模块如下图:完整的一个类模块如下图关于classdef与handleclassdef是定义类名,后面的是表示继承,Matlab允许多重继承,继承自handle类,handle类定义了很多关于object的处理函数,例如addListener以及notify还有delete等对对象的函数,是一个抽象类关于propertiesproperties类似于java或C++中的成员变量,我们也可以给其设定各种访问属性,更详细的解释可参考:DefiningProperties。关于Class中的methodsmethods就是具体的函数实现。有很多种不同类型的函数,下面简要介绍:普通函数(Ordinarymethods)。我们实现的大部分都是普通函数,它负责完成该类要完成的主要任务。构造函数(Constructormethods)。和其他高级语言类似,也必须是类名,用来给属性赋值。唯一不同是它必须返回它创建的对象。更详细的解释可参考:ClassConstructorMethods。析构函数(Destructormethods)。名字必须是delete,用来释放空间。更详细的解释可参考:HandleClassDeleteMethods。属性访问函数(Propertyaccessmethods)。类似于其他高级语言中的set、get函数。更详细的解释可参考:ControllingPropertyAccess。静态函数(Staticmethods)。类似于其他高级语言中的静态函数,通过类对象进行访问。转换函数(Conversionmethods)。是对其他类构造函数的重载,可以将自己定义类的对象转换成重载构造函数类的对象。更详细的解释可参考:ConvertingObjectstoAnotherClass。抽象函数(Abstractmethods)。无需解释,用来在子类中继承的函数创建类的简单举例类是一种数据类型,与普通的数据类型不同的是类不仅包含数据,还包含对数据的操作,类把数据和数据操作方法封装在一起,作为一个整体参与程序的运行。类具有课继承性,创建一个新的类的时候,可以在一个基类中添加成员派生出新类。类的变量和类的实例是不同的,类的实例是动态分配的内存区域,通常称类的实例维“对象”,同一个类可以有不同的实例存在,他们各自有自己的数据,但是数据操作方法是相同的。类的变量可以看作是一个指针,指向类的实例。举例:建立一个类建立一个类通常一个类应该包含四个基本的成员函数:构造函数――与类名相同,可以在其中完成成员初始化的工作;显示函数――名为display,用于显示成员的数据;赋值函数――名为set,用于设置类成员的数值;取值函数――名为get,用于读取类成员的函数。与C++的类不同的是,MATLAB的类不需要特别的析构函数。如果类用到了一些特殊的内容需要释放的话,可以编写一个成员函数,比如classclear,用包来释放所占用的资源。举例:建立一个类下面用一个简单的例子类介绍一些类如何使用。定义一个名为list的类,它有两个数据成员x和y,希望通过一个成员函数prod()来获取x和y的乘积。举例:建立一个类类名:list成员变量:x,y成员函数:list:构造函数display:显示函数get:取值函数set:赋值函数prod:计算函数现在就来建立它。举例:建立一个类第一步:(1)在工作目录上建立一个子目录(以笔者的习惯为例):cdE:\MyProgram\matlab7\chap4mkdir@list类名前面要加上一个字符'@’,对于这样形式的目录里所有保存的M文件,MATLAB都认为是类的成员函数。举例:建立一个类第二步:(2)编写5个成员函数的M文件保存在E:\MyProgram\matlab7\chap4\@list目录下:举例:建立一个类第二步:函数list.m%list.mfunctiond=list(x,y)d.x=x;d.y=y;d=class(d,'list');%display.mfunctiondisplay(d)fprintf('listclass:\n');fprintf('x=%d\n',d.x);fprintf('y=%d\n',d.y);举例:建立一个类第二步:函数get.m%get.mfunctionval=get(d,prop_name)switchprop_namecase'x'val=d.x;case'y'val=d.y;otherwiseerror([prop_name,'isnotavalidlistproperty']);end举例:建立一个类第二步:%set.mfunctiond=set(d,varargin)%该函数的定义在后面的章节再详细讲解argin=varargin;whilelength(argin)=2,prop=argin{1};val=argin{2};argin=argin(3:end);switchpropcase'x'd.x=val;case'y'd.y=val;otherwiseerror('Assetproperties:x,y');endend举例:建立一个类第三步:在MATLAB命令行中进行如下操作:cdE:\MyProgram\matlab7\chap4d=list(11,22)listclass:x=11y=22prod(d)ans=242d=set(d,'x',7);get(d,'x')ans=7prod(d)ans=154举例:创建类类成员变量的赋值本例中,类的成员变量是在构造函数中赋值的。MATLAB中,类成员变量都是private的,必须在成员函数中访问,因此就不能箱struct那样,用d.x和d.y等形式访问其成员变量了。访问时编个专门的成员函数get就行了。另外,成员函数的调用跟普通的函数一样。注意在get和set函数中,成员变量是以字符串的形式指定的,要通过字符串比较的办法进行区分,然后对输出变量进行赋值。本例中的set函数支持同时对两个成员变量赋值,因此用到了不定长输入产生表varargin,例如:d=set(d,'x',12)%只对其中一个成员变量赋值listclass:x=12y=22d=set(d,'x',23,'y',34)%同时对两个成员变量赋值listclass:x=23y=34在类中引用方法:实现方法函数类的方法(classmethods)是指M文件编写的以类的对象作为输入产生的函数。一个特定的类的方法通常要保存在这个类的目录中。如上一小节中@list的方法函数存储在@list路径下。对方法汗的调用方式和对普通函数的调用方式是相同的,其命令格式为:[输出1,输出2,…]=方法名称(对象名,参数1,参数2,…);但是必须注意,方法函数中如果对类的成员变量进行了改变,就必须将改变后的类变量作为输出变量返回,否则在原工作空间中的类变量的成员变量不能得到更新。例如:d=list(10,20);set(d,'x',23,'y',34);dlistclass:x=10y=20可以看到,调用set函数而不将返回结果重新赋值给d,着d的x和y两个成员变量仍然保持原来的数值。在类中的引用方法:私有方法私有方法是指只能被同类的其他方法所调用的方法,其对应的M文件存在类目录的private子目录下。例如,如果list类有私有方法,就应该将它们保存在@list/private目录下。私有方法的作用域子限于list这个类中,而不能够被MATLAB命令行调用,或者被上一层类的方法调用。类的继承和集成MATLAB中的类对象可以集成其他类对象的属性,当一个子类从父类中继承了属性后,在子类中将包括父类的所有成员和方法,父类的方法也可以使用之类继承的法拉国防。继承的概念是面向对象编程中的一个重要特性,子类可以很方便的引用父类中已经定义的方法。类的继承由两种方式:简单继承和多重继承。类集成的概率有点类似于嵌套,是指类对象的域中包括另外一个对象的情形。1.简单继承简单继承是指子类从一个父类继承属性,子类中也包括它自己的一些新的属性。对于父类的操作可以应用到子类上来,而对于子类中不属于父类的方法则不可以应用到父类上去。通常可以使用class函数来实现类的继承。子类对象名=class(子类对象名,‘子类类名’,父类对象名);2.多重继承多重继承是指子类从多于一个父类中继承属性。子类中包含所有从父类中继承来的属性,还包括它自己的属性。3.类的集成类的集成是指一个类可以把另外的类作为自己的一个成员变量。被嵌入的类对象的方法函数值能通过外层对象的方法函数调用。定义类的好处使用类(class)有很多好处,其中一个重要的好处便是解决变量名冲突和让函数、对象的结构清晰。class的staticfunction可以在不定义类的实例直接调用类的成员函数,比如定义classdeftoolshandlemethods(Static=true)functiona=test(b,c)a=b+c;endendend然后可以直接通过a=tools.test(b,c);调用函数。创建类:关于Access与Privatemethods(Access='private')%Accessbyclassmembersonlyfunctionm=CalcModulus(td)%Over-simplifiedcalculationofElasticModulusind=find(td.Strain0);%Findnonzerostrainm=mean(td.Stress(ind)./td.Strain(ind));end%CalcModulusend上述代码中的最后一个方法methods(Access='private')中的Access=‘private’表示该方法