title: 【python基础之面向对象介绍】--- 面向对象
date: 2024-01-04 14:54:06
updated: 2024-01-04 15:20:00
description: python的面向对象介绍
cover:
https://home.cnblogs.com/u/dream-ze/
https://zhuanlan.zhihu.com/p/365265818
【一】面向对象导读/前言
用当前的知识点写一个有关人狗大战的小游戏
# 【一】角色信息
# 我们可以选一个角色 : 角色的名字,年龄,性别,攻击值,生命值
# 我们可以选一个角色 : 角色的名字,角色的类型,攻击值,生命值
# 【二】功能
# 功能 : 人打狗,狗肯定会疼,会掉血
# 功能 : 狗咬人,人肯定会疼,会掉血
# 【三】开发功能
# 【1】定义参数
dog_dict_one = {
'dog_name': "旺财",
'dog_type': "田园犬",
'attack': 10,
'health': 100
}
dog_dict_two = {
'dog_name': "小獒",
'dog_type': "藏獒",
'attack': 20,
'health': 100
}
person_dict = {
'person_name': "lolo",
'person_gender': "male",
'person_age': 28,
'attack': 30,
'health': 100
}
# 【2】狗咬人 / 人打狗
# 定义成函数
def dog_attack_person(dog: dict, person: dict):
'''
:param dog: 狗
:param person: 人
:return:
'''
# 狗咬人 ---> 人会掉血
person['health'] -= dog['attack']
print(f'{dog["dog_name"]} 咬了 {person["person_name"]} 掉了 {dog["attack"]}血')
def person_attack_dog(dog: dict, person: dict):
'''
:param dog: 狗
:param person: 人
:return:
'''
# 狗咬人 ---> 人会掉血
dog['attack'] -= person['health']
print(f'{person["person_name"]} 打了 {dog["dog_name"]} 掉了 {dog["attack"]}血')
# 调用函数传递参数
dog_attack_person(dog=dog_dict_one, person=person_dict)
print(person_dict)
# 【三】开发功能
# 【1】定义参数
def create_dog(dog_name, dog_type, attack, health):
dog_dict = {
'dog_name': dog_name,
'dog_type': dog_type,
'attack': attack,
'health': health
}
return dog_dict
def create_person(person_name, person_gender, person_age, attack, health):
person_dict = {
'person_name': person_name,
'person_gender': person_gender,
'person_age': person_age,
'attack': attack,
'health': health
}
return person_dict
# 【2】狗咬人 / 人打狗
# 定义成函数
def dog_attack_person(dog: dict, person: dict):
'''
:param dog: 狗
:param person: 人
:return:
'''
# 狗咬人 ---> 人会掉血
person['health'] -= dog['attack']
print(f'{dog["dog_name"]} 咬了 {person["person_name"]} 掉了 {dog["attack"]}血')
def person_attack_dog(dog: dict, person: dict):
'''
:param dog: 狗
:param person: 人
:return:
'''
# 狗咬人 ---> 人会掉血
dog['attack'] -= person['health']
print(f'{person["person_name"]} 打了 {dog["dog_name"]} 掉了 {dog["attack"]}血')
# 获取人和狗的参数
dog_dict_one = create_dog(dog_name="旺财", dog_type="田园犬", attack=10, health=100)
dog_dict_two = create_dog(dog_name="小獒", dog_type="藏獒", attack=20, health=100)
person_dict = create_person(person_name='lolo', person_gender='male', person_age=28, attack=30, health=100)
# 调用函数传递参数
dog_attack_person(dog=dog_dict_one, person=person_dict)
print(person_dict)
【二】面向过程与面向对象
# 【零】面条版
# 一条线穿到底
# 缺点:不容易维护和开发
# 【一】面向过程 (函数)
# 核心在于:过程
# 过程其实就是将程序流程化
# 可以说是一条流水线,分步骤的解决问题,先干什么再干什么,分的很清楚
# 【二】面向对象 (类)
# 面向对象核心在于对象二字
# 对象就是相当于一个整合体 ,把数据和功能整合到一起
# 比如我们有一个酒厂
# 面条班:这个酒厂每个厂子 生产出来酒。如果有人买酒,就从厂子里开始给人家送酒
# 函数版:我们得厂子,不是上面那样直接从生产线送出去了,而是酒厂里面会有一个仓库,如果有客户下单,就会从仓库里面拿东西送出去
# 对象版:我们变成了经销商模式,开分店,分店里面有自己的库存,酒,如果有客户买,直接从经销商手中买酒
# 先有学校还是先有学生?
# 先有学生,再有学校
# 学生:自己的名字,自己的年龄,自己的性别
# 比如一个学生可以上课、写作业、运动;
def student():
def sport():
...
student_dict = {
'name': 'name',
'sport': sport
}
# 比如一个老师可以教课、批改作业;
# 比如一个运动员可以训练、参加比赛
# 学校 :
# 学校有名字
# 学校有地址
# 先有酒厂再有经销商
# 面向对象去写上述的学校的这个类
# 类:其实就是相当于我们的酒厂
# 对象:相当于我们的经销商,经销商有自己的位置,有自己的存酒
# 类即类别/种类,
# 是面向对象分析和设计的基石,如果多个对象有相似的数据与功能,那么该多个对象就属于同一种类。
# 经销商有自己的位置,有自己的酒,有自己的定价 -- 对象
# 他们都有共有的属性 : 位置,酒,定价 -- 类
# 学生 : 运动员,老师,上课学生 -- 对象
# 同属于一个学校,都有各自的名字,年龄,职责 -- 类
【三】类导读
- 类即类别/种类,是面向对象分析和设计的基石,如果多个对象有相似的数据与功能,那么该多个对象就属于同一种类。
- 有了类的好处是:
- 我们可以把同一类对象相同的数据与功能存放到类里,而无需每个对象都重复存一份,这样每个对象里只需存自己独有的数据即可,极大地节省了空间。
- 所以,如果说对象是用来存放数据与功能的容器,那么类则是用来存放多个对象相同的数据与功能的容器。
- 综上所述,虽然我们是先介绍对象后介绍类,但是需要强调的是:
- 在程序中,必须要事先定义类,然后再调用类产生对象(调用类拿到的返回值就是对象)。
- 产生对象的类与对象之间存在关联,这种关联指的是:对象可以访问到类中共有的数据与功能
- 所以类中的内容仍然是属于对象的,类只不过是一种节省空间、减少代码冗余的机制
- 面向对象编程最终的核心仍然是去使用对象。
【四】什么是类
- 类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体
- 所以,先有鸡和先有蛋的问题就出来了
- 先有的一个个具体存在的对象(比如一个具体存在的人)
- 还是先有的人类这个概念,这个问题需要分两种情况去看
(1)现实中
- 在现实世界中:先有对象,再有类
- 世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念
- 也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在
(2)程序中
- 在程序中:务必保证先定义类,后产生对象
- 这与函数的使用是类似的,先定义函数,后调用函数,类也是一样的,在程序中需要先定义类,后调用类
- 不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象
【五】类的定义
# 我们有学校 ,我们有学生
# 学校有学校的属性
# 学生有学生的属性
# 可以有不同的学校 -- 对象
# 学校都有共同的属性 -- 学校名字,学校位置
# 学生有不同的角色,自己的名字,年龄,职业 -- 对象
# 学生都共有的属性 -- 角色名字,名字,年龄,职业 -- 对象
'''
# 学生类
相同的特征:
学校=实验一中
相同的功能:
读书
写作
跑步
'''
# def DreamStudent():
# school = '实验一中'
# def read():
# print(f'可以读书')
#
# def write():
# print(f'可以写作')
#
# def running():
# print(f'可以跑步')
# return {
# 'school':school,
# 'read':read,
# 'write':write,
# 'running':running,
# }
# print(DreamStudent())
'''
# 定义类
class(关键字) 类名():
# 定义参数
# 定义函数
# 调用类 ---> 得有一个具体的对象才能调用类
'''
# 定义学生类
# class DreamStudent():
# school = '实验一中'
#
# def read(self):
# print(f'可以读书')
#
# def write(self):
# print(f'可以写作')
#
# def running(self):
# print(f'可以跑步')
(1)类的创建语法格式:
class ClassName:
'''变量'''
'''方法'''
pass
class 是关键字,表示类。例如 class Student 即创建了一个 Student 类。
(2)类的数据成员
数据成员包括:变量和方法。
(2.1)变量
类变量 :定义在类中且在函数体之外,在实例化对象中是公有的。
course_count = 4 # 类变量
实例变量:在类的内部,但是在类的其他成员方法之外声明,在实例化对象中是私有的。
def __init__(self, name, number):
self.name = name # 实例变量
self.number = number # 实例变量
本例是通过构造函数来声明,类变量和实例变量的区别很大,访问方式也也不一样。
(2.2)方法
类中定义的函数:
# 定义方法
def show(self):
print(f'姓名: {self.name},学号: {self.number}')
初始化时的构造函数也是一种方法。
提示:
- 在对象的方法里面都有一个self参数, 比如__init__(self), show(self)。 这里的self是指对象本身而非类本身。
- 构造方法__init__(self,....):在生成对象时调用,可以用来进行一些初始化操作,不需要显示去调用,系统会默认去执行。构造方法支持重载,如果用户自己没有重新定义构造方法,系统就自动执行默认的构造方法。
(3) 私有/公有
类里面的私有属性和私有方法以双下划线__开头。私有属性或方法不能在类的外部被使用或直接访问,公有属性和公有方法可以在类的外部被使用或直接访问。
def __init__(self, name, number, score):
self.name = name # 实例变量
self.number = number # 实例变量
self.__score = score # 私有变量
# 实例化
stu1 = Student('当打之年','001',90)
print(stu1.name) # 当打之年
print(stu1.__score) # AttributeError: 'Student' object has no attribute '__score'
【六】查看和修改类的属性/调用
- 方式一
# 定义学生类
# class DreamStudent():
# school = '实验一中'
#
# def read(self):
# print(f'可以读书')
#
# def write(self):
# print(f'可以写作')
#
# def running(self):
# print(f'可以跑步')
# 调用:先实例化类得到一个对象
# stu1 = DreamStudent()
# stu2 = DreamStudent()
# print(stu1) # <__main__.DreamStudent object at 0x000001EB964A2CD0>
# dir 方法查看对象具有的功能
# print(dir(stu1))
# print(stu1.school)
# print(stu1.__dict__)
# stu1.__dict__['name'] = 'dream'
# stu1.__dict__['age'] = 18
# stu1.__dict__['gender'] = 'male'
# print(stu1.__dict__)
# print(stu1.name)
# print(stu1.school)
- 方式二
class DreamStudent():
school = '实验一中'
def read(self):
print(f'可以读书')
def write(self):
print(f'可以写作')
def running(self):
print(f'可以跑步')
def init(obj, name, age, gender):
# 【三】向对象中修改对象的独有属性
obj.__dict__['name'] = name
obj.__dict__['age'] = age
obj.__dict__['gender'] = gender
# 【一】先调用类实例化得到一个对象
stu1 = DreamStudent()
stu2 = DreamStudent()
# 【二】调用初始化对象的方法,得到独有的对象属性
init(obj=stu1, name='dream', age=18, gender='male')
init(obj=stu2, name='hope', age=28, gender='female')
print(stu1.__dict__)
print(stu2.__dict__)
- 方式三
# class DreamStudent():
# school = '实验一中'
#
# def read(self):
# print(f'可以读书')
#
# def write(self):
# print(f'可以写作')
#
# def running(self):
# print(f'可以跑步')
#
# def set_info(self, name, age, gender):
# # self 就是当前类实例化出来的对象
# # 【三】向对象中修改对象的独有属性
# self.__dict__['name'] = name
# self.__dict__['age'] = age
# self.__dict__['gender'] = gender
#
#
# # 【一】先调用类实例化得到一个对象
# stu1 = DreamStudent()
# stu2 = DreamStudent()
# # print(stu1.__dict__)
# # print(dir(stu1))
# # 【二】调用初始化对象的方法,得到独有的对象属性
# # 对象调用类的方法时,会将对象本身作为参数 self 传进去
# stu1.set_info(name='dream', age=18, gender='male')
# stu2.set_info(name='hope', age=28, gender='female')
#
# print(stu1.__dict__)
# print(stu2.__dict__)
- 方式四
# class DreamStudent():
# school = '实验一中'
#
# # 魔法方法 --- init 初始化方法
# def __init__(self, name, age, gender):
# # self 就是当前类实例化出来的对象
# # 【三】向对象中修改对象的独有属性
# self.name = name
# self.age = age
# self.gender = gender
#
# def read(self,sex):
# # print(self,dir(self))
# # print(self.name)
# print(f' {sex}可以读书')
#
# def write(self):
# print(f'可以写作')
#
# def running(self):
# print(f'可以跑步')
#
#
# # 【一】先调用类实例化得到一个对象
# # 和我们的调用函数很像 返回值可以是任意类型 = 函数名(参数名=参数值)
# # 返回值是一个类的对象 = 类名(参数名=参数值)
# stu1 = DreamStudent(name='dream', age=18, gender='male')
# stu2 = DreamStudent(name='hope', age=28, gender='female')
# # print(stu1.__dict__)
# # print(dir(stu1))
# # 【二】调用初始化对象的方法,得到独有的对象属性
# # 对象调用类的方法时,会将对象本身作为参数 self 传进去
# # print(dir(stu1))
# stu1.read(sex='男')