MATLAB 面向对象编程——类,属性,方法

类组件

MATLAB® 将类定义代码组织成模块化代码块,以关键字分隔。所有关键字都有相关联的 end 语句:

  • classdef…end:所有类组件的定义

  • properties…end:属性名称声明、属性特性设定、默认值赋值

  • methods…end:方法签名、方法属性和函数代码的声明

  • events…end:事件名称和属性的声明

  • enumeration…end:枚举类的枚举成员和枚举值的声明。

  • properties、methods、events 和 enumeration 只是 classdef 代码块内的关键字。

classdef (Attributes) ClassName
 
   properties (Attributes) 
      PropertyName
   end 
 
   methods (Attributes) 
      function obj = methodName(obj,arg2,...)
         ...
      end
   end
 
   events (Attributes) 
      EventName
   end
 
   enumeration
      EnumName
   end
 
end

如何定义一个类(Class)

< handle 是 MATLAB 的抽象类,做父类

classdef 类名 < 继承类
    properties   %属性
        %...
    end
    methods   %方法
        %...
    end
end

简单的二维点类定义如下:

classdef Point2D < handle
    properties   %属性
       x
       y
       %...
    end
    methods   %方法
        function obj = Point2D(x0,y0)%...
            obj.x = x0;
            obj.y = y0;
        end
        function normalize(obj)
            r = sqrt(obj.x^2+obj.y^2);
            obj.x =obj.x/r;
            obj.y =obj.y/r;
        end
    end
end

表示二维坐标轴上的点,具有 x,y 坐标属性作为其属性

methods 定义了两个方法,一个是 (Constructor) 构造方法;一个是其他的使用函数。其类的成员方法和普通函数区别不大。

注意: 写好类之后,保存调用即可,不能选中类执行,否则会报如下错误:

在这里插入图片描述

不同的类类型如下:
MATLAB 面向对象编程——类,属性,方法_第1张图片

类的属性

p1 = Point2D(1.2,1.0);
p1.x % 1.2000
p1.x = 10;
p1.x % 10

默认属性值

classdef Point2D < handle
    properties   %属性
       x = 0.2;
       y = 0.3;
       %...
    end

支持MATLAB表达式,最好使用固定值。也可以在Constructor中对成员变量进行初始化。

  • 常量(Constant)
  • properties(Constant)不可修改。

非独立属性

classdef Point2D<handle
    properties   %属性
       x = 0.2;
       y = 0.3;
       r % r 在Point2D中,通过 x y 计算得出
    end
    methods   %方法
        function obj = Point2D(x0,y0)%...
            obj.x = x0;
            obj.y = y0;
            obj.r = sqrt(obj.x^2+obj.y^2);
        end
   end
end

可以声明成 dependent(非独立)属性,其值可以动态改变

classdef Point2D<handle
    properties   %属性
       x = 0.2;
       y = 0.3;
     
    end
    properties(Dependent)
          r
    end
    methods   %方法
        function obj = Point2D(x0,y0)%...
            obj.x = x0;
            obj.y = y0;
            
        end
        function r = get.r(obj) %计算公式需要放在get方法中。
            r = sqrt(obj.x^2+obj.y^2);
        end
   end
end

隐藏属性

properties(Hidden)

查看对象信息,不被显示。 同理可以在成员方法中使用。

不同属性定义如下:
MATLAB 面向对象编程——类,属性,方法_第2张图片
MATLAB 面向对象编程——类,属性,方法_第3张图片
在这里插入图片描述

类的方法

function作为关键词。方法较多,可以将方法单独放一个文件。但需要创建一个独立文件夹

MATLAB 面向对象编程——类,属性,方法_第4张图片

类方法的不同属性:
MATLAB 面向对象编程——类,属性,方法_第5张图片

类的构造函数

一个类仅有一个构造函数(Constructor),其函数有且只能有一个返回值,且必须是新的对象。

  • 构造函数中可以给属性赋值。
  • 通过nargin使构造函数接收不同参数的输入。
  • 默认构造函数(Default Constructor:不带任何参数的构造函数)
  • 不创建构造函数,MATLAB会给一个默认值。不接受任何参数。

类的调用:
MATLAB 面向对象编程——类,属性,方法_第6张图片

类的继承

假设有二维点Point类为基类,这是想拓展其成为三维点Point2类,此时并不需要全部重新构造一个新类,而是在Point的基础上添加需要的属性和方法。

子类会继承所有非私有的属性和方法,可以直接访问和使用,MATLAB默认的继承方法是public,这里我们先不讨论访问权限,只考虑公有继承。
在继承中需要考虑的问题有:

  • 新加属性
  • 新的构造函数
  • 如何调用父类方法
  • 如何区分同名函数
  • saveobj和loadobj方法定义 (暂不讲)

二维点类定义

classdef Point < handle % 表示Point是继承handle的
    properties
        x = 0
        y = 0
    end
    methods
        normalize(obj); % 在类外定义了
        function obj = Point(x,y)  % 可以使用nargin得到复杂初始化
            obj.x  = x;
            obj.y = y ;
        end
        function disp(obj)  % 自定义显示方法
            disp(['x:' num2str(obj.x)]);
            disp(['y:' num2str(obj.y)]);
        end
    end
end

其中: function obj = Point(x,y) 为构造函数,返回的类Point的对象
MATLAB 面向对象编程——类,属性,方法_第7张图片

三维点类定义

classdef Point3D < handle
    properties   %属性
        x = 0
        y = 0
        z = 0
    end
    methods   %方法
        function obj = Point3D(x,y,z)
            obj.x = x;
            obj.y = y;
            obj.z = z;
        end
        function normalize(obj)
          Q = sqrt(obj.x^2+obj.y^2+obj.z^2);
          obj.x = obj.x/Q;
          obj.y = obj.y/Q;
          obj.z = obj.z/Q;
        end
        function disp(obj)
            disp(['x:',num2str(obj.x)]);
            disp(['y:',num2str(obj.y)]);
            disp(['z:',num2str(obj.z)]);
        end
    end
end

重新定义三维点类,代码重复率较高,冗余,构造函数也相似,disp 函数也相似。故可以从二维点类继承到三维点类。

通过继承方式从二维点类创建三维点类:

classdef Point3D < Point  % 表示Point2是继承Point
   properties
       z = 0;  % 新增一个坐标 z
   end
   methods
       function obj = Point3D(x,y,z)
           obj = obj@Point(x,y);
           obj.z = z;
       end
       function normalize(obj)
          Q = sqrt(obj.x^2+obj.y^2+obj.z^2);
          obj.x = obj.x/Q;
          obj.y = obj.y/Q;
          obj.z = obj.z/Q;
       end
       function disp(obj)
          disp@Point(obj)
          disp(['z:' num2str(obj.z)]);
       end
   end    
end

其中Point2D为父类(Parent Class)Point3D为子类。

添加新属性

  • Point 中已经有了 x 和 y,只需要在 Point3D 中添加 z 即可

子类的构造函数

  • 子类的构造函数需要先调用父类的构造函数,obj = obj@Point(x,y); ,这里右边的obj表示Point返回一个obj对象,给左边的obj赋值之后,obj是一个Point2对象,z为空。

调用父类方法:

  • 在上面的例子中,在Point3D的disp函数中调用了父类的disp,其调用方式为:
父类函数名 + @ + 父类类名 + (obj,其他参数)
p3 = Point3D();
isa(p3,'Point')

子类的构造函数需要先调用父类的 Constructor。

子类中如何调用父类同名方法

MATLAB 面向对象编程——类,属性,方法_第8张图片
相同函数foo,子类对父类的方法进行了扩展。

多态(Polymorphism)

同样的方法被不同的对象调用产生不同的形态。如上三维点类和二维点类的print函数。

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

B可不可以继承A,要看其是否拥有A的属性和方法。例:企鹅和鸟的类区别。
类的组合(Composition):多个类的组合,而不是多个类的多重继承。

classdef Head<handle
    properties
        eye
        nose
        mouth
        ear
    end
    methods
        function obj = Head()
            obj.eye = Eye();
            obj.nose = Nose();
            obj.mouth = Mouth();
            obj.ear = Ear();
        end
    end
end
%避免使用如下 多重继承
classdef Head<Eye&Nose&Mouth&Ear
    %..
end

Handle类的set和get方法

set方法给对象属性赋值

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

在命令行给a负值,则会报错

>> obj = A();
>> obj.a = -10
错误使用 A/set.a (line 10)
a must be positive

外部赋值,会调用set函数 ;内部则不会,但在properties部分设置默认值时需要验证set的有效性。

一个属性的set方法尽量不要访问其他属性,(Order Dependency),若需要则将其属性设置为Dependent。

get方法

function val = get.b(obj)
    val = obj.b;
    disp('getter called');
end

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

classdef tools < handle  
    methods (Static = true)  
        function a = test(b, c)  
            a = b + c;  
        end  
    end  
end  

然后可以直接通过 a = tools.test(b, c) 调用函数。

References

基于MATLAB的面向对象编程(1)——类,属性,方法

《MATLAB面向对象编程-从入门到设计模式(第2版)》

MATLAB 面向对象编程(三)类的继承

你可能感兴趣的:(#,MATLAB,matlab,开发语言)