doc: update docs/matlab.md (#969)

This commit is contained in:
fenglielie
2025-06-01 23:23:57 +08:00
committed by GitHub
parent 68b804b7f5
commit 0b9af04f70

View File

@ -1410,6 +1410,402 @@ true 或 false 条件
[thingSpeakWrite](https://ww2.mathworks.cn/help/matlab/ref/thingspeakwrite.html) | 将数据写入 `ThingSpeak` 通道
<!--rehype:className=style-list-->
## 面向对象基础
MATLAB 支持面向对象编程,虽然很少有人使用。
MATLAB 的自定义类型可以分成全值类和句柄类,它们的区别在于句柄类相当于指针,赋值时只会进行浅拷贝,全值类总是会进行深拷贝。下面的例子只涉及全值类。
### 简单例子
一个简单的 `point2d` 类(文件名必须与类名相同:`point2d.m`
```matlab
classdef point2d
properties % 属性
x
y
end
methods % 方法
function obj = point2d(x0,y0) % 构造方法
if nargin == 0
obj.x = 0;
obj.y = 0;
elseif nargin == 2
obj.x = x0;
obj.y = y0;
else
error("unsupported arguments")
end
end
function obj = normalize(obj) % 普通方法
% obj 相当于 Python 的 self
r = sqrt(obj.x^2+obj.y^2);
obj.x = obj.x/r;
obj.y = obj.y/r;
end
end
end
```
使用例如
```matlab
a = point2d(3,4);
fprintf('(%f, %f)\n',a.x,a.y);
% (3.000000, 4.000000)
b = a.normalize();
fprintf('(%f, %f)\n',b.x,b.y);
% (0.600000, 0.800000)
```
### 属性
可以给属性提供默认值
```matlab
classdef point2d
properties
x = cos(pi/12);
y = sin(pi/12);
end
...
end
```
默认值不需要是常量,可以是任何表达式
```matlab
classdef demo
properties
time_stamp = date;
end
...
end
```
属性的默认值在类被加载时会被计算,并不会在每一个对象创建时重新计算。
可以将属性标记为只读(`Constant`),不允许对其进行修改。
```matlab
classdef demo
properties(Constant)
R = pi/180;
end
...
end
```
尝试修改会报错
```matlab
s = demo();
disp(s.R)
s.R = 100; % error
```
### 构造方法和普通方法
#### 构造方法
与类同名的方法称为构造方法。MATLAB只允许创建一个构造方法但是我们通过nargin判断参数个数并据此实现不同的创建行为例如
```matlab
function obj = point2d(x0,y0)
if nargin == 0
obj.x = 0;
obj.y = 0;
elseif nargin == 2
obj.x = x0;
obj.y = y0;
else
error("unsupported arguments")
end
end
```
例如
```matlab
s1 = point2d(1,2);
s2 = point2d();
s3 = point2d;
```
#### 普通方法
类的普通方法的第一个参数是对象自身并且习惯上使用obj表示。
```matlab
classdef demo
properties
x = 100;
end
methods
function z = compute(obj,y)
z = obj.x + y;
end
end
end
```
普通方法可以通过对象或类调用
```matlab
s = demo();
s.compute(10); % 110
compute(s,20); % 120
```
### 静态方法
MATLAB 提供了静态方法,在定义时标记为 `Static`,静态方法没有`obj`参数,不绑定任何的对象,不能访问类对象的普通属性,但是可以访问类的常量属性。
例如
```matlab
classdef demo
methods(Static) % 静态方法
function hello()
disp("hello,world!")
end
end
end
```
使用例如
```matlab
>> demo.hello()
hello,world!
>> s = demo();
>> s.hello()
hello,world!
```
### 重写disp方法
可以通过提供`disp`方法来定制自定义类型调用`disp`函数时的行为,例如
```matlab
classdef point2d
properties
x = 0
y = 0
end
methods
function disp(obj)
fprintf("(%f,%f)",obj.x,obj.y);
end
end
end
```
提供`disp`函数后的输出
```matlab
>> s = point2d();
>> disp(s)
(0.000000,0.000000)
```
作为对比,默认情况下的输出
```matlab
>> s = point2d();
>> disp(s)
point2d with properties:
x: 0
y: 0
R: 0.0175
```
### 重载运算符
MATLAB 支持自定义类型对运算符的重载,例如`plus`方法对应加法。
```matlab
classdef point2d
properties
x
y
end
methods
function obj = point2d(x0,y0)
% same as before
end
function result = plus(obj, other)
result = point2d(obj.x + other.x, obj.y + other.y);
end
end
end
```
例如
```matlab
>> a = point2d(1,0);
>> b = point2d(0,2);
>> a + b
ans =
point2d with properties:
x: 1
y: 2
```
### 属性和方法的权限
MATLAB 提供了比 C++ 和 Java 更加精细的访问权限控制默认情况下所有的属性和方法都是public。
基本的三种权限例如
```matlab
classdef demo
properties % public
x1
end
properties(Access = protected)
x2
end
properties(Access = privated)
x3
end
methods % public
function h1(obj)
end
end
methods(Access = protected)
function h2(obj)
end
end
methods(Access = privated)
function h3(obj)
end
end
end
```
MATLAB对属性提供了更精细的访问权限可以将其拆分为读权限和写权限例如
```matlab
classdef demo
properties(SetAccess = private)
x1
end
properties(SetAccess = private, GetAccess = protected)
x2
end
end
```
### 类的继承
MATLAB 使用 `<` 表示继承关系。
基类
```matlab
classdef demo
properties
Value
end
methods
function obj = demo(val)
if nargin > 0
obj.Value = val;
else
obj.Value = 0;
end
end
function displayValue(obj)
disp(['Value: ', num2str(obj.Value)]);
end
end
end
```
派生类
```matlab
classdef demo2 < demo
properties
ExtraValue
end
methods
function obj = demo2(val, extraVal)
obj = obj@demo(val); % 调用基类构造方法
if nargin > 1
obj.ExtraValue = extraVal;
else
obj.ExtraValue = 0;
end
end
function displayValue(obj)
displayValue@demo(obj); % 调用基类的同名函数
disp(['Extra Value: ',num2str(obj.ExtraValue)]);
end
end
end
```
### 补充
#### 抽象方法和抽象类
MATLAB提供了抽象方法和抽象类。
抽象基类(不可实例化)
```matlab
classdef demo
methods(Abstract) % 抽象方法
hello(obj) % 只有接口,没有实现
end
end
```
继承自抽象基类的派生类(实现了抽象方法,可以实例化)
```matlab
classdef demo2 < demo
methods
function hello(obj) % 实现抽象方法
disp("hello,world!")
end
end
end
```
#### 禁止继承和重写
可以使用 `Sealed` 关键词来禁止一个类被继承,例如
```matlab
classdef (Sealed) demo
...
end
```
可以使用 `Sealed` 关键词来禁止方法被派生类重写,例如
```matlab
classdef demo
methods(Sealed)
...
end
end
```
另见
----