继承
在Python中,所有类默认继承object类,object类是顶级类或基类;其他子类叫做派生类
Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法
class A(object):
def __init__(self):
self.num = 1
pass
def info_print(self):
print(self.num)
class B(A):
pass
b = B()
b.info_print()
# 程序的开闭原则 开发扩展 关闭修改
Python支持多继承的语言
单继承
- 一个子类继承一个父类
故事主线:一个煎饼果子老师傅,在煎饼果子界摸爬滚打多年,研发了一套精湛的摊煎饼果子的技术。师父要把这套技术传授给他的唯一的最得意的徒弟。
# 师傅类
class Master(object):
def __init__(self):
self.kongfu = '[古法煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
# 徒弟类
class Prentice(Master):
pass
bowen = Prentice()
# 对象访问父类的实例属性
print(bowen.kongfu)
# 对象访问父类的实例方法
bowen.make_cake()
多继承
所谓多继承意思就是一个类同时继承了多个父类
故事推进:bowen是个爱学习的好孩子,想学习更多的煎饼果子技术, 于是了解到山东蓝翔教制作煎饼果子一绝
# 师傅类
class Master(object):
def __init__(self):
self.kongfu = '[古法煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
# 蓝翔类
class School(object):
def __init__(self):
self.kongfu = '[蓝翔煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
def wanjueji(self):
print("运用挖掘机制作煎饼果子")
# 徒弟类
class Prentice(Master, School):
pass
bowen = Prentice()
# 对象访问父类的实例属性
print(bowen.kongfu)
# 对象访问父类的实例方法
bowen.make_cake()
bowen.wanjueji()
当一个类有多个父类的时候,默认使用第一个父类的同名属性和方法
子类调用父类的同名方法和属性
# 师傅类
class Master(object):
def __init__(self):
self.kongfu = '[古法煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
# 蓝翔类
class School(object):
def __init__(self):
self.kongfu = '[蓝翔煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
def wajueji(self):
print("运用挖掘机制作煎饼果子")
# 徒弟类
class Prentice(Master, School):
def __init__(self):
self.kongfu = '[独创煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
bowen = Prentice()
# 对象访问父类的实例属性
print(bowen.kongfu)
# 对象访问父类的实例方法
bowen.make_cake()
bowen.wajueji()
当子类和父类用于同名方法和属性时, 我们调用的是子类的方法和属性
很多顾客都希望也能吃到古法的和蓝翔的
# 师傅类
class Master(object):
def __init__(self):
self.kongfu = '[古法煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
# 蓝翔类
class School(object):
def __init__(self):
self.kongfu = '[蓝翔煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
def wajueji(self):
print("运用挖掘机制作煎饼果子")
# 徒弟类
class Prentice(Master, School):
def __init__(self):
self.kongfu = '[独创煎饼果子配方]'
def make_cake(self):
# 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
self.__init__()
print("运用{}制作煎饼果子".format(self.kongfu))
# 调用父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
bowen = Prentice()
bowen.make_cake()
# 对象访问父类的实例属性
# print(bowen.kongfu)
# # 对象访问父类的实例方法
# bowen.make_cake()
# bowen.wajueji()
多层继承
故事:N年后,bowen老了,想要把所有技术传承给自己的徒弟
# 师傅类
class Master(object):
def __init__(self):
self.kongfu = '[古法煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
# 蓝翔类
class School(object):
def __init__(self):
self.kongfu = '[蓝翔煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
def wajueji(self):
print("运用挖掘机制作煎饼果子")
# 徒弟类
class Prentice(Master, School):
def __init__(self):
self.kongfu = '[独创煎饼果子配方]'
def make_cake(self):
# 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
self.__init__()
print("运用{}制作煎饼果子".format(self.kongfu))
# 调用父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
class Tusun(Prentice):
pass
t = Tusun()
t.make_cake()
t.make_school_cake()
t.make_master_cake()
super()调用父类方法
# 师傅类
class Master(object):
def __init__(self):
self.kongfu = '[古法煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
# 蓝翔类
class School(Master):
def __init__(self):
self.kongfu = '[蓝翔煎饼果子配方]'
def make_cake(self):
print("运用{}制作煎饼果子".format(self.kongfu))
# Master.__init__()
# 方式1
# super(School, self).__init__()
# super(School, self).make_cake()
# # 方式2
super().__init__()
super().make_cake()
s = School()
s.make_cake()
使用super() 可以自动查找父类
私有权限
在Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或实例方法不继承给子类。
故事:bowen把技术传承给徒弟的同时,不想把自己的钱(2000000个亿)继承给徒弟,这个时候就要为钱这个实例属性设置私有权限
设置私有权限的方法:在属性名和方法名 前面 加上两个下划线 __
私有属性和私有方法只能在类里面访问和修改
# 徒弟类
class Prentice(object):
def __init__(self):
self.kongfu = '[独创煎饼果子配方]'
self.__money = 2000000
def make_cake(self):
# 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
self.__init__()
print("运用{}制作煎饼果子".format(self.kongfu))
class Tusun(Prentice):
pass
t = Tusun()
print(t.kongfu)
print(t.__money)
获取和修改私有属性值
在Python中,一般定义函数名get_xx用来获取私有属性,定义set_xx用来修改私有属性值
# 徒弟类
class Prentice(object):
def __init__(self):
self.kongfu = '[独创煎饼果子配方]'
self.__money = 2000000
def make_cake(self):
# 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
self.__init__()
print("运用{}制作煎饼果子".format(self.kongfu))
def get_money(self):
return self.__money
def set_money(self, money):
self.__money = money
class Tusun(Prentice):
pass
t = Tusun()
print(t.kongfu)
t.set_money(20)
print(t.get_money())
- 继承的特点
- 子类默认拥有父类的所有属性和方法
- 子类重写父类同名方法和属性
- 子类调用父类同名方法和属性
- super()方法快速调用父类方法
- 私有权限
- 不能继承给子类的属性和方法需要添加私有权限
面向对象
面向对象三大特性
- 封装
- 将属性和方法书写到类的里面的操作即为封装
- 封装可以为属性和方法添加私有权限
- 继承
- 子类默认继承父类的所有属性和方法
- 子类可以重写父类属性和方法
- 多态
- 传入不同的对象,产生不同的结果
了解多态
多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承)。
- 定义:多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果
- 好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化!
- 实现步骤:
- 定义父类,并提供公共方法
- 定义子类,并重写父类方法
- 传递子类对象给调用者,可以看到不同子类执行效果不同
class Dog(object):
def work(self):
print("指哪咬哪")
class ArmyDog(Dog):
def work(self):
print("追击敌人....")
class DrugDog(Dog):
def work(self):
print("追查毒品....")
class Person(object):
def work_with_dog(self, dog):
dog.work()
ad = ArmyDog()
dd = DrugDog()
p = Person()
p.work_with_dog(ad)
p.work_with_dog(dd)
类属性和实例属性
类属性 :-类属性就是 类对象 所拥有的属性,它被 该类的所有实例对象 所共有。
-类属性可以使用 类对象 或 实例对象 访问
class Dog(object):
tooth = 10
wangcai = Dog()
print(wangcai.tooth) #一般不这么调用类属性
print(Dog.tooth) #一般不这么调用类属性
- 记录的某项数据 始终保持一致时,则定义类属性。
- 实例属性 要求 每个对象 为其 单独开辟一份内存空间 来记录数据,而 类属性 为全类所共有 ,仅占用一份内存,更加节省内存空