第12章 类-面向对象
Python是一门面向对象的语言,在面向对象的概念中Python允许用户自定义数据类型,这种自定义的数据类型叫做类。类(class)是用来描述具有相同属性和方法的对象的集合。
12.1 类的定义
语法格式如下:
class ClassName(): # 类名首字母必须大写
statement1
...
statementn
程序实例:
class Student(): # 定义类
name = '张三' # 定义属性name
age = '18' # 定义属性age
def motto(self): # 定义方法
return "好好学习,天天向上"
12.2 类对象
类对象支持两种操作:属性引用和实例化。属性引用使用的标准语法:obj.name(即对象.属性名)。类对象创建后,类命名空间中所有的命名都是有效属性名。
程序实例:
class Student(): # 定义类
name = '张三' # 定义属性name
age = '18' # 定义属性age
def motto(self): # 定义方法
return "好好学习,天天向上"
# 实例化类
stu = Student()
# 访问类的属性和方法
print("Student类的属性name为:", stu.name)
print("Student类的属性age为:", stu.age)
print("Student类的方法motto输出为:", stu.motto())
执行结果:
Student类的属性name为: 张三
Student类的属性age为: 18
Student类的方法motto输出为: 好好学习,天天向上
类有一个名为__init__()的特殊方法(构造方法),该方法在类实例化时会自动调用。_init_() 方法可以有参数,参数可以传递到类的实例化操作上。
程序实例:
class Complex:
def __init__(self, realpart, imgpart): # self代表类的实例,而非类
self.r = realpart
self.i = imgpart
x = Complex(3.0, -4.5)
print(x.r, x.i)
执行结果:
3.0 -4.5
12.3 类的方法
在类的内部,使用def关键字来定义一个方法。与一般函数定义不同,类方法必须包含参数self,且为第一个参数,self代表的是类的实例。
程序实例:
# 类定义
class People:
# 定义基本属性
name = ''
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def say(self):
print("我叫 %s,今年 %d 岁" % (self.name, self.age))
# 实例化类
p = People('罗三', 18, 60)
p.say()
执行结果:
我叫 罗三,今年 18 岁
12.4 继承
Python同样支持类的继承,派生类的定义如下所示:
class DerivedClassName(BaseClassName):
statement1
...
statementn
BaseClassName(基类名)必须与派生类定义在一个作用域内。
程序实例:
# 类定义
class People:
# 定义基本属性
name = ''
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def say(self):
print("我叫 %s,今年 %d 岁" % (self.name, self.age))
# 单继承示例
class Student(People):
hobby = ''
def __init__(self, n, a, w, h):
# 调用父类的构造函数
People.__init__(self, n, a, w)
self.hobby = h
# 覆写父类的方法
def say(self):
print("我叫 %s ,今年 %d 岁,我喜欢 %s" % (self.name, self.age, self.hobby))
# 实例化类
p = People('罗三', 18, 60)
p.say()
s = Student('张三', 18, 55, '游泳')
s.say()
执行结果:
我叫 罗三,今年 18 岁
我叫 张三 ,今年 18 岁,我喜欢 游泳
12.5 多继承
Python同样有限的支持多继承形式。多继承的类定义如下所示:
class DerivedClassName(Base1, Base2, Base3):
statement1
...
statementn
需要注意括号中父类的顺序,若父类中有相同的方法名,而在子类使用时未指定,python将从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法。
程序实例:
# 类定义
class People:
# 定义基本属性
name = ''
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def say(self):
print("我叫 %s,今年 %d 岁" % (self.name, self.age))
# 单继承示例
class Student(People):
hobby = ''
def __init__(self, n, a, w, h):
# 调用父类的构造函数
People.__init__(self, n, a, w)
self.hobby = h
# 覆写父类的方法
def say(self):
print("我叫 %s ,今年 %d 岁,我喜欢 %s" % (self.name, self.age, self.hobby))
class Speaker():
topic = ''
name = ''
def __init__(self, n, t):
self.name = n
self.topic = t
def say(self):
print("我叫 %s, 是一个演说家,今天我演讲的主题是 %s" % (self.name, self.topic))
# 多重继承
class Sample(Speaker, Student):
a = ''
def __init__(self, n, a, w, h, t):
Student.__init__(self, n, a, w, h)
Speaker.__init__(self, n, t)
# 实例化类
p = People('罗三', 18, 60)
p.say()
s = Student('张三', 18, 55, '游泳')
s.say()
sp = Sample('川建国', 20, 60, '唱、跳、rap', '疫情防控')
sp.say()
执行结果:
我叫 罗三,今年 18 岁
我叫 张三 ,今年 18 岁,我喜欢 游泳
我叫 川建国, 是一个演说家,今天我演讲的主题是 疫情防控
12.6 方法重写
有时父类的方法可能并不能满足需求,此时可以在子类中重写父类的方法。
程序实例:
class Parent: # 定义父类
def myMethod(self):
print('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self): # 重写父类方法
print('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
super(Child,c).myMethod() # 用子类对象调用父类已被覆盖的方法
执行结果:
调用子类方法
调用父类方法
面向对象示例–学员管理系统:
"""
需求:
1.存储数据的位置:文件(student.data)
- 加载文件数据
- 修改数据后保存到文件
2.存储数据的形式:列表存储学员对象
3.系统功能:
- 添加学员
- 删除学员
- 修改学员
- 查询学员信息
- 显示所有学员信息
- 保存学员信息
"""
import ast
# 定义学员类类
class Student(object):
"""学员类"""
def __init__(self, name, gender, tel):
# 姓名、性别、手机号
self.name = name
self.gender = gender
self.tel = tel
def __str__(self):
return f'{self.name}, {self.gender}, {self.tel}'
# 定义学员管理类
class StudentManager(object):
"""学员管理类"""
"""
管理系统框架
需求:系统功能循环使用,用户输入不同的功能序号执行不同的功能。
步骤:
1.定义程序入口函数:
- 加载数据
- 显示功能菜单
- 用户输入功能序号
- 根据用户输入的功能序号执行不同功能
2.定义系统功能函数,添加删除学员等
"""
def __init__(self):
# 存储数据所用的列表
self.student_list = []
# 程序入口函数,启动程序后执行的函数
def run(self):
# 1.加载文件里面的学员数据
self.load_student()
while True:
# 2.显示功能菜单
self.show_menu()
# 3.用户输入目标功能序号
menu_num = int(input('请输入您需要的功能序号:'))
# 4.根据用户输入的序号执行不同的功能
if menu_num == 1:
# 添加学员
self.add_student()
elif menu_num == 2:
# 删除学员
self.del_student()
elif menu_num == 3:
# 修改学员信息
self.modify_student()
elif menu_num == 4:
# 查询学员信息
self.search_student()
elif menu_num == 5:
# 显示所有学员信息
self.show_student()
elif menu_num == 6:
# 保存学员信息
self.save_student()
elif menu_num == 7:
confirm = input('确定要退出吗?(Y/N)')
if confirm == 'Y':
break
# 退出系统 -- 退出循环
break
else:
print('输入的功能序号有误!')
# 2.系统功能函数
# 2.1 显示功能菜单
@staticmethod
def show_menu():
"""显示功能菜单"""
print('*'*8 + '欢迎使用学员管理系统' + '*'*8)
print('请选择如下功能:')
print('1--添加学员')
print('2--删除学员')
print('3--修改学员信息')
print('4--查询学员信息')
print('5--显示所有学员信息')
print('6--保存学员信息')
print('7--退出系统')
# 2.2 添加学员
def add_student(self):
"""
需求:用户输入学员姓名、性别、手机号,将学员添加到系统
步骤:
- 用户输入姓名、性别、手机号
- 创建该学员对象
- 将该学员对象添加到列表
"""
# 1.用户输入姓名、性别、手机号
name = input('请输入新学员姓名:')
# 判断学员是否已存在
for i in self.student_list:
if i.name == name:
print('该学员已存在!')
return
gender = input('请输入新学员性别:')
tel = input('请输入新学员手机号:')
# 2.创建该学员对象
stu = Student(name, gender, tel)
# 3.将该学员对象添加到列表
self.student_list.append(stu)
# print(self.student_list)
# print(stu)
# 2.3 删除学员
def del_student(self):
"""删除学员"""
# 1.用户输入目标学院姓名
del_name = input('请输入要删除的学员姓名:')
# 2.判断该学员是否存在,遍历学员列表,存在则删除,不存在则提示
for i in self.student_list:
if i.name == del_name:
self.student_list.remove(i)
break
else:
print('查无此人!')
# 打印学员列表,验证删除是否成功
# print(self.student_list)
self.show_student()
# 2.4 修改学员信息
def modify_student(self):
"""修改学员信息"""
# 1.用户输入目标学员姓名
modify_name = input('请输入要修改的学员的姓名:')
# 2.判断学员是否存在
for i in self.student_list:
if i.name == modify_name:
i.name = input('姓名:')
i.gender = input('性别:')
i.tel = input('手机号:')
print(f'修改学员信息:姓名:{i.name},性别:{i.gender},手机号:{i.tel}')
break
else:
print('查无此人!')
# 2.5 查询学员信息
def search_student(self):
"""查询学员信息"""
# 1.输入目标学员姓名
search_name = input('请输入要查询的学员姓名:')
# 2.遍历判断学员是否存在,存在则打印
for i in self.student_list:
if i.name == search_name:
print(f'姓名:{i.name},性别:{i.gender},手机号:{i.tel}')
break
else:
print('查无此人!')
# 2.6 显示所有学员信息
def show_student(self):
print('姓名\t性别\t手机号')
for i in self.student_list:
print(f'{i.name}\t{i.gender}\t{i.tel}')
# 2.7 保存学员信息
def save_student(self):
"""保存学员信息"""
"""
需求:将修改后的学员数据保存到存储数据的文件
步骤:
- 打开文件
- 写入数据--写入的应该是字典
- 关闭文件
"""
# 1.打开文件
f = open('student.data', 'w')
# 2.写入数据
# 2.1文件写入的数据不能是学员对象的内存地址,需要将学员数据转换成列表数据再做存储
# __dict__返回的是字典
new_list = [i.__dict__ for i in self.student_list]
print(new_list)
# 2.2文件内数据要求为字符串类型,需要先转换数据类型为字符串才能写入
f.write(str(new_list))
# 3.关闭文件
f.close()
# 2.8 加载学员信息
def load_student(self):
"""加载学员信息"""
# print('加载数据')
# 1.打开文件
f = open('student.data', 'r')
# 2.读取数据---得到的是字符串
content = f.readline()
# 通过literal_eval得到有效表达式--这里的得到的是列表
content = ast.literal_eval(content)
for i in content:
stu = Student(i['name'], i['gender'], i['tel'])
self.student_list.append(stu)
# 3.关闭文件
f.close()
# 启动学员管理系统
# 保证是当前文件运行才启动管理系统
if __name__ == '__main__':
student_manager = StudentManager()
student_manager.run()
参考文章链接:
https://www.runoob.com/python3/python3-class.html
往期文章:
- 《Python零基础快乐学习之旅》学习笔记2——认识变量与基本数学运算
- 《Python零基础快乐学习之旅》学习笔记3——Python的基本数据类型
- 《Python零基础快乐学习之旅》学习笔记4——基本输入与输出
- 《Python零基础快乐学习之旅》学习笔记5——程序的流程控制使用if语句
- 《Python零基础快乐学习之旅》学习笔记6——列表(list)
- 《Python零基础快乐学习之旅》学习笔记7——循环设计
- 《Python零基础快乐学习之旅》学习笔记8——元组(tuple)
- 《Python零基础快乐学习之旅》学习笔记9——字典(dict)
- 《Python零基础快乐学习之旅》学习笔记10——集合(set)
- 《Python零基础快乐学习之旅》学习笔记11——函数设计