一、类和对象
➢ 类 是对一群具有相同特征或者行为的事物的一个统称,
➢ 对象 是由类创建出来的一个具体 实例,可以直接使用
➢ 类 只有一个,而 对象 可以有很多个
➢ 不同的对象 之间 属性 可能会各不相同
➢ 类 中定义了什么 属性和方法,对象 中就有什么属性和方法
1、python自己提供的常见的内置属性和类方法
方法名 | 作用 |
---|---|
__new __ | 创建对象的时候, 会被自动调用, 给对象分配内存地址和空间 |
__init __ | 对象被初始化时, 会被自动调用 |
__del __ | 对象被从内存中销毁前, 会被自动调用 |
__str __ | 返回对象的描述信息, print函数输出使用 |
2、
➢ 方法
定义格式和之前的函数几乎相同, 唯一的区别是, 对象的方法第一个参数必须是 self
➢ Self 代表什么含义呢?
➢ 哪个对象调用的方法,self就是哪一个对象的引用
➢ 类名命名:大驼峰
- 举个栗子(๑╹ヮ╹๑)ノ
➢ 定义一个人的类,每个人都有姓名,年龄,身高等属性,每个人都会跑,会吃等
class Person:#类名用大驼峰命名,大写
def __init__(self, name, age, height):#属性
self.name = name
self.age = age
self.height = height
def eat(self):#方法
print('%s很能吃' % self.name)
def run(self):#方法
print('%s去跑步' % self.name)
return 23333
def __str__(self):
return self.name
def __del__(self):
print('对象正在删除')
#语法规范:方法之间空1个行
lei = Person('lilei',18,175.5)
print(Person)#类名地址
print(lilei)
print(lilei.run())
# del lilei
lilei.weight = 90 #给实例对象添加属性
print(lilei.weight)
- 再举个栗子(๑╹ヮ╹๑)ノ
➢ 知识点: 一个对象的属性可以是 另外一个类创建的对象
class Piggy:
"""
这是一个存钱罐类
存钱罐类有两个方法: “吃钱”, “吐钱”
存钱罐类要有两个属性:型号, 容量
"""
def __init__(self, cate, total_money):
self.cate = cate
self.money = total_money
self.remain_money = total_money
def eat_money(self, money):
"""吃钱"""
if money > self.remain_money:
print("待放入的钱已经超过容量, 容量剩余{}".format(self.remain_money))
return
else:
# self.remain_money = self.remain_money - money
self.remain_money -= money
print("本次存入%s, 还剩余容量: %s" % (money, self.remain_money))
def out_money(self):
"""吐钱, 每次出1万"""
if self.money - self.remain_money < 1:
print("余额{}不足, 请充值".format(self.money - self.remain_money))
else:
self.remain_money += 1
print("还剩余钱数: %s" % (self.money - self.remain_money))
class Person:
"""人类"""
def __init__(self, name,piggy=None):
self.name = name
self.piggy = piggy
def spend_money(self):
"""花钱"""
# 重点:花钱之前需要判断是否有实例化的存钱罐
if self.piggy is None:
print("%s 还没有放私房钱的地方" % self.name)
return
else:
self.piggy.out_money()
piggy = Piggy("小猪佩奇", 20)
person = Person("周老师")
person.spend_money()
person.piggy = piggy
piggy.eat_money(2)
person.spend_money()
piggy.eat_money(200)
#说实话这个栗子有点懵QAQ
3、私有属性和私有方法
class Women:
def __init__(self, name):
self.name = name
self.__age = 18
def __secret(self):
print('我的年龄是 %s'%self.__age)
xiaofang = Women('小芳')
# print(xiaofang.__age)#私有属性,外部不能直接访问
#xiaofang.__secret()#私有方法,外部不可直接调用。删掉两个下划线就可以使用了嗷
'''或者这个亚子↓前边加 _类名 '''
print(xiaofang._Women__age)
xiaofang._Women__secret()
二、继承和多态
< 一 >、继承
1、单继承和多继承
- 举个超级大的
例子煎饼 (๑╹ヮ╹๑)ノ
class Master():
def __init__(self):
self.kongfu = '古法煎饼果子健'
def make_cake(self):
print('按照<%s>制作了一份煎饼果子健'%self.kongfu)
def dayandai(self):
print('师父的大烟袋。。')
class School():
def __init__(self):
self.kongfu = '现代煎饼果子健配方'
def make_cake(self):
print('[现代]按照<%s>制作了一份煎饼果子健'%self.kongfu)
def xiaoyandai(self):
print('学校的小烟袋。。')
class Prentice(Master,School):#多继承,括号里有俩
pass
damao = Prentice()
print(damao.kongfu)#执行master的属性
damao.make_cake()#执行master的实例方法
#子类的魔法属性__mro__决定了属性和方法的查找顺序
print(Prentice.__mro__)
damao.dayandai()#不重名不影响
damao.xiaoyandai()
'''---看这里!↓敲黑板划重点!(图单另放一张)---'''
School.make_cake(damao)
#重名,可以强制指定执行某一个父类的方法,需要我们自己为self赋值
↑为啥前边【现代】后边却是【古法】咧?
(新机子哇茂一豆子)
看这里!↓
2、修改私有属性的值
3、子类重写父类同名属性和方法
class Master():
def __init__(self):
self.kongfu = '古法煎饼果子健'
def make_cake(self):
print('按照<%s>制作了一份煎饼果子健'%self.kongfu)
class Prentice(Master):
def __init__(self):
self.kongfu = '猫氏煎饼果子配方'
def make_cake(self):
print('[猫氏]按照<%s>制作了一份煎饼果子...'%self.kongfu)
#如果子类和父类的方法名和属性名相同,则默认使用子类的
#叫 子类重写父类的同名方法和属性
damao = Prentice()
print(damao.kongfu)#子类和父类有同名属性,则默认使用子类的
damao.make_cake()#子类和父类有同名方法,则默认使用子类的
#子类的魔法属性__mro__决定了属性和方法的查找顺序
print(Prentice.__mro__)
4、子类调用父类同名属性和方法
class Master():
def __init__(self):
self.kongfu = '古法煎饼果子健'
def make_cake(self):
print('[古法]按照<%s>制作了一份煎饼果子健'%self.kongfu)
class Prentice(Master):
def __init__(self):
self.kongfu = '猫氏煎饼果子配方'
def make_cake(self):
self.__init__()
print('[猫氏]按照<%s>制作了一份煎饼果子...'%self.kongfu)
#调用父类方法格式:父类类名.父类方法(self)
def make_old_cake(self):
Master.__init__(self)#调用父类Master的__init__方法,self.kongfu = '古法...'
Master.make_cake(self)#调用父类Master的实例方法
#实例化对象,自动执行子类的__init__方法
damao = Prentice()
damao.make_cake()#调用子类的方法(默认重写了父类的同名方法)
print('--'*10)
damao.make_old_cake()#进入实例方法去调用父类master的方法
5、多层继承
6、通过super()来调用父类方法
class Master():
def __init__(self):
self.kongfu = '古法煎饼果子健'
def make_cake(self):
print('[古法]按照<%s>制作了一份煎饼果子健' % self.kongfu)
class Prentice(Master):
def __init__(self):
self.kongfu = '猫氏煎饼果子配方'
def make_cake(self):
self.__init__()
print('[猫氏]按照<%s>制作了一份煎饼果子...'%self.kongfu)
def make_old_cake(self):
#1、指定执行父类的方法
# Master.__init__(self)#调用父类Master的__init__方法,self.kongfu = '古法...'
# Master.make_cake(self)#调用父类Master的实例方法
#2、super()带参数
# super(Prentice,self).__init__()#执行父类的__init__方法
# super(Prentice,self).make_cake()
#3、super()的简化版,只支持新式类
super().__init__()#执行父类的__init__方法
super().make_cake()#执行父类的实例方法
damao = Prentice()
damao.make_cake()
damao.make_old_cake()
< 二 >多态
- 对象方法
- 类方法
- 静态方法
装饰器
应用
class Dog(object):
def work(self): #父类提供统一的方法,哪怕是空方法
pass
class ArmyDog(Dog):#继承Dog
def work(self): #子类重写方法,并且处理自己的行为
print('追击敌人')
class DrugDog(Dog):
def work(self):
print('追查毒品')
class Person(object):
def work_with_dog(self, dog):
dog.work() #使用小狗可以根据对象的不同而产生不同的运行效果
#子类对象可以当做父类来使用
dog = Dog()
print(isinstance(dog, Dog)) # isinstance可以判断dog是否是Dog类的对象
ad = ArmyDog()
print(isinstance(ad, Dog))
dd = DrugDog()
print(isinstance(dd, Dog))
p = Person()
p.work_with_dog(dog)
p.work_with_dog(ad) #同一个方法,只要是Dog的子类就可以传递,提供了代码的灵活性
p.work_with_dog(dd) # 并且传递不同对象,最终 work_with_dog产生了不同的执行效果