自定义类是值语义对象(栈上构造,赋值拷贝),与 .yt 结构体、扩展句柄类(HTTP类 等)都不同。
硬约束
- 一个
.ypp 一个类;类名必须与文件名(不含扩展名)一致。
.ypp 内用 类 名字 {... },方法写 方法 名(参数) [返回类型] {... };不要写顶层 函数。
- 方法调用必须带括号:
对象.问好("x");属性用 对象.名字(无括号)。
- 继承用英文半角
:,如 类 猫 : 动物(单继承)。
- 局部数组变量写
MatchData result[],不是 MatchData[] result。
- 不要把用户类当成
HTTP类 那种扩展句柄:无「支持库元数据」方法表,只有你在 .ypp 里定义的成员。
- 赋值是拷贝;
对象2 = 对象1 后两边独立。
怎么新建
- 工程树 → 源代码 → 右键 → 新建类文件
- 输入名称(可省略
.ypp)
- 一个文件一个类,类名必须与文件名(不含扩展名)一致
保存后,工程内任意 .yc 自动可用,无需导入。
定义签名模板
类 类名 [: 基类名] {
类型 属性 [= 默认值]
方法 构造([类型 参 = 默认], …) { … }
方法 析构() { … }
方法 方法名(类型 参, …) [返回类型] { … }
}
| 成员 |
签名写法 |
说明 |
| 属性 |
文本 名字 = "小花" |
写在方法外;方法内同名是局部变量 |
| 构造 |
方法 构造(文本 name = "小花") { … } |
可带默认;类名("x") 调带参构造 |
| 析构 |
方法 析构() { … } |
可空 |
| 无返回方法 |
方法 说话() { … } |
调用须 说话() |
| 有返回 |
方法 问好(文本 name) 文本 { 返回(…) } |
|
返回 .yt |
方法 取一项() MatchData { … } |
|
| 返回类数组 |
方法 取列表() MatchData[] { … } |
|
| 继承 |
类 猫 : 动物 |
英文半角 : |
示例定义
类 我的类 {
文本 名字 = "小花"
整数 年龄 = 0
方法 构造(文本 name = "小花") { 名字 = name; 年龄 = 1 }
方法 析构() { }
方法 问好(文本 name) 文本 {
返回("你好," + name)
}
方法 取一项() MatchData { … }
方法 取列表() MatchData[] { … }
}
类 猫 : 动物 {
文本 名字 = "小花"
方法 构造() { 年龄 = 1 }
}
- 无参
类名():若仅有带参构造,会走自动补的空默认构造
- 支持
父.子对象.方法(...) 嵌套接收者调用
- 返回类型可以是:内置标量、
.yt、其它 .ypp 用户类、以及上述的 [] / [][]
- 编辑器右键「添加方法」或 Ctrl+Q 插入带
/// @说明 的方法模板
.yc 用法
| 操作 |
写法 |
| 构造 |
我的类 对象1 = 我的类("小白") / 猫 喵喵 = 猫() |
| 调方法 |
对象1.问好("小花") |
| 读属性 |
对象1.名字 |
| 写属性 |
对象1.年龄 = 2 |
| 嵌套调用 |
对象1.宠物.说话() |
我的类 对象1 = 我的类("小白")
输出(对象1.问好("小花"))
对象1.宠物.说话()
猫 喵喵 = 猫()
输出(喵喵.名字)
喵喵.说话()
规则速查
| 规则 |
说明 |
| 文件 |
.ypp 只放类,不要写顶层 函数 / 主函数 |
| 命名 |
类名 = 文件名 |
| 语义 |
值语义;赋值拷贝 |
| 继承 |
单继承;字段/方法可沿基类查找 |
| 返回类型 |
标量 / .yt / 用户类 / 类型[];局部数组写 MatchData result[] |
易错对照
| 错误 |
正确 |
对象.问好 无括号 |
对象.问好("x") |
MatchData[] result |
MatchData result[] |
中文冒号继承 类 猫 :动物 |
类 猫 : 动物 |
一个文件写两个 类 |
拆成两个 .ypp |
期望像 HTTP类 有内置方法表 |
只有你定义的成员 |
与第三方 DLL
用类封装第三方 DLL 的写法见 third-party-dll.md。