第8篇:类和对象——面向对象编程 原生中文编程
本文介绍了面向对象编程中的类和对象概念,通过生活实例说明对象包含属性和方法。文章展示了华为仓颉语言的类定义语法,同时指出了类型后置不符合中文习惯的问题。主要内容包括:1) 类作为对象模板的定义方法;2) 对象实例的创建与使用;3) 封装原则的实现;4) 通过学生类和银行账户类的完整代码示例演示面向对象编程。最后提供了学生管理系统实践练习,帮助读者掌握类与对象的核心概念及应用。
第8篇:类和对象——面向对象编程
**作者:**中文编程倡导者—— 李金雨
联系方式: wbtm2718@qq.com
**目标读者:**编程入门(零基础)
核心理念: 使用华为仓颉原生中文编程,体验真正的国产编程语言
一、开篇引入
1.1 从"过程"到"对象"
前面的课程,我们学习的是"面向过程"编程——按照步骤一步一步执行。
现在,我们要学习更强大的"面向对象"编程——把现实世界的事物抽象成"对象"。
1.2 什么是对象?
生活例子:
你周围的一切都是"对象":
- 👤 学生对象:有姓名、年龄、班级,能学习、能考试
- 📱 手机对象:有品牌、颜色、价格,能打电话、能拍照
- 🚗 汽车对象:有品牌、颜色、速度,能启动、能刹车
每个对象都有:
- 属性(特征):姓名、年龄、颜色…
- 方法(行为):学习、打电话、启动…
1.3 关于类定义的语法思考
在学习类之前,我们再聊聊仓颉的语法设计。
仓颉的类定义是:
class 学生 {
var 姓名: String
var 年龄: Int64
init(姓名: String, 年龄: Int64) {
this.姓名 = 姓名
this.年龄 = 年龄
}
}
这里又出现了类型后置的问题!var 姓名: String中,类型String放在了变量名后面。
如果仓颉能像C#那样:
// C#风格
class 学生 {
public string 姓名;
public int 年龄;
public 学生(string 姓名, int 年龄) {
this.姓名 = 姓名;
this.年龄 = 年龄;
}
}
这样读起来就是"字符串 姓名",而不是"姓名 字符串",更符合中国人的定语前置习惯!
不过,仓颉的class关键字表示"类",还是比较直观的。而且类名、属性名、方法名都可以用中文,这一点很好!
1.4 本课目标
今天我们要学习:
- 什么是类(模板)
- 什么是对象(实例)
- 如何定义类
- 如何创建对象
- 属性(特征)和方法(行为)
- 构造函数
- 做一个学生管理系统
二、概念讲解
2.1 类(Class)——对象的模板
什么是类?
类是创建对象的"模板"或"蓝图"。
就像建筑图纸:
- 图纸(类)定义了房子应该有什么(房间、门窗)
- 根据图纸可以建造很多房子(对象)
定义类
class 学生 {
// 属性(特征)
var 姓名: String
var 年龄: Int64
var 班级: String
// 构造函数
init(姓名: String, 年龄: Int64, 班级: String) {
this.姓名 = 姓名
this.年龄 = 年龄
this.班级 = 班级
}
// 方法(行为)
func 自我介绍(): Unit {
println("大家好,我叫${姓名},今年${年龄}岁,来自${班级}班。")
}
func 学习(): Unit {
println("${姓名}正在认真学习...")
}
func 考试(成绩: Int64): Unit {
println("${姓名}考了${成绩}分")
if (成绩 >= 60) {
println("及格了!")
} else {
println("不及格,要加油!")
}
}
}
再次吐槽类型后置:
var 姓名: String、func 自我介绍(): Unit,类型都放在了后面。
如果改进成类型前置:
// 设想中的改进
class 学生 {
String 姓名
Int64 年龄
func 自我介绍(): Unit { // 返回类型后置还可以接受
// 代码
}
}
希望华为能在未来版本中考虑!
2.2 对象(Object)——类的实例
什么是对象?
对象是根据类创建的具体事物。
就像根据图纸建造的房子:
- 图纸(类):定义了房子的结构
- 房子1(对象):张三的家
- 房子2(对象):李四的家
创建对象
main() {
// 创建学生对象
let 张三 = 学生("张三", 15, "初三(1)")
let 李四 = 学生("李四", 16, "初三(2)")
let 王五 = 学生("王五", 15, "初三(1)")
// 使用对象的方法
张三.自我介绍()
张三.学习()
张三.考试(85)
println("")
李四.自我介绍()
李四.考试(92)
}
2.3 访问属性
main() {
let 张三 = 学生("张三", 15, "初三(1)")
// 访问属性
println("姓名:${张三.姓名}")
println("年龄:${张三.年龄}")
// 修改属性
张三.年龄 = 16
println("修改后的年龄:${张三.年龄}")
}
2.4 封装——保护数据
什么是封装?
封装就是把数据保护起来,只能通过特定方法访问。
就像ATM机:
- 你的存款(数据)被保护在机器里
- 只能通过插卡、输密码(方法)来访问
代码示例
class 银行账户 {
// 私有属性(外部不能直接访问)
private var 余额: Float64
private var 密码: String
// 公有属性
public var 账号: String
public var 户名: String
init(账号: String, 户名: String, 初始余额: Float64, 密码: String) {
this.账号 = 账号
this.户名 = 户名
this.余额 = 初始余额
this.密码 = 密码
}
// 存款(公有方法)
public func 存款(金额: Float64): Unit {
if (金额 > 0) {
余额 = 余额 + 金额
println("存款成功,当前余额:${余额}")
} else {
println("存款金额必须大于0")
}
}
// 取款(公有方法)
public func 取款(金额: Float64, 输入密码: String): Unit {
if (输入密码 != 密码) {
println("密码错误!")
return
}
if (金额 > 余额) {
println("余额不足!")
return
}
余额 = 余额 - 金额
println("取款成功,当前余额:${余额}")
}
// 查询余额(公有方法)
public func 查询余额(输入密码: String): Float64 {
if (输入密码 != 密码) {
println("密码错误!")
return 0.0
}
return 余额
}
}
main() {
let 我的账户 = 银行账户("622202123456789", "张三", 1000.0, "123456")
println("户名:${我的账户.户名}")
println("账号:${我的账户.账号}")
// 存款
我的账户.存款(500.0)
// 取款
我的账户.取款(200.0, "123456")
// 查询余额
let 余额 = 我的账户.查询余额("123456")
println("当前余额:${余额}")
}
三、动手实践
3.1 基础练习:学生类
// 学生类
class 学生 {
// 属性
var 姓名: String
var 年龄: Int64
var 班级: String
var 成绩: Int64
// 构造函数
init(姓名: String, 年龄: Int64, 班级: String, 成绩: Int64) {
this.姓名 = 姓名
this.年龄 = 年龄
this.班级 = 班级
this.成绩 = 成绩
}
// 方法
func 自我介绍(): Unit {
println("大家好,我叫${姓名},今年${年龄}岁,来自${班级}班。")
}
func 学习(): Unit {
println("${姓名}正在认真学习...")
}
func 考试(): Unit {
println("${姓名}参加了考试,考了${成绩}分")
if (成绩 >= 90) {
println("评价:优秀")
} else if (成绩 >= 80) {
println("评价:良好")
} else if (成绩 >= 60) {
println("评价:及格")
} else {
println("评价:不及格")
}
}
func 升级(): Unit {
年龄 = 年龄 + 1
println("${姓名}升级了,现在${年龄}岁")
}
}
main() {
println("=== 学生管理系统 ===")
println("")
// 创建学生对象
let 张三 = 学生("张三", 15, "初三(1)", 85)
let 李四 = 学生("李四", 16, "初三(2)", 92)
let 王五 = 学生("王五", 15, "初三(1)", 78)
// 学生列表
let 学生列表 = [张三, 李四, 王五]
// 显示所有学生信息
println("【所有学生】")
for (学生 in 学生列表) {
学生.自我介绍()
}
println("")
// 让所有学生学习
println("【学习时间】")
for (学生 in 学生列表) {
学生.学习()
}
println("")
// 让所有学生考试
println("【考试时间】")
for (学生 in 学生列表) {
学生.考试()
println("")
}
// 升级
println("【升级】")
for (学生 in 学生列表) {
学生.升级()
}
}
3.2 进阶练习:图书类
// 图书类
class 图书 {
// 属性
var 书名: String
var 作者: String
var 出版社: String
var 价格: Float64
var 是否借出: Bool
// 构造函数
init(书名: String, 作者: String, 出版社: String, 价格: Float64) {
this.书名 = 书名
this.作者 = 作者
this.出版社 = 出版社
this.价格 = 价格
this.是否借出 = false
}
// 方法
func 显示信息(): Unit {
println("《${书名}》")
println("作者:${作者}")
println("出版社:${出版社}")
println("价格:${价格}元")
println("状态:${是否借出 ? "已借出" : "可借阅"}")
}
func 借阅(): Unit {
if (是否借出) {
println("抱歉,《${书名}》已被借出")
} else {
是否借出 = true
println("《${书名}》借阅成功")
}
}
func 归还(): Unit {
if (!是否借出) {
println("《${书名}》没有被借出")
} else {
是否借出 = false
println("《${书名}》归还成功")
}
}
}
main() {
println("=== 图书馆管理系统 ===")
println("")
// 创建图书
let 图书1 = 图书("西游记", "吴承恩", "人民文学出版社", 45.0)
let 图书2 = 图书("红楼梦", "曹雪芹", "人民文学出版社", 50.0)
let 图书3 = 图书("三国演义", "罗贯中", "人民文学出版社", 48.0)
let 图书列表 = [图书1, 图书2, 图书3]
// 显示所有图书
println("【图书馆藏书】")
for (图书 in 图书列表) {
图书.显示信息()
println("")
}
// 借阅图书
println("【借阅操作】")
图书1.借阅()
图书1.借阅() // 再次借阅,应该失败
println("")
// 归还图书
println("【归还操作】")
图书1.归还()
}
3.3 挑战练习:游戏角色类
// 游戏角色类
class 角色 {
// 属性
var 名字: String
var 职业: String
var 等级: Int64
var 生命值: Int64
var 魔法值: Int64
var 攻击力: Int64
var 防御力: Int64
// 构造函数
init(名字: String, 职业: String) {
this.名字 = 名字
this.职业 = 职业
this.等级 = 1
this.生命值 = 100
this.魔法值 = 50
this.攻击力 = 10
this.防御力 = 5
}
// 方法
func 显示状态(): Unit {
println("【${名字}】")
println("职业:${职业}")
println("等级:${等级}")
println("生命值:${生命值}")
println("魔法值:${魔法值}")
println("攻击力:${攻击力}")
println("防御力:${防御力}")
}
func 升级(): Unit {
等级 = 等级 + 1
生命值 = 生命值 + 20
魔法值 = 魔法值 + 10
攻击力 = 攻击力 + 5
防御力 = 防御力 + 3
println("${名字}升级了!当前等级:${等级}")
}
func 攻击(目标: 角色): Unit {
let 伤害 = 攻击力 - 目标.防御力
if (伤害 > 0) {
目标.生命值 = 目标.生命值 - 伤害
println("${名字}攻击了${目标.名字},造成${伤害}点伤害")
} else {
println("${名字}攻击了${目标.名字},但未造成伤害")
}
}
func 是否存活(): Bool {
return 生命值 > 0
}
}
main() {
println("=== 角色对战 ===")
println("")
// 创建角色
let 战士 = 角色("亚瑟", "战士")
let 法师 = 角色("梅林", "法师")
// 显示初始状态
println("【初始状态】")
战士.显示状态()
println("")
法师.显示状态()
println("")
// 升级
println("【升级】")
战士.升级()
战士.升级()
println("")
// 对战
println("【对战开始】")
while (战士.是否存活() && 法师.是否存活()) {
战士.攻击(法师)
if (法师.是否存活()) {
法师.攻击(战士)
}
println("")
}
// 显示结果
println("【对战结束】")
if (战士.是否存活()) {
println("${战士.名字}获胜!")
} else {
println("${法师.名字}获胜!")
}
}
四、知识总结
4.1 核心概念回顾
- 类:创建对象的模板
- 对象:类的实例
- 属性:对象的特征
- 方法:对象的行为
- 构造函数:创建对象时初始化
- 封装:保护数据
4.2 关于语法设计的总结
仓颉的类定义语法:
class 学生 {
var 姓名: String
var 年龄: Int64
init(姓名: String, 年龄: Int64) {
this.姓名 = 姓名
this.年龄 = 年龄
}
}
优点:
class关键字直观- 类名、属性名、方法名可以用中文
- 支持封装
可以改进的地方:
- 属性类型后置
- 方法返回类型后置
如果改进成类型前置:
// 设想中的改进
class 学生 {
String 姓名
Int64 年龄
学生(String 姓名, Int64 年龄) {
this.姓名 = 姓名
this.年龄 = 年龄
}
}
希望华为能在未来版本中考虑!
4.3 关键代码速查
// 定义类
class 类名 {
// 属性
var 属性名: 类型
// 构造函数
init(参数: 类型) {
this.属性名 = 参数
}
// 方法
func 方法名(): 返回类型 {
return 结果
}
}
// 创建对象
let 对象 = 类名(参数)
// 访问属性
对象.属性名
// 调用方法
对象.方法名()
4.4 常见错误提醒
| 错误现象 | 原因 | 解决方法 |
|---|---|---|
| 属性未初始化 | 构造函数中没有赋值 | 在init中初始化 |
| 无法访问私有属性 | 属性是private | 使用公有方法访问 |
| 方法调用错误 | 方法名错误或对象为空 | 检查方法名和对象 |
五、课后作业
5.1 巩固练习(必做)
练习1:设计汽车类
属性:品牌、颜色、速度、油量
方法:启动、加速、刹车、加油
练习2:设计动物类
属性:名字、种类、年龄
方法:吃、睡、叫
练习3:设计购物车类
属性:商品列表、总价
方法:添加商品、删除商品、计算总价
5.2 创意编程(选做)
创意1:设计游戏角色系统
战士、法师、弓箭手等不同职业。
创意2:设计银行账户系统
支持存款、取款、转账、查询余额。
创意3:设计学校管理系统
学生、老师、课程、成绩管理。
5.3 下篇预习
下一篇,我们将学习继承和多态,这是面向对象编程的高级特性。
恭喜你完成了第8篇的学习! 🎉
现在你已经掌握了面向对象编程的基础,可以创建类和对象了!
下节课,我们将学习继承和多态,这是更强大的面向对象特性!
更多推荐




所有评论(0)