跳到主要内容

类和接口

在 Sii 2 中,class 关键字用于定义结构体(数据容器),而真正的对象(带方法的)是通过 crob 关键字创建的。本章将详细介绍结构体定义、对象创建、方法定义以及接口的使用。

结构体定义(class)

基本语法

使用 class 关键字定义结构体:

class 结构体名 {
字段名: 字段类型;
字段名: 字段类型;
...
}

注意:虽然使用 class 关键字,但这实际上定义的是结构体(数据容器),只包含字段,不包含方法。

结构体定义规则

  1. 结构体名首字母必须大写
  2. 结构体只能包含字段(属性),不能包含方法
  3. 所有字段必须指定类型
  4. 不支持继承和多态

简单示例

class Person {
name: string;
age: int;
email: string;
}

class BankAccount {
balance: int;
accountNumber: string;
owner: string;
}

对象创建(crob)

Sii 2 使用 crob 关键字创建对象(带方法的实例),支持两种方式:

简单对象创建

最简单的对象创建方式:

crob 对象名 = new 类名();

示例:

class User {
id: int;
name: string;
age: int;
}

// 使用 crob 创建对象(类型为 obj)
crob user = new User();
user.id = 1;
user.name = "Alice";
user.age = 25;

注意crob 创建的对象类型是 obj

封装式对象创建

封装式创建允许在创建对象时初始化字段和定义方法:

crob 对象名 (class: 类名, right: boolean) {
// 字段初始化
字段名 = 值;

// 方法定义
func 方法名(参数列表): 返回类型 {
方法体;
back 返回值;
}
}

参数说明:

  • class: 结构体名:指定要使用的结构体(通过 class 关键字定义的)
  • right: boolean:指定对象是否允许重构
    • true:允许使用 remake 关键字重构对象
    • false:不允许重构

示例:

class BankAccount {
balance: int;
accountNumber: string;
}

crob account (class: BankAccount, right: true) {
balance = 1000;
accountNumber = "123456789";

func deposit(amount: int): int {
balance = balance + amount;
back balance;
}

func withdraw(amount: int): bool {
if (amount <= balance) {
balance = balance - amount;
back true;
} else {
back false;
}
}

func getBalance(): int {
back balance;
}
}

对象使用

访问字段

使用点号访问对象的字段:

crob user = new User();
user.name = "Bob";
let name: string = user.name;

调用方法

使用点号调用对象的方法:

let newBalance: int = account.deposit(500);
let success: bool = account.withdraw(200);
let currentBalance: int = account.getBalance();

this 关键字

在对象方法中,可以使用 this 关键字引用当前对象:

crob person (class: Person, right: true) {
name = "Alice";
age = 25;

func getInfo(): string {
back "Name: " + this.name + ", Age: " + string(this.age);
}

func updateAge(newAge: int): string {
this.age = newAge;
back this.getInfo();
}
}

this 关键字规则

  • 只能在对象方法内部使用
  • 引用当前对象的字段和方法
  • 当方法参数名与字段名相同时,使用 this.字段名 明确指向对象字段

对象重构

当对象创建时 right 参数为 true 时,可以使用 remake 关键字重构对象。

重构语法

remake 对象名 {
// 重构现有方法
func 原方法名(参数列表): 返回类型 {
重构的方法体;
back 返回值;
}

// 添加新方法
func 新方法名(参数列表): 返回类型 {
新方法体;
back 返回值;
}

// 添加新字段
新字段名 = 值;
}

重构示例

// 重构现有方法
remake account {
func deposit(amount: int): int {
if (amount > 0) {
this.balance = this.balance + amount;
sii.io.print("Deposit successful, balance: " + string(this.balance));
back this.balance;
} else {
sii.io.print("Deposit amount must be greater than 0");
back this.balance;
}
}

// 添加新方法
func transfer(targetAccount: obj, amount: int): bool {
if (amount <= this.balance) {
this.balance = this.balance - amount;
sii.io.print("Transfer successful, amount: " + string(amount));
back true;
} else {
sii.io.print("Insufficient balance, transfer failed");
back false;
}
}

// 添加新字段
transactionCount = 0;
}

重构注意事项

  1. 重构限制:只有 right: true 的对象才能重构
  2. 重构时机:重构定义结束后才能调用对象
  3. 方法重构:可以重构现有方法或添加新方法
  4. 字段添加:可以添加新字段,但不能删除现有字段

完整示例

示例 1:用户管理系统

class User {
id: int;
name: string;
email: string;
isActive: bool;
}

crob userManager (class: User, right: true) {
id = 0;
name = "";
email = "";
isActive = false;

func createUser(name: string, email: string): void {
this.name = name;
this.email = email;
this.isActive = true;
sii.io.print("User created: " + this.name);
}

func deactivate(): void {
this.isActive = false;
sii.io.print("User deactivated: " + this.name);
}

func getInfo(): string {
let status: string = if (this.isActive) { "Active" } else { "Inactive" };
back "User: " + this.name + " (" + this.email + ") - " + status;
}
}

示例 2:购物车系统

class ShoppingCart {
items: arr;
total: int;
}

crob cart (class: ShoppingCart, right: true) {
items = new Array();
total = 0;

func addItem(itemName: string, price: int): void {
crob item = new Object();
item.name = itemName;
item.price = price;
// 添加元素到数组
let nextIndex: int = this.items.length();
this.items[nextIndex] = item;
this.total = this.total + price;
sii.io.print("Added: " + itemName + " ($" + string(price) + ")");
}

func removeItem(index: int): void {
if (index >= 0 && index < this.items.length()) {
let item: obj = this.items[index];
this.total = this.total - item.price;
rmv this.items[index]; // 使用 rmv 语句删除元素
sii.io.print("Removed item at index " + string(index));
}
}

func getTotal(): int {
back this.total;
}

func clear(): void {
this.items = new Array();
this.total = 0;
sii.io.print("Cart cleared");
}
}

结构体和对象的区别

结构体(class 定义)

  • 用途:简单的数据容器
  • 类型:结构体类型
  • 特点:只包含字段,不包含方法
  • 使用场景:数据传递、数据组织

对象(crob 创建)

  • 用途:带方法的对象实例
  • 类型obj 类型
  • 创建方式crob obj = new ClassName(); 或封装式创建
  • 特点:可以包含字段和方法(通过封装式创建)
  • 使用场景:需要封装数据和行为、需要对象方法、需要对象重构

何时使用结构体

  • 只需要简单的数据容器
  • 不需要方法
  • 需要类型安全
  • 数据相对独立

何时使用对象

  • 需要封装数据和行为
  • 需要对象方法
  • 需要对象重构
  • 需要更复杂的对象模型

最佳实践

1. 类名规范

类名首字母必须大写,使用大驼峰命名:

// 正确
class UserAccount { }
class DatabaseConnection { }

// 错误
class userAccount { }
class database_connection { }

2. 字段组织

将相关的字段组织在一起:

// 好的组织
class Person {
name: string;
age: int;
email: string;
address: string;
}

// 不好的组织:不相关的字段混在一起
class Person {
name: string;
fileSize: int;
isConnected: bool;
}

3. 方法设计

方法应该:

  • 有单一职责
  • 名称清晰表达功能
  • 参数数量适中
  • 返回值类型明确

4. 对象生命周期

  • 合理使用 right 参数
  • 只在需要重构时设置 right: true
  • 避免不必要的重构

小结

本章介绍了类和接口的核心概念:

  • 类定义:使用 class 关键字定义类
  • 对象创建:简单创建和封装式创建
  • 方法定义:在封装式对象中定义方法
  • this 关键字:引用当前对象
  • 对象重构:使用 remake 重构对象
  • 最佳实践:如何设计和使用类

下一章我们将学习包(模块)系统,了解如何组织和重用代码。