Matlab也可以写面向对象的代码,首先表现在可以定义类,以及可以继承,使用类(class)有很多好处,其中一个重要的好处便是解决变量名冲突和让函数、对象的结构清晰。class的static function可以在不定义类的实例直接调用类的成员函数,比如定义

[html] view plain copy  
  1. classdef tools < handle
  2. methods (Static = true)
  3. function a = test(b, c)
  4. a = b + c;
  5. end
  6. end
  7. end

然后可以直接通过

a = tools.test(b, c);

调用函数。

classdel是定义类名,后面的<是表示继承,Matlab允许多重继承,继承自handle类,handle类定义了很多关于object的处理函数,例如addListener以及notify还有delete等对对象的函数,是一个抽象类,不能实例化,具体可以看一下参考文献【2】。

类的方法是放在methods ...end里面。

下面是一个稍微复杂的类的定义

[html] view plain copy  
  1. classdef TensileData
  2. properties
  3. Material = 'carbon steel';
  4. SampleNumber = 0;
  5. Stress
  6. Strain
  7. end
  8. properties (Dependent)
  9. Modulus
  10. end
  11. methods
  12. function td = TensileData(material,samplenum,stress,strain)
  13. if nargin > 0
  14. td.Material = material;
  15. td.SampleNumber = samplenum;
  16. td.Stress = stress;
  17. td.Strain = strain;
  18. end
  19. end % TensileData
  20. end
  21. methods
  22. function obj = set.Material(obj,material)
  23. if ~(strcmpi(material,'aluminum') ||...
  24. strcmpi(material,'stainless steel') ||...
  25. strcmpi(material,'carbon steel'))
  26. error('Material must be aluminum, stainless steel, or carbon steel')
  27. end
  28. obj.Material = material;
  29. end % Material set function
  30. function modulus = get.Modulus(obj)
  31. ind = find(obj.Strain > 0); % Find nonzero strain
  32. modulus = mean(obj.Stress(ind)./obj.Strain(ind));
  33. end % Modulus get function
  34. function obj = set.Modulus(obj,~)
  35. fprintf('%s%d\n','Modulus is: ',obj.Modulus)
  36. error('You cannot set Modulus explicitly');
  37. end
  38. function disp(td)
  39. fprintf(1,'Material: %s\nSample Number: %g\nModulus: %1.5g\n',...
  40. td.Material,td.SampleNumber,td.Modulus);
  41. end % disp
  42. function plot(td,varargin)
  43. plot(td.Strain,td.Stress,varargin{:})
  44. title(['Stress/Strain plot for Sample ',num2str(td.SampleNumber)])
  45. xlabel('Strain %')
  46. ylabel('Stress (psi)')
  47. end % plot
  48. end
  49. methods (Access = 'private') % Access by class members only
  50. function m = CalcModulus(td)
  51. % Over-simplified calculation of Elastic Modulus
  52. ind = find(td.Strain > 0); % Find nonzero strain
  53. m = mean(td.Stress(ind)./td.Strain(ind));
  54. end % CalcModulus
  55. end
  56. end % classdef

在上述代码中,

classdef TensileData

  ...

end

是定义一个TensileData类。代码:

properties
      Material = 'carbon steel';
      SampleNumber = 0;
      Stress
      Strain
   end
 是定义这个类的属性,也就是C++中类的成员变量。但是和C++不同的是,matlab中的类定义还有一个比较特别的地方的,就是定义依赖属性,如下述代码:

properties (Dependent)
      Modulus
   end

这表示Modulus这个属性是个依赖属性,它的值是通过其他属性计算得到的,其中Dependent的默认属性值为True。

它的值是通过下面函数实现的:

% Modulus get function

function modulus = get.Modulus(obj)
         ind = find(obj.Strain > 0); % Find nonzero strain
         modulus = mean(obj.Stress(ind)./obj.Strain(ind));
end

类的方法(函数)的定义是以methods ... end的的形式出现的。如下面的类方法的定义:

methods
      function td = TensileData(material,samplenum,stress,strain)
         if nargin > 0
            td.Material = material;
            td.SampleNumber = samplenum;
            td.Stress = stress;
            td.Strain = strain;
         end
      end 
end

该函数块定义了TensileData构造函数方法。上述代码中的最后一个方法 methods (Access = 'private')

中的Access = 'private'表示该方法仅能被类本身访问和修改,是个私有成员方法。其中属性Access又可分为

SetAccess和GetAccess,属性值和Access相同。

面向对象的使用必然导致程序的开销变高,关于相关的讨论可以看一下【1】:

封装后的函数多次调用会话费相当长的时间

所以到底该不该封装,还需取决于实际情况,如果函数本身特别简单,并且会被循环调用,最好还是通过m文件函数的形式。之前MIT大牛给出了更多地建议

  1. 虽然for-loop的速度有了很大改善,vectorization(向量化)仍旧是改善效率的重要途径,尤其是在能把运算改写成矩阵乘法的情况下,改善尤为显著。
  2. 在不少情况下,for-loop本身已经不构成太大问题,尤其是当循环体本身需要较多的计算的时候。这个时候,改善概率的关键在于改善循环体本身而不是去掉for-loop。
  3. MATLAB的函数调用过程(非built-in function)有显著开销,因此,在效率要求较高的代码中,应该尽可能采用扁平的调用结构,也就是在保持代码清晰和可维护的情况下,尽量直接写表达式和利用built-in function,避免不必要的自定义函数调用过程。在次数很多的循环体内(包括在cellfun, arrayfun等实际上蕴含循环的函数)形成长调用链,会带来很大的开销。
  4. 在调用函数时,首选built-in function,然后是普通的m-file函数,然后才是function handle或者anonymous function。在使用function handle或者anonymous function作为参数传递时,如果该函数被调用多次,最好先用一个变量接住,再传入该变量。这样,可以有效避免重复的解析过程。
  5. 在可能的情况下,使用numeric array或者struct array,它们的效率大幅度高于cell array(几十倍甚至更多)。对于struct,尽可能使用普通的域(字段,field)访问方式,在非效率关键,执行次数较少,而灵活性要求较高的代码中,可以考虑使用动态名称的域访问。
  6. 虽然object-oriented从软件工程的角度更为优胜,而且object的使用很多时候很方便,但是MATLAB目前对于OO的实现效率很低,在效率关键的代码中应该慎用objects。
  7. 如果需要设计类,应该尽可能采用普通的property,而避免灵活但是效率很低的dependent property。如非确实必要,避免重载subsref和subsasgn函数,因为这会全面接管对于object的接口调用,往往会带来非常巨大的开销(成千上万倍的减慢),甚至使得本来几乎不是问题的代码成为性能瓶颈。

参考文献:

【1】http://zhiqiang.org/blog/it/class-wrapper-functions-in-matlab.html

【2】http://cn.mathworks.com/help/matlab/ref/handle.html?searchHighlight=handle

【3】http://www.cnblogs.com/magic-cube/archive/2011/11/08/2241580.html

【4】http://anony3721.blog.163.com/blog/static/5119742011911111232557/

Matlab中的类定义 classdef相关推荐

  1. MATLAB中的清除,oop – 在MATLAB中清除类定义

    我在编写新的HPF课程时遇到了这个问题.所以我尝试了一些东西,因为当我调试新类时,我做了很多更改,然后测试. "清除功能"没有帮助.我甚至试过"清除hpf".但 ...

  2. boost::regex模块在 cpp 文件中搜索类定义,使用全局数据的测试程序

    boost::regex模块在 cpp 文件中搜索类定义,使用全局数据的测试程序 实现功能 C++实现代码 实现功能 boost::regex模块在 cpp 文件中搜索类定义,使用全局数据的测试程序 ...

  3. boost::regex模块在 cpp 文件中搜索类定义,使用 C++ Builder 闭包作为回调的测试程序

    boost::regex模块在 cpp 文件中搜索类定义,使用 C++ Builder 闭包作为回调的测试程序 实现功能 C++实现代码 实现功能 boost::regex模块在 cpp 文件中搜索类 ...

  4. boost::regex模块在 cpp 文件中搜索类定义,使用绑定成员函数回调测试程序

    boost::regex模块在 cpp 文件中搜索类定义,使用绑定成员函数回调测试程序 实现功能 C++实现代码 实现功能 boost::regex模块在 cpp 文件中搜索类定义,使用绑定成员函数回 ...

  5. boost::regex模块在 cpp 文件中搜索类定义,使用全局回调函数的测试程序

    boost::regex模块在 cpp 文件中搜索类定义,使用全局回调函数的测试程序 实现功能 C++实现代码 实现功能 boost::regex模块在 cpp 文件中搜索类定义,使用全局回调函数的测 ...

  6. boost::regex模块实现在 cpp 文件中搜索类定义的测试程序

    boost::regex模块实现在 cpp 文件中搜索类定义的测试程序 实现功能 C++实现代码 实现功能 boost::regex模块实现在 cpp 文件中搜索类定义的测试程序 C++实现代码 #i ...

  7. matlab中的类标转换程序

    matlab中的类标转换程序 原始类标为Y,新类标为Y_new %进行排序,针对类标数目orig_labels = sort(unique(Y)); Y_new = Y;new_labels = 1: ...

  8. python中class 类定义与使用

    ☞☞☞点击查看更多优秀Python博客☜☜☜ python中class 类定义与使用 python中class 类定义与使用 class的定义 class 类 init 功能(初始) ==**文章导航 ...

  9. Matlab中句柄类和值类的比较

    句柄类和值类的比较 基本差异 ​        值类构造函数返回一个与其赋值变量相关联的对象.如果对此变量重新赋值,MATLAB® 会创建原始对象的独立副本.如果将此变量传递给函数以修改它,函数必须将 ...

最新文章

  1. QT入门注意事项(1)
  2. 《研磨设计模式》chap14 迭代器模式(1)简介
  3. mybatis出现 Parameter '__frch_excelModel_0' not found.
  4. 每日程序C语言8-打印“水仙花数”
  5. LeetCode77:Combinations
  6. Linux 使用 yum 查看安装的软件包
  7. php 如何生成二级目录json,使用PHP根据已解码的JSON创建文件夹/文件结构
  8. Git安装及密钥的生成并上传本地文件到GitHub上
  9. WPF ListView中自动生成的列
  10. java 映射servlet,java – 将映射或对象从jsp传递到servlet
  11. 大疆机器学习算法岗笔试
  12. 绕过密码关闭趋势防毒墙
  13. [转载] MLDN魔乐科技李兴华主讲Oracle——02 Oracle安装
  14. 如何用计算机还原魔方,初学者使用的魔方口诀 7步教你快速复原三阶魔方(附图解)...
  15. 小白入门——关于什么是区块链
  16. 学习笔记(二十一)—— 使用SMTP发送电子邮件
  17. android studio 预览报错,Android Studio 布局预览时 渲染错误
  18. 0.96寸OLED显示屏介绍
  19. nginx修改成非root用户启动
  20. 男人在神永恒国度里的沉思录

热门文章

  1. 学生党什么蓝牙耳机比较适合?500左右高人气蓝牙耳机分享
  2. python读取大疆激光雷达LVX数据并显示
  3. Unity 内部执行cmd命令行
  4. vue作用域插槽,你真的懂了吗?
  5. flutter国内环境更换阿里镜像。
  6. 【第四篇:解决校招面试中的测试设计题目】
  7. cmd快速进入指定文件夹方法
  8. Nginx网络负载均衡,负载均衡,网络负载,网络均衡
  9. 马云:公司到底缺人才,还是缺制度?
  10. java url安全的base64编码_URL安全的Base64编码