MATLAB - 类和对象
MATLAB - 现代面向对象编程
Section titled “MATLAB - 现代面向对象编程”MATLAB 中的面向对象编程 (OOP) 是一种强大的范式,用于设计和实现复杂的软件系统。通过创建类和对象,您可以构建模块化、可重用和可维护的代码,以模拟现实世界实体及其交互。
OOP 核心概念
Section titled “OOP 核心概念”- 类(Class):创建对象的模板或蓝图。它定义了一组对象将拥有的属性(数据)和方法(函数)。
- 对象(Object):类的一个实例。它在属性中存储特定数据,并可以使用其方法执行操作。
- 封装(Encapsulation):将数据(属性)和操作该数据的方法捆绑到一个单一的单元(对象)中。这隐藏了内部复杂性并保护数据免受未经授权的访问。
- 继承(Inheritance):从现有类(超类)创建新类(子类)。子类继承超类的属性和方法,从而实现代码重用和创建专门化的类。
- 多态(Polymorphism):不同类以各自独特方式响应相同方法调用的能力。这使得代码具有灵活性和可扩展性。
定义现代 MATLAB 类
Section titled “定义现代 MATLAB 类”现代类定义在 .m 文件中,文件名与类名匹配。定义以 classdef 关键字开始。
让我们创建一个实用的 BankAccount 类来演示其关键特性。创建一个名为 BankAccount.m 的文件。
% BankAccount.mclassdef BankAccount < handle % 一个表示简单银行账户的句柄类。
properties (Access = public) AccountHolder string end
properties (SetAccess = private) % 可从外部读取,但只能在内部设置。 AccountNumber (1,1) double Balance (1,1) double = 0.0 end
properties (Constant) % 所有实例共享的常量属性。 BankName string = "MATLAB Central Bank" end
methods % --- 构造函数方法 --- function obj = BankAccount(holderName, initialDeposit) % 创建 BankAccount 类的实例。 arguments holderName (1,1) string initialDeposit (1,1) double {mustBeNonnegative} = 0 end
obj.AccountHolder = holderName; obj.Balance = initialDeposit;
% 分配一个唯一的账号(简单示例) obj.AccountNumber = randi([1e5, 1e6-1]);
fprintf('Welcome, %s! Account #%d created with a balance of $%.2f.\n', ... obj.AccountHolder, obj.AccountNumber, obj.Balance); end
% --- 公共方法 --- function deposit(obj, amount) % 存钱到账户中。 arguments obj BankAccount amount (1,1) double {mustBePositive} end obj.Balance = obj.Balance + amount; fprintf('Deposited $%.2f. New balance: $%.2f.\n', amount, obj.Balance); end
function withdraw(obj, amount) % 从账户中取钱。 arguments obj BankAccount amount (1,1) double {mustBePositive} end
if amount > obj.Balance error('BankAccount:InsufficientFunds', ... 'Withdrawal amount of $%.2f exceeds current balance of $%.2f.', ... amount, obj.Balance); end
obj.Balance = obj.Balance - amount; fprintf('Withdrew $%.2f. New balance: $%.2f.\n', amount, obj.Balance); end endend关键特性解释
Section titled “关键特性解释”classdef BankAccount < handle:这定义了一个名为BankAccount的类,它继承自handle。句柄类的行为类似于引用;当您复制一个句柄对象时,您复制的是引用,而不是对象的数据。两个副本都指向相同的底层数据。这与默认的值类不同,值类在复制时会创建完全独立的副本。properties (Attribute):属性块用于定义数据。属性控制它们的行为:-
- **`Access = public`**:可以从任何地方读取和写入(例如 `AccountHolder`)。
-
- **`SetAccess = private`**:可以从任何地方读取,但只能由类内部的方法修改(例如 `Balance`、`AccountNumber`)。这是封装的关键部分。
-
- **`Constant`**:该值是固定的,不能更改(例如 `BankName`)。
methods:方法块包含对对象进行操作的函数。任何非静态方法的第一个参数始终是对象本身(通常命名为obj)。- 构造函数(
BankAccount(...)):一个与类同名的特殊方法。当您创建对象时(例如myAccount = BankAccount(...)),它会自动被调用。 arguments块:一种现代且强烈推荐的特性,用于验证方法输入,使您的代码更健壮且具有自文档性。
您现在可以从 MATLAB 命令窗口或脚本创建并与 BankAccount 对象交互。
% Create two accountsaccount1 = BankAccount("Alice", 200.0);Welcome, Alice! Account #157363 created with a balance of $200.00.
account2 = BankAccount("Bob");Welcome, Bob! Account #935069 created with a balance of $0.00.
% Perform operationsaccount1.deposit(50.0);Deposited $50.00. New balance: $250.00.
account2.deposit(1000.0);Deposited $1000.00. New balance: $1000.00.
account1.withdraw(30.0);Withdrew $30.00. New balance: $220.00.
% Trying to modify a private-set property will failaccount1.Balance = 5000;Error using BankAccount/set.BalanceYou cannot set the read-only property 'Balance' of BankAccount.
% Trying an invalid operationaccount1.withdraw(300.0);Error using BankAccount/withdraw (line 69)Withdrawal amount of $300.00 exceeds current balance of $220.00.OOP 的基本内置函数
Section titled “OOP 的基本内置函数”MATLAB 提供了在运行时检查和使用对象的函数。
class(obj):获取类名
Section titled “class(obj):获取类名”class 函数将变量的类名作为字符串返回。这对于类型检查很有用。
myAccount = BankAccount("Charlie");Welcome, Charlie! Account #489764 created with a balance of $0.00.
className = class(myAccount)className = "BankAccount"
someNumber = 42;class(someNumber)ans = 'double'isobject(A):检查变量是否为对象
Section titled “isobject(A):检查变量是否为对象”isobject 函数如果输入变量是任何 MATLAB 类的实例,则返回逻辑 true,否则返回 false。
isobject(myAccount)ans = logical 1
myStruct = struct('field', 'value');isobject(myStruct)ans = logical 0isa(obj, 'ClassName'):检查特定类类型
Section titled “isa(obj, 'ClassName'):检查特定类类型”isa 函数比 isobject 更具体。如果对象是指定类或其任何子类的实例,则返回 true。这是检查对象类型的首选方法。
isa(myAccount, 'BankAccount')ans = logical 1
isa(myAccount, 'handle') % BankAccount inherits from handleans = logical 1
isa(myAccount, 'double')ans = logical 0后续步骤和最佳实践
Section titled “后续步骤和最佳实践”- 测试:使用 MATLAB 单元测试框架为您的类编写自动化测试。这确保您的方法按预期工作并防止回归。
- 包(Packages):对于大型项目,将相关的类组织到包中(以
+开头的文件夹)。这可以防止命名冲突并分组功能,例如+mybank/BankAccount.m。 - 静态方法(Static Methods):使用
Static属性定义属于类但不属于特定实例的方法。它们对于与类相关的实用函数很有用。 - 事件和监听器(Events and Listeners):通过在类中定义事件并创建在事件触发时做出反应的监听器来实现在观察者设计模式。