1.单继承
知识点:
单继承: 一个类继承一个父类
1. 单继承格式
calss 子类名(父类名):
pass
2.注意: 一个父类可以有多个子类
示例:
# 1.定义父类
class Person():
def study(self):
print('学习...')
# 2.定义子类去继承父类
class Student(Person):
pass
class Teacher(Person):
pass
# 3.测试子类是否继承了父类的功能
stu = Student()
stu.study()
tea = Teacher()
tea.study()
2.多继承
知识点:
多继承: 一个类可以继承多个父类
1. 多继承格式:
class 子类名(父类名1,父类名2...):
pass
2. 当继承的父类中出现同名属性或方法时: 子类如果继承了多个父类,默认使用第一个父类的同名属性和方法
3. 就近原则:一个属性或方法,首先在本类中找,找不到就去第一个父类找,然后第二个,依次类推,还没有,则去第一个祖宗类中找,依次类推....
示例:
# 需求: 有一个师父类,属性是煎饼果子配方,方法制作煎饼果子,徒弟想填饱肚子所以去学了煎饼果子...
# 上进,来黑马学python大数据...
# 1.1先定义一个父类
class Master():
def __init__(self):
self.secret = '秘制煎饼果子配方'
def make(self):
print(f'使用 "{self.secret}" 制作煎饼果子,填饱肚子')
# 1.2再定义一个父类
class School():
def __init__(self):
self.secret = '黑马最新python大数据技术'
def make(self):
print(f'使用 "{self.secret}" 高薪就业')
# 2.定义子类继承多个父类
class Prentice(School,Master):
pass
# 3.测试徒弟类是否拥有父类的属性和方法
td = Prentice()
td.make()
4.重写
知识点:
重写:子类重写父类的同名属性或方法
为什么重写: 当父类的功能不满足子类需求时候,子类需要自己重写去拓展功能
重写后注意: 当子类去调用同名属性和方法时候,默认调用的是子类自己重写后的属性和方法
示例:
# 需求: 徒弟想填饱肚子所以去学了煎饼果子...有一个师父类,属性是煎饼果子配方,方法制作煎饼果子
# 想上进,进入互联网行业选择来黑马学python大数据..
# 已经高薪就业,自己独创一门新的开发语言,实现财富自由走上人生巅峰
# 1.1先定义一个父类
class Master():
def __init__(self):
self.secret = '秘制煎饼果子配方'
def make(self):
print(f'使用 "{self.secret}" 制作煎饼果子,填饱肚子')
# 1.2再定义一个父类
class School():
def __init__(self):
self.secret = '黑马最新python大数据技术'
def make(self):
print(f'使用 "{self.secret}" 高薪就业')
# 2.定义子类继承多个父类,父类功能不能满足子类需求,子类去重写
class Prentice(School, Master):
# 如果子类重写了父类的同名属性和方法,默认使用子类自己的同名属性和方法
def __init__(self):
self.secret = '独创开发语言'
def make(self):
print(f'使用 "{self.secret}" 实现财富自由,走上人生巅峰')
# 3.测试徒弟类调用的是哪个父类的属性和方法
td = Prentice()
td.make()
5.子类调用父类同名属性和方法
知识点:
方式1: 使用父类名直接调用 格式: 父类名.父类方法名(self) #需要传self,父类有很多子类,要告诉它你是谁
方式2: python3.x版本super 格式: super().父类方法名() #3.0以后,参数全部省了,不用自己写
方式3: python3.x版本之前 格式: super(当前类名,self).父类方法名()
super的缺点就是,有同名方法或属性时只能调用第一个父类的方法,不过好处是,父类名称改了,也不用修改代码
示例:
# 需求: 徒弟想填饱肚子所以去学了煎饼果子...有一个师父类,属性是煎饼果子配方,方法制作煎饼果子
# 想上进,进入互联网行业选择来黑马学python大数据..
# 已经高薪就业,自己独创一门新的开发语言,实现财富自由走上人生巅峰
# 又想体验下原来的生活...
# 1.1先定义一个父类
class Master():
def __init__(self):
self.secret = '秘制煎饼果子配方'
def make(self):
print(f'使用 "{self.secret}" 制作煎饼果子,填饱肚子')
# 1.2再定义一个父类
class School():
def __init__(self):
self.secret = '黑马最新python大数据技术'
def make(self):
print(f'使用 "{self.secret}" 高薪就业')
# 2.定义子类继承多个父类,父类功能不能满足子类需求,子类去重写
class Prentice(School,Master):
# 如果子类重写了父类的同名属性和方法,默认使用子类自己的同名属性和方法
def __init__(self):
self.secret = '独创开发语言'
def make(self):
print(f'使用 "{self.secret}" 实现财富自由,走上人生巅峰')
# 调用父类的同名属性和方法
# 方式1: 父类名.父类方法名(self)
School.__init__(self)
School.make(self)
Master.__init__(self)
Master.make(self)
print('-'*30)
# 方式2: python3.x版本: super().父类方法名()
super().__init__()
super().make()
print('-' * 30)
# 方式3: python3.x版本之前: super(当前类名,self).父类方法名()
super(Prentice,self).__init__()
super(Prentice,self).make()
# 3.测试徒弟类调用的是哪个父类的属性和方法
td = Prentice()
td.make()
6.多层继承
知识点:
多层继承: 是一种关系 举例: 父子孙多代关系
就是这样,没什么东西
示例:
# 需求: 徒弟想填饱肚子所以去学了煎饼果子...有一个师父类,属性是煎饼果子配方,方法制作煎饼果子
# 想上进,进入互联网行业选择来黑马学python大数据..
# 已经高薪就业,自己独创一门新的开发语言,实现财富自由走上人生巅峰
# 又想体验下原来的生活...
# 有了自己的儿子,儿子继承了他所有一切...
# 1.1先定义一个父类
class Master():
def __init__(self):
self.secret = '秘制煎饼果子配方'
def make(self):
print(f'使用 "{self.secret}" 制作煎饼果子,填饱肚子')
# 1.2再定义一个父类
class School():
def __init__(self):
self.secret = '黑马最新python大数据技术'
def make(self):
print(f'使用 "{self.secret}" 高薪就业')
# 2.定义徒弟类继承多个父类,父类功能不能满足子类需求,子类去重写
class Prentice(School,Master):
# 如果子类重写了父类的同名属性和方法,默认使用子类自己的同名属性和方法
def __init__(self):
self.secret = '独创开发语言'
def make(self):
print(f'使用 "{self.secret}" 实现财富自由,走上人生巅峰')
# 调用父类的同名属性和方法
# 方式1: 父类名.父类方法名(self)
School.__init__(self)
School.make(self)
Master.__init__(self)
Master.make(self)
print('-'*30)
# 方式2: python3.x版本: super().父类方法名()
super().__init__()
super().make()
print('-' * 30)
# 方式3: python3.x版本之前: super(当前类名,self).父类方法名()
super(Prentice,self).__init__()
super(Prentice,self).make()
# 3.定义儿子类继承徒弟类
class Son(Prentice):
pass
# 测试儿子类是否拥有了徒弟类的一切
s = Son()
s.make()
7.mro方法解析顺序
知识点:
mro: method resolve order 方法解析顺序
它有一个属性和方法,功能一样,具体如下:
1. 属性: __mro__
2. 方法: mro()
它打印出方法的解析顺序
示例:
# 需求: 徒弟想填饱肚子所以去学了煎饼果子...有一个师父类,属性是煎饼果子配方,方法制作煎饼果子
# 想上进,进入互联网行业选择来黑马学python大数据..
# 已经高薪就业,自己独创一门新的开发语言,实现财富自由走上人生巅峰
# 又想体验下原来的生活...
# 有了自己的儿子,儿子继承了他所有一切...
# 1.1先定义一个父类
class Master(object):
def __init__(self):
self.secret = '秘制煎饼果子配方'
def make(self):
print(f'使用 "{self.secret}" 制作煎饼果子,填饱肚子')
def show(self):
print('Master中的show方法...')
# 1.2再定义一个父类
class School():
def __init__(self):
self.secret = '黑马最新python大数据技术'
def make(self):
print(f'使用 "{self.secret}" 高薪就业')
# 2.定义徒弟类继承多个父类,父类功能不能满足子类需求,子类去重写
class Prentice(School,Master):
pass
# 3.定义儿子类继承徒弟类
class Son(Prentice):
pass
# 测试儿子类是否拥有了徒弟类的一切
s = Son()
s.show() # 就近原则:Son->Prentice->School->Master->object
# (<class '__main__.Son'>, <class '__main__.Prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)
print(Son.__mro__)
# [<class '__main__.Son'>, <class '__main__.Prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>]
print(Son.mro())
8.私有权限
知识点:
直接加两个下划线即可:
私有属性: _ _属性名
私有方法: _ _方法名()
私有权限特点: 不能被外界直接访问, 不能被继承!!!
一般定义公共的接口(方法)间接访问
示例:
# 1.先定义一个师父类
class Master():
def __init__(self):
self.name = '大师'
# 私有属性
self.__money = 1000
# 公共方法:用于获取私有属性money
def get_money(self):
print(f'您当前余额为:{self.__money}')
# 公共方法: 用于修改私有属性money
def set_money(self,money):
self.__money += money
# 私有方法:大师买了个私人别墅
def __house(self):
print('大师的私人别墅...')
# 公共方法: 用于间接调用私有方法
def show(self):
self.__house()
# 2.再创建对象
m = Master()
# 3.访问私有属性
# print(m.__money) # 报错,私有属性外界不能直接访问
# 间接通过公共的方法访问私有属性
m.set_money(2000) # 存钱
m.get_money() # 查看
# 4.访问私有方法
# m.__house() # 报错,私有方法外界不能直接访问
# 间接通过公共的方法访问私有方法
m.show()
9.实例属性和类属性
知识点:
1. 实例属性: 就是对象的属性(存在于对象的内存空间中)
获取方式 : 对象(self).实例属性
修改方式 : 对象(self).实例属性 = 值
2. 类属性: 类属性在类的内存空间中,类以及所有对象都能调用
获取方式 : 1. 对象(self).类属性 2. 类名.类属性
修改1种方式 : 类名.类属性 = 值
3. 注意:对象无法修改类属性,如果你想要:对象.类属性名 = 值;它相当于对象在自己的内存空间中添加了一个和类属性同名的属性
示例:
# 先有类
class Dog():
# 定义类属性,只开辟一块空间,所有对象共有
tooth = 10
def __init__(self, name, age):
# 实例属性:每个对象都开辟一个空间
self.name = name
self.age = age
# 根据类创建对象
eh = Dog('二哈', 5)
print(eh.tooth) # 对象访问类属性 10
jm = Dog('金毛', 6)
print(jm.tooth) # 对象访问类属性 10
# 类属性多了一种访问访问方式: 类名.类属性
# print(Dog.name) # 实例属性需要通过对象调用
print(Dog.tooth) # 类属性既可以通过对象调用,也可以通过类名调用 10
print('------------------------------------------------------')
# 正确的修改类属性方式: 类名.类属性 = 值
Dog.tooth = 12
print(eh.tooth) # 对象访问类属性 12
print(jm.tooth) # 对象访问类属性 12
print(Dog.tooth) # 类属性既可以通过对象调用,也可以通过类名调用 12
print('------------------------------------------------------')
# 修改类属性错误方式: 不报错,只是给对象自己添加了一个属性(和类属性同名而已)
eh.tooth = 15
print(eh.tooth) # 对象访问类属性 15
print(jm.tooth) # 对象访问类属性 12
print(Dog.tooth) # 类属性既可以通过对象调用,也可以通过类名调用 12
10.实例方法和类方法和静态方法
知识点:
1. 实例方法: 对象的普通方法
实例方法形参: 第一个位置是实例对象地址self
实例方法调用: 需要通过对象调用
2. 类方法: 使用装饰器@classmethod修饰的方法
类方法形参: 第一个位置是类对象地址cls
类方法调用: 可以通过对象调用 , 也可以通过类名直接调用
3. 静态方法: 使用装饰器@staticmethod修饰的方法
静态方法形参: 不需要传递self和cls
静态方法调用: 可以通过对象调用 , 也可以通过类名直接调用
静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用.
另外,“静态方法”和在模块中定义普通函数没有区别,只不过“静态方法”放到了“类的名字空间里面”,需要通过“类调用”。简单的说,静态方法就是把普通函数放到了类里面.
示例:
# 先定义一个类
class Dog():
__tooth = 10
# 实例方法 : 形参第一个位置是实例对象自己:self
def get_tooth1(self):
return Dog.__tooth
# 类方法 : 形参第一个位置是类对象: cls
@classmethod
def get_tooth2(cls):
return Dog.__tooth
# 静态方法: 形参没有self和cls
@staticmethod
def get_tooth3():
return Dog.__tooth
# 1.通过实例方法访问类属性
d = Dog()
# 对象.实例方法
print(d.get_tooth1())
print('-------------------------------')
# 2.通过类方法访问类属性
# 方式1: 对象.类方法
print(d.get_tooth2())
# 方式2: 类名.类方法
print(Dog.get_tooth2())
print('-------------------------------')
# 3.通过静态方法访问类属性
# 方式1: 对象.类方法
print(d.get_tooth3())
# 方式2: 类名.类方法
print(Dog.get_tooth3())
总结
知识点
- 类 : 对具有相同属性和方法的集合 ,是一种概念
- 类对象 : 给类开辟的空间就是类对象
- 类对象空间中存放的是 公共数据,也就是类属性和类方法
- 类和对象都可以使用这些数据
- 实例对象: 存放对应的实例对象的独有数据
- 类属性(cls)
- 存放在类对象空间里的属性
- 公共属性
- 实例属性(self)
- 存放在实例对象空间里属性
- 独有属性
- 类方法 @classmethod
- 用来修改类属性的方法
- 公共方法,存放与类空间中,类对象和实例对象都能调用
- 实例方法 (self) (也就是普通方法)
- 修改实例属性的方法
- 实例独有的方法
- 静态方法 @staticmethod
- 它不需要传self和cls参数
- 不管是类还是实例对象都可以使用他
- 简单的说,静态方法就是把普通函数放到了类里面