class

SKILL.md

仓颉语言类 Skill

1. 类定义

1.1 基本语法

  • 使用 class ClassName { ... } 声明,仅可在顶层作用域定义
  • 引用类型 — 赋值/传参共享同一对象(与 struct 的值类型行为不同)
  • 类体可包含:成员变量、成员属性(prop)、静态初始化器、构造函数、成员函数、操作符函数

1.2 抽象类

  • abstract class — 可声明抽象函数(无函数体),不能实例化
  • 抽象函数不能为 private;非抽象子类须实现所有抽象函数
  • 抽象类定义时 open 修饰符可选
  • sealed abstract class — 仅同包内可继承,隐含 public/open 语义

1.3 成员变量

  • 实例成员:使用 let/var 定义,通过对象访问。可省略初始值(须有类型标注)
  • 静态成员static let/static var,无静态初始化器时须有初始值,通过类型名访问

1.4 静态初始化器

  • static init() { ... } — 每个类最多一个,须初始化所有未初始化的静态成员
  • 不允许访问修饰符

1.5 构造函数

普通构造函数

  • init(params) { ... } — 须初始化所有未初始化的实例成员变量
  • 多个构造函数须构成有效重载

主构造函数

  • ClassName(let x: T, var y: T) {} — 参数名前缀 let/var 同时定义成员变量
  • 每个类最多一个

执行顺序

  1. 构造函数外成员默认值初始化
  2. 隐式/显式 super() 调用
  3. 构造函数体

自动生成构造函数

  • 若无自定义构造函数且所有实例成员有初始值,则自动生成无参 public init()

1.6 终结器(~init

  • ~init() { ... } — 在垃圾回收时触发,用于释放系统资源
  • 无参数、无返回类型、无泛型类型参数、无修饰符、不可显式调用
  • 带终结器的类不能为 open。每个类最多一个。不能在扩展中定义
  • 触发时机不确定;可能在任意线程上运行
  • 终结器向外抛出未捕获异常属于未定义行为
  • 未完整初始化的对象(初始化时抛异常)的终结器不会执行

1.7 成员函数

  • 实例函数:通过对象访问,可使用 this
  • 静态函数static func,通过类型名访问,不能访问实例成员
  • 抽象函数:无函数体,仅在抽象类或接口中。隐式 open,须为 publicprotected
  • 限制:同一个类中,静态方法和实例方法不能同名(即使参数不同)

1.8 访问修饰符(4 级)

修饰符 可见性
private 仅在类定义内
internal(默认) 当前包及子包
protected 当前模块及子类
public 全局可见

1.9 This 类型

  • 在类内部,This 是当前类类型的占位符,仅可用作实例方法返回类型
  • 子类继承返回 This 的方法时,返回类型被识别为子类类型
  • 若实例成员函数未声明返回类型且仅返回 This 类型表达式,返回类型推断为 This

2. 对象创建与使用

2.1 创建对象

  • let obj = ClassName(args) — 调用构造函数
  • 通过对象访问 public 实例成员和实例函数

2.2 成员修改

  • var 成员可通过对象修改;let 成员不可修改
  • 赋值复制引用,非对象本身 — 多个变量指向同一对象,修改互相可见

3. 继承

3.1 基本规则

  • 单继承:class B <: A { }A 须为 openabstract
  • 子类继承所有非 private、非构造函数成员
  • 类不能继承自身。无显式父类的类继承自 Object
  • open 修饰的成员被继承时,open 修饰符也会被继承

3.2 sealed 抽象类

  • sealed abstract class — 仅同包内可继承
  • sealed 隐含 public/open 语义
  • sealed 的子类可不是 sealed,仍可被 open/sealed 修饰
  • 若子类被 open 修饰,则其子类可在包外被继承

3.3 父类构造函数调用

  • 在子类 init 中:使用 super(args)this(args) 作为函数体第一个表达式(互斥)
  • 主构造函数可用 super(args) 但不可用 this(args)
  • 若两者都未调用,编译器插入 super() — 父类须有无参构造函数

3.4 重写与重定义

  • 重写(实例函数):父类函数须为 open;子类使用 override(可选)。基于运行时类型的动态分派
  • 重定义(静态函数):子类使用 redef(可选)。基于类型名的静态分派
  • 命名参数须在父类与重写之间匹配
  • 泛型重写时子类约束须等于或宽松于父类

4. 属性(prop)在类中的使用

4.1 定义

  • prop name: Type { get() { ... } } — 只读属性(类似 let
  • mut prop name: Type { get() { ... } set(v) { ... } } — 读写属性(类似 var

4.2 getter 与 setter

  • getter() -> T — 读取属性时执行
  • setter(T) -> Unit — 属性被赋值时执行
  • 在 getter/setter 内部访问属性本身 = 递归调用

4.3 mut 限制

  • 数值类型、元组、函数、BoolUnitNothingStringRangeenum 类型不能mut 属性

4.4 修饰符

  • 与成员函数相同的访问修饰符(publicprivateprotectedinternal
  • 支持 openoverrideredef — 允许在子类中重写/重定义
  • 重写时若父类属性有 mut,子类也须有 mut,类型相同

4.5 抽象属性

  • 在抽象类中:属性声明无实现体,非抽象子类须提供实现

4.6 实例属性与静态属性

  • 实例属性:通过对象访问(obj.prop
  • 静态属性:通过类型名访问(ClassName.prop)。可为 static mut prop
Weekly Installs
2
First Seen
3 days ago
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1