本文已参与「新人创作礼」活动,一起开启掘金创作之路。
@[toc]
1. 继承的基本语法[掌握]
- 继承: 描述的类与类之间所属关系.
- 基本语法:
class 类B(类A):
pass
- 称为类 B 继承类 A
- 特点: B类的对象可以使用 A类的属性和方法
- 优点: 代码复用.重复相同的代码不用多次书写.
- 名词:
- 类A: 父类 基类
- 类B: 子类 派生类
# 1. 定义是个 动物类 animal类
class Animal(object):
# 2. 在animal类书写 play方法,输出二哈在拆家....
def play(self):
print('二哈在拆家....')
# 3. 定义Dog类继承animal类,
class Dog(Animal):
pass
# 4. 创建dog类对象.调用父类的方法
dog = Dog()
dog.play()
2. 单继承和多层继承[理解]
- 单继承: 如果一个类只有一个父类,把这种继承关系称为单继承
- 多继承: 如果一个类有多个父类,把这种继承关系称为多继承
- 多层继承: C--> B --> A
# 1. 定义是个 动物类 animal类
class Animal(object): # 对于Animal类和object类来说,单继承
# 2. 在animal类书写 play方法,输出二哈在快乐的拆家....
def play(self):
print('二哈在快乐的拆家....')
# 3. 定义Dog类继承animal类,
class Dog(Animal): # Dog --> Animal 也是单继承, Dog --> Animal --> object 这种继承关系称为多层继承
def bark(self):
print('萨摩耶在睡觉.......')
# 定义类 XTQ类, 继承 Dog类
# 多层继承中,子类可以使用所有继承链中的类中的方法和属性
class XTQ(Dog): # XTQ --> Dog 单继承, XTQ --> Dog --> Animal 类, 多层继承
pass
xtq = XTQ()
xtq.bark() # 调用父类Dog中的方法
xtq.play() # 调用爷爷类 animal类中的方法
3. 子类重写父类的同名方法[掌握]
- 重写: 子类定义和父类名字相同的方法.
- 为什么重写: 父类中的方法,不能满足子类对象的需求,所以要重写.
- 重写之后的特点: 子类对象调用子类自己的方法,不再调用的方法,父类对象调用父类自己的方法.
# 1. 定义Dog类, 书写bark方法, 输出 萨摩耶在睡觉
class Dog(object):
def bark(self):
print('萨摩耶在睡觉.........')
# 2. 定义XTQ类,继承Dog类. 重写父类中的bark方法, 输出 萨摩耶在洗澡
class XTQ(Dog):
def bark(self):
print('萨摩耶在洗澡--------')
# 创建Dog类对象
dog = Dog()
dog.bark() # 父类自己的
# 创建XTQ类对象
xtq = XTQ()
xtq.bark()
4. 子类调用父类的同名方法[掌握]
# 1. 定义Dog类, 书写bark方法, 输出 萨摩耶在睡觉
class Dog(object):
def bark(self):
print('萨摩耶不理主人.........')
# 2. 定义XTQ类,继承Dog类. 重写父类中的bark方法, 输出 萨摩耶在洗澡
class XTQ(Dog):
def bark(self):
print('萨摩耶跑过来了--------')
def see_host(self):
"""看见主人之后,要跑过来,不能不理主人"""
print('看见主人了,', end='')
# self.bark()
# 想要在子类中调用父类的同名方法
# 方法一: 父类名.方法名(self, 其他参数), 通过实例对象.方法名() 调用方法,不需要给self传递实参值,
# python解释器会自动将对象作为实参值传递给self形参, 如果是通过类名.方法() 调用,python解释器就不会自动传递实参值,需要手动给self形参传递实参值
Dog.bark(self)
# 方法二 super(类A, self).方法名(参数) , 会调用当类A 的父类中的方法
super(XTQ, self).bark() # 调用 XTQ类父类中的bark方法
# 方法三 是方法二的简写, super().方法名(参数) ==> super(当前类, self).方法名()
super().bark()
# 创建XTQ类对象
xtq = XTQ()
xtq.see_host()
5. 继承中的 init [掌握]
# 1. 定义Dog类
class Dog(object):
def __init__(self, name):
# 添加属性
self.age = 0
self.name = name
def __str__(self):
return f'名字为:{self.name}, 年龄为{self.age}'
# 2. 定义XTQ类继承Dog类
class XTQ(Dog):
# 子类重写了父类的__init__ 方法,默认不再调用父类的init方法, 需要手动的调用父类的init方法
def __init__(self, name, color):
super().__init__(name)
self.color = color
def __str__(self):
return f'名字为:{self.name}, 年龄为{self.age}, 毛色为:{self.color}'
# 3. 创建XTQ类对象
xtq = XTQ('萨摩耶', '纯白色')
print(xtq)
6. 多继承[理解]
- 如果一个类有两个及以上的父类,就把这种继承关系称为多继承.
# 1. 定义Dog类, 定义doing方法,和 eat方法
class Dog(object):
def doing(self):
print('萨摩耶在睡觉.....')
def eat(self):
print('吃狗粮.....')
# 2. 定义God类, 定义 play方法和eat方法
class God(object):
def play(self):
print('萨摩耶在洗澡....')
def eat(self):
print('吃烤串不加料....')
# 3. 定义XTQ类, 继承Dog类和God类
# class XTQ(Dog, God): # XTQ 类有两个父类,这个继承关系称为多继承,XTQ类对象,可以调用两个父类中的属性和方法
class XTQ(God, Dog): # XTQ 类有两个父类,这个继承关系称为多继承,XTQ类对象,可以调用两个父类中的属性和方法
pass
# 4. 创建XTQ类对象
xtq = XTQ()
xtq.doing() # 调用 Dog父类中的方法
xtq.doing() # 调用 God父类中的方法
xtq.eat() # 两个父类都存在eat方法,子类对象调用的是 第一个父类中的方法
6.1 多继承调用指定父类中的方法
# 1. 定义Dog类, 定义doing方法,和 eat方法
class Dog(object):
def doing(self):
print('萨摩耶在睡觉.....')
def eat(self):
print('吃狗粮.....')
# 2. 定义God类, 定义 play方法和eat方法
class God(object):
def play(self):
print('萨摩耶在洗澡....')
def eat(self):
print('吃烤串不加料....')
# 3. 定义XTQ类, 继承Dog类和God类
# class XTQ(Dog, God): # XTQ 类有两个父类,这个继承关系称为多继承,XTQ类对象,可以调用两个父类中的属性和方法
class XTQ(God, Dog): # XTQ 类有两个父类,这个继承关系称为多继承,XTQ类对象,可以调用两个父类中的属性和方法
def eat(self):
print('子类重写eat方法,调用子类自己的方法')
# 调用指定父类中的方法
# 方法一 类名.方法名(self, 参数)
# Dog.eat(self)
# God.eat(self)
# 方法二 super(类A, self).方法名(参数) 类A的父类(继承顺序链的下一个类)中的方法
# super(XTQ, self).eat() # God 类中的方法
super(God, self).eat() # 调用的Dog类中的方法
# super(Dog, self).eat() # 调用的object类中的方法,注意: object类中没有eat方法,代码报错
# 4. 创建XTQ类对象
xtq = XTQ()
xtq.doing() # 调用 Dog父类中的方法
xtq.play() # 调用 God父类中的方法
xtq.eat() # 两个父类都存在eat方法,子类对象调用的是 第一个父类中的方法
# 类名.__mro__ 可以当前类的继承顺序链,也叫做方法的调用顺序
# print(XTQ.__mro__)
6.2 类名.__mro__方法
代码是6.1的代码,把最后一行解注释
类名.mro 可以当前类的继承顺序链,也叫做方法的调用顺序
7. 私有权限[理解]
- 访问权限控制: 在什么地方可以使用和操作.
- 私有权限:
定义: 在方法和属性前加上两个下划线, 就变为私有.
- 不能在类外部通过对象直接访问和使用, 只能在类内部访问和使用
- 不能被子类继承
- 公有: 不是私有的,就是公有的.
7.1私有属性
- 私有属性,只需要在原属性名前加上两个下划线,即可
- 目的: 保证数据的相对安全,
- 想要访问和使用私有属性: 定义一个公有的方法,通过这个方法使用
7.1.1__dict__方法
通过__dict__方法找出来私有属性被重新命名的名字,然后再修改私有属性的值,这种方法可以修改私有属性的值,但是不推荐这样写,不安全,可以用7.2的方法来写
# 案例需求: 定义People 类, 定义属性 ICBC_money , 钱不能随便被修改,必须是合法的终端才可以操作
class People(object):
def __init__(self):
# python中的私有本质是 修改属性的名字, 在创建对象的时候,会自动的修改属性名
# 在属性名的前边加上 _类名前缀
self.__ICBC_money = 0 # 定义私有属性
# 创建People类对象
xw = People()
# 实例对象.__dict__ 可以查看对象具有的属性信息,类型是字典,字典的key是属性名, 字典的value是属性值
print('赋值之前:', xw.__dict__)
# print(xw.__ICBC_money)
xw.__ICBC_money = 1000 # 不是修改私有属性,是重新添加一个公有属性
print('赋值之后:', xw.__dict__)
print(xw.__ICBC_money)
xw._People__ICBC_money = 1000
print(xw._People__ICBC_money)
print('修改之后:', xw.__dict__)
7.1.2 定义公有的方法,提供接口
# 案例需求: 定义People 类, 定义属性 ICBC_money , 钱不能随便被修改,必须是合法的终端才可以操作
class People(object):
def __init__(self):
# python中的私有本质是 修改属性的名字, 在创建对象的时候,会自动的修改属性名
# 在属性名的前边加上 _类名前缀
self.__ICBC_money = 0 # 定义私有属性
# 定义公有的方法,提供接口,修改余额
def get_money(self):
return self.__ICBC_money
def set_money(self):
num = input('输入金额:')
self.__ICBC_money += int(num)
# 创建People类对象
xw = People()
# 实例对象.__dict__ 可以查看对象具有的属性信息,类型是字典,字典的key是属性名, 字典的value是属性值
print('赋值之前:', xw.__dict__)
# print(xw.__ICBC_money)
xw.__ICBC_money = 1000 # 不是修改私有属性,是重新添加一个公有属性
print('赋值之后:', xw.__dict__)
print(xw.__ICBC_money)
# xw._People__ICBC_money = 1000
# print(xw._People__ICBC_money)
# print('修改之后:', xw.__dict__)
print('=' * 20)
print(xw.get_money()) # 0
xw.set_money()
print(xw.get_money())
xw.set_money()
print(xw.get_money())
7.2私有方法
- 私有方法: 在方法的前边加上两个__ ,就为私有方法
- 私有方法,不能在类外部访问
- 作用: 一般作为类内部的方法使用,不让在外部直接调用, 保证业务逻辑不被破坏
class Dog(object):
def born(self):
"""吃一顿饭,可以睡5个小时"""
print('吃了一顿饭...')
self.__sleep()
def __sleep(self):
print('睡了5个小时')
dog = Dog()
# dog.__sleep()
dog.born()