内容简介
- 类和对象之间的关系
- 面向对象设计基本步骤
- 定义类和创建对象
- 使用构造方法实例化对象
- 掌握封装的概念及其使用
定义类
-
定义类
# 演员类 class Actor: def __init__(self, name, sex, job): self.name = name # 使用变量存储数据域,表示状态或属性 self.sex = sex self.job = job # 共有行为:吃饭、表演 def eat(self): # 使用方法(类中定义的函数)/函数来定义一个对象的行为 pass def performs(self): pass
-
创建对象
类会提供一种特殊的方法:_ init _,被称为初始化程序,它在创建和初始化这个新对象时被调用
# 一旦定义了一个类,就可以使用构造方法由类来创建对象 actor = Actor("佟湘玉", "女", "掌柜的")
类和对象之间的关系
-
类是抽象的概念,仅仅是模板
-
对象是一个你能够看得到、摸得着的具体实体
构造方法
-
对象的初始化方式很"low"且容易遗漏
role = Role() role.name = “佟湘玉" role.sex = "女" role.job = "掌柜的" role.age = 28;
-
解决方案:使用构造方法传参
def __init__(self, name, intro, power, type): self.name = name self.intro = intro self.power = power self.type = type
隐藏数据域
-
数据域私有
def set_age(self, age): if 0 <= age <= 100: self.__age = age else: self.__age = 18 def get_age(self): return self.__age
-
让数据域私有来保护数据
-
为避免直接修改数据域,就不要让类用户直接访问数据域,这被称为数据隐藏
-
在Python中,私有数据域以两个下划线开头
-
私有数据域和方法只能在类的内部被访问
# @function:隐藏数据域 # @Description:一只萤火虫 class Role: def __init__(self, name, sex, job, age): self.__name = name # 两个前导下划线开头的变量仅供对象的内部使用 -- 私有数据域 self.__sex = True self.__age = age self.set_age(age) self._job = "一个下划线" # 一个下划线开头的属性,称为受保护的属性 def set_sex(self, sex): self.__sex = sex def set_age(self, age): if age > 100 or age < 0: self.__age = 18 else: self.__age = age def is_sex(self): """ bool类型成员,一般使用is开头的方法实现读取器 """ return self.__sex def get_age(self): return self.__age def get_name(self): return self.__name # 因为没有定义set_name方法,所以name一旦确定,后面就不能修改了 if __name__ == '__main__': role = Role("李大嘴", "男", "大厨", 25) print(role.get_name() + "年龄是:", role.get_age()) print("受保护的属性仍然可以被类的用户访问到", role._job)
-
-
注意:
-
1、类只是在程序内部使用,没有必要隐藏数据域;类需要给其它程序使用时,为了防止数据域被修改,需要隐藏数据域
-
2、不要以一个以上的下划线结尾:Python中,以两个下划线开头并结尾的名字具有特殊意义
-
3、类的抽象是将类的实现和使用相分离;类的实现细节对用户而言是不可见的,这就是类的封装
-
使用内标操作多个对象
-
使用列表可以简化对多个同类型对象的操作
模块代码# @Projection: 定义类 # @Function: 一只萤火虫 # 演员类 class Actor: def __init__(self, name, sex, job="演员"): self.name = name # 使用变量存储数据域,表示状态或属性 self.sex = sex self.job = job def __eq__(self, other): """ 当调用 == 符号比较两个对象时,自动调用本方法 """ if self.name == other.name: return True else: return False # 共有行为:吃饭、表演 def eat(self): # 使用方法(类中定义的函数)/函数来定义一个对象的行为 pass def performs(self): # self. 可以访问当前对象定义的属性以及方法 print(self.sex + "子, " + self.name + "正在表演拿手好戏!")
主程序
from actor import Actor # 引入模块 if __name__ == '__main__': actor_list = [ Actor("佟湘玉", "女"), Actor("吕轻侯", "男"), Actor("白展堂", "男"), Actor("郭芙蓉", "女") ] # 判断对象是否存在于列表中 new_actor = Actor("佟湘玉", "女") is_exists = False for actor in actor_list: if new_actor == actor: is_exists = True if not is_exists: actor_list.append(new_actor) # 可以使用循环操作多个在列表中的对象 for actor in actor_list: actor.performs() print(Actor("佟湘玉", "女") == Actor("佟湘玉", "女"))
输出结果
可变对象和不可变对象
-
可变对象传参时内容有可能改变
# @function:自定义的类实例就是一个可变类型 # @Description:一直萤火虫 class User: def __init__(self, user_name, login_pwd): """ :param user_name: 登录用户名 :param login_pwd: 登录密码 """ self.__user_name = user_name self.__login_pwd = login_pwd self.__login_count = 0 # 用来记录当前用户登录成功的次数 def get_user_name(self): return self.__user_name def get_login_pwd(self): return self.__login_pwd def get_login_count(self): return self.__login_count def set_login_count(self, login_count): if login_count < 0: self.__login_count = 0 else: self.__login_count = login_count def __eq__(self, other): return self.__user_name == other.get_user_name() and self.__login_pwd == other.get_login_pwd() # 已经注册的用户列表 register_user_list = [ User("墨家巨子", "兼爱非攻"), User("鬼谷子", "天下大势,唯我纵横"), User("道家", "道法自然"), User("123", "123456") ] class UserManagement: """ 用户业务类:当程序逻辑非常复杂时,可以讲关于用户的业务逻辑方法单独封装在这个类中 """ def validate(self, user): user.set_login_count(1000) for curr in register_user_list: if curr == user: curr.set_login_count(curr.get_login_count() + 1) return curr return None if __name__ == '__main__': user_name = input("请输入用户名:") password = input("请输入密码:") login_user = User(user_name, password) # 实例化业务对象,调用验证方法 user_manager = UserManagement() result = user_manager.validate(login_user) if not result: print("用户名和密码不匹配!") else: print("登录成功,欢迎您:", result.get_user_name()) print("登录系统的次数:", result.get_login_count()) print("可变类型在函数中修改属性后:", login_user.get_login_count()) 输出结果: 请输入用户名:123 请输入密码:123456 登录成功,欢迎您: 123 登录系统的次数: 1 1000
小结:面向对象的思考
-
使用面向对象的软件设计重点在对象以及对象的操作上
-
在面向过程程序中,数据和数据上的操作是分离的,而且这种做法要求传递数据给方法
-
面向对象程序设计将数据和对它们的操作都放在一个对象中
-
面向对象程序设计方法以一种反映真实世界的方式组织程序
- 在真实世界中,所有的对象和属性及动作都是相关联的
- 使用对象提高了软件的可重用性,并且使程序更易于开发和维护
-
Python程序设计涉及对对象的思考,一个Python程序可以看做是一个相互操作对象的集合
-
封装的概念:
-
封装对象初始化
-
封装对象的操作
-
封装对象的内部数据
-