在学习'对象'之前,程序中的数据和功能是分离的,而对象会把数据和功能整合起来。程序=数据结构+算法
# 分离举例
# 数据:姓名,年龄
name = 'XX'
age = 20
# 功能
def func(name,age):
print('姓名:{},年龄:{}'.format(name,age))
func(name,age)
类与对象
类:一个抽象的概念,即生活中的'类别'。
- 类中的所有变量称为属性
- 类中的所有函数通常称为方法
属性:将特征用程序描述。如姓名,年龄等。
方法:将动词用程序描述。如吃饭,走路等。
实例化:把类转变成实例化的过程。
对象:类的具体实例,归属于某个类别的个体。
如:猫(类),XX家的布偶猫(对象)
# 定义类:
# class 类名:
class Cat:
# 属性
name = '咪咪'
age = 5
# 方法:
def eat(self):
print('猫吃饭')
# 通过类实例化一个对象
cat1 = Cat() # 猫对象1,拥有类所有属性和功能
cat2 = Cat() # 猫对象2,拥有类所有属性和功能
print(cat1) # <__main__.Cat object at 0x000001DA6E5A6150>
print(cat1.name) # 咪咪
print(cat2.name) # 咪咪
cat1.eat() # 猫吃饭
cat2.eat() # 猫吃饭
在这里会发现,猫对象1和猫对象2内容完全一样,这就需要个性化了。
# 个性化
class Cat:
# 属性
type = '布偶猫'
# 初始化方法(内置方法)【在实例化执行的时候自动调用】
# 谁调用方法,self就只指向谁
def __init__(self,name,age):
self.name = name
self.age = age
# 方法
def set(self):
print('猫玩耍')
# 实例化
cat1 = Cat('夜白','3') # 猫对象1
print(cat1.name) # 夜白
cat2 = Cat('白夜','5') # 猫对象2
print(cat2.name) # 白夜
像这样,猫1和猫2都有他们各自的名字啦。
增删改查:
class Student:
# 类属性(公有属性)
school = 'YY'
grade = '大学二年级'
def learn(self):
print('is learning')
print(Student.__dict__) # 返回一个字典类型的数据
# 查
print(Student.school) # YY
# 增
Student.country = 'China'
print(Student.__dict__) # 字典中新增 'country': 'China' 数据
# 删
del Student.school
print(Student.school) # 会报错,显示没有school这个属性
# 改
Student.grade = '小学二年级'
print(Student.__dict__) # 字典中修改原grade为 'grade': '小学二年级'
class Student:
school = 'YY'
grade = '大学二年级'
# 初始化
def __init__(self,name,hobby):
self.name = name
self.hobby = hobby
def learn(self):
print('is learning')
# 实例化
stu1 = Student('ZZ','sleep')
stu2 = Student('CC','play')
print(stu1.name) # ZZ
stu1.name = '零奈'
print(stu1.name) # 零奈
stu1.hobby = stu2.hobby
print(stu1.hobby) # play
stu1.learn() # is learning (类中的属性是所有对象共有的)
Student.learn(stu1) # is learning # (类中的属性和方法是给对象使用的)
编写一个学生类,产生一堆学生对象 要求:有一个计数器(属性),统计总共实例化了多少个学生对象
class Student:
# 类属性
school = 'YY'
count = 0
# 初始化
def __init__(self,name,score):
self.name = name
self.score = score
Student.count += 1 # 这是类的count属性
print('第{}个学生:{},分数为:{}'.format(self.count,self.name,self.score))
# 类方法
def learn(self):
print('is learning')
stu1 = Student('一花',70)
stu2 = Student('二乃',68)
stu3 = Student('三玖',72)
stu4 = Student('四叶',59)
stu5 = Student('五月',71)
第1个学生:一花,分数为:70
第2个学生:二乃,分数为:68
第3个学生:三玖,分数为:72
第4个学生:四叶,分数为:59
第5个学生:五月,分数为:71
定义两个角色类 要求: 1.角色有阵地,武器,攻击力,生命值 2.实例化两个角色 3.角色之间相互打斗,被打的一方会掉血,血量小于0判断死亡
# 魈
class Xiao:
# 阵营
camp = '璃月' # 设置阵地
name = '魈'
# 初始化
def __init__(self,weapon,life_value,aggressivity):
self.weapon = weapon
self.life_value = life_value
self.aggressivity = aggressivity
def attack(self,enemy):
# 敌方的生命值=生命值-我方攻击力
enemy.life_value -= self.aggressivity
# 宵宫
class Yoimiya:
# 阵营
camp = '稻妻'
name = '宵宫'
# 初始化
def __init__(self,weapon,life_value,aggressivity):
self.weapon = weapon
self.life_value = life_value
self.aggressivity = aggressivity
def attack(self,enemy):
# 敌方的生命值=生命值-我方攻击力
enemy.life_value -= self.aggressivity
x1 = Xiao('和璞鸢',20000,2000)
y1 = Yoimiya('飞雷之弦振',17000,2200)
print('{},阵地{}\n\t使用武器:{},伤害{}'.format(x1.name,x1.camp,x1.weapon,x1.aggressivity))
print('{},阵地{}\n\t使用武器:{},伤害{}'.format(y1.name,y1.camp,y1.weapon,y1.aggressivity))
r = 0
while True:
r += 1
print('============第{}轮============='.format(r))
x1.attack(y1) # x1(魈)攻击y1(宵宫)
print('{}还剩{}血量'.format(y1.name,y1.life_value))
y1.attack(x1) # y1(宵宫)攻击x1(魈)
print('{}还剩{}血量'.format(x1.name,x1.life_value))
if x1.life_value <= 0:
print('{}的生命值已经低于0'.format(x1.name))
break
if y1.life_value <= 0:
print('<<<<<{}的生命值已经低于0'.format(y1.name))
break
魈,阵地璃月
使用武器:和璞鸢,伤害2000
宵宫,阵地稻妻
使用武器:飞雷之弦振,伤害2200
============第1轮=============
宵宫还剩15000血量
魈还剩17800血量
============第2轮=============
宵宫还剩13000血量
魈还剩15600血量
============第3轮=============
宵宫还剩11000血量
魈还剩13400血量
============第4轮=============
宵宫还剩9000血量
魈还剩11200血量
============第5轮=============
宵宫还剩7000血量
魈还剩9000血量
============第6轮=============
宵宫还剩5000血量
魈还剩6800血量
============第7轮=============
宵宫还剩3000血量
魈还剩4600血量
============第8轮=============
宵宫还剩1000血量
魈还剩2400血量
============第9轮=============
宵宫还剩-1000血量
魈还剩200血量
<<<<<宵宫的生命值已经低于0
面向对象:
封装,继承,多态
封装
- 第一层:在类的里部可以放属性和方法
- 第二层:在类中定义私有的属性和方法(只有类的内部可以使用的)
- 在python中用双下划线'__'开头的方式将属性和方法设置为私有
class A:
num = 100
__co = 5
def __fo(self):
print('ss')
def fo(self):
print(self.__fo()) # 在类的内部可以访问私有
a = A()
print(A.num) # 100
a.fo() # ss
封装的意义:
- 封装数据属性:明确区分内外,控制外部对隐藏属性的操作行为
-
class People: def __init__(self,name,age): self.__name = name # 将传进来的数据进行封装 self.__age = age def __str__(self): return "我叫{},年龄是{}".format(self.__name,self.__age) p1 = People("零奈",20) p1.__name = '五月' print(p1) # 我叫零奈,年龄是20
-
class People: def __init__(self,name,age): self.__name = name # 将传进来的数据进行封装 self.__age = age def __str__(self): return "我叫{},年龄是{}".format(self.__name,self.__age) # 操作姓名和年龄 def set_info(self,name,age): # 在这个间接操作中可以进行一些判断 if not isinstance(name,str): print('输入不合法,姓名必须是字符串') return if not isinstance(age,int): print('输入不合法,年龄必须是整型') return self.__name = name self.__age = age p1 = People("零奈",20) print(p1) # 我叫零奈,年龄是20 p1.set_info('五月',22) print(p1) # 我叫五月,年龄是22
-
封装方法:隔离复杂度
-
class ATM: def __card(self): pass def __input(self): pass def __get_money(self): pass def __save_money(self): pass def withdraw(self): self.__card() self.__input() self.__get_money() self.__save_money() # 实例化一个对象 a = ATM a.withdraw() # 对于使用者来说,类内部的流程隐藏了
继承:
解决类与类之间代码重用,冗长的问题。
在python中,新建的类可以继承一个或多个类。被继承的类叫做父类,可以称为基类或超类,新建的类叫做子类或派生类。
class Parent1: # 定义父类
pass
class Parent2:
pass
class Sub1(Parent1): # 子类单继承父类
pass
class Sub2(Parent1,Parent2): # 子类多继承父类
pass
print(Sub1.__bases__) # (<class '__main__.Parent1'>,) 查看父类
print(Sub2.__bases__) # (<class '__main__.Parent1'>, <class '__main__.Parent2'>)
class Dog(object): # 定义的类都是默认继承了object的,便可以使用内置方法,__init__这些。可以鼠标移到object上按住Ctrl键查看内置方法。
pass
举例:(上面对角色的大段描述也可以这样写)
class role:
# 初始化
def __init__(self,weapon,life_value,aggressivity):
self.weapon = weapon
self.life_value = life_value
self.aggressivity = aggressivity
def attack(self,enemy):
# 敌方的生命值=生命值-我方攻击力
enemy.life_value -= self.aggressivity
class Xiao(role):
# 阵营
camp = '璃月' # 设置阵地
name = '魈'
# 宵宫
class Yoimiya(role):
# 阵营
camp = '稻妻'
name = '宵宫'
x1 = Xiao('和璞鸢',20000,2000)
y1 = Yoimiya('飞雷之弦振',17000,2200)
派生:子类可以添加自己新的属性,但如果子类定义的新属性和父类重名,那么调用这个属性时以自己为准。
继承寻找属性遵循的原则
- 子类会先于父类被检查
- 多个父类会根据他们在MRO列表的顺序被检查
- 如果对下一个类存在两个合法的选择(父类里面有重名的)选择第一个父类
python3-->新式类-->遵循广度优先搜索
组合:在一个类中,以另外一个类的对象作为数据属性,称为类的组合。
例如:
# 枪类
# 属性:类型type 子弹数量count
# 方法:发射子弹shoot 填充子弹add
# 士兵类
# 属性:姓名name 枪gun
# 方法:开火fire
class Gun:
def __init__(self,type,count):
self.type = type
self.count = count
# 发射子弹
def shoot(self):
if self.count == 0:
print('没有子弹了')
else:
self.count -= 5
print('正在开火!嘭嘭 嘭!')
# 填充子弹
def add(self,number):
self.count += number
print('子弹填充完毕!')
class Soldier:
def __init__(self,name):
self.name = name
self.gun = None # 目前是没有枪的状态,后面实例化出来
def fire(self): # 拿枪射击
if self.gun == None:
print("很遗憾,你没有枪")
else:
self.gun.shoot()
# 实例化一把枪
M41 = Gun("M41",30)
# 实例化士兵
s1 = Soldier('XX')
# 给士兵一把枪
s1.gun = M41 # 组合
for i in range(10):
if M41.count == 0:
M41.add(30)
else:
s1.fire()
正在开火!嘭嘭 嘭!
正在开火!嘭嘭 嘭!
正在开火!嘭嘭 嘭!
正在开火!嘭嘭 嘭!
正在开火!嘭嘭 嘭!
正在开火!嘭嘭 嘭!
子弹填充完毕!
正在开火!嘭嘭 嘭!
正在开火!嘭嘭 嘭!
正在开火!嘭嘭 嘭!
多态和多态性
多态:指一类事物具有多种形态。如动物:猫、狗..,文件:文本文件、可执行文件
多态性:向不同的对象发送同一个指令,不同的对象在接收时会产生不同的行为(方法)
# 动物
class Animal:
def talk(self):
pass
class Cat:
def talk(self):
print('miao~')
class Dog:
def talk(self):
print('woof!')
多态性:一个接口,多实现。
多态性的好处:
- 增加了程序的灵活性
- 增加了程序的可扩展性