Python中的继承:
子类(派生类)继承了父类(基类),那么子类就继承了父类的公共属性和方法
简化了子类的设计,便于后期维护和升级
当一个子类继承多个父类的时候:
如果多个父类的方法名不同,子类会全部继承
如果多个父类方法名相同,子类会继承第一个父类
查看一个类的继承链:
类名._mro_
实际开发中 经常用子类对象去替换掉父类的一个对象
对应的原则称之为 里氏替换原则 LSP
类和类之间有三种关系:is-a has-a use-a
is-a: 继承 或者 又叫做 泛化 关系
比如 学生和人 手机和电子产品
has-a: 关联
比如部门和员工的关系 汽车和引擎的关系
关联关系如果又是整体和部分的关系 这种又可以称作 聚合关系
如果整体负责了部分的生命周期(整体和部分是不可分割的)
同时在同时消亡 就是最强的关联关系 称之为 合成关系
use-a:依赖关系
比如一个司机有驾驶行为(方法)其中(的参数)使用到了汽车
那么司机和汽车就是依赖关系
class A(object):
def __init__(self):
self.a = "我是A类的属性"
def fun(self):
print("我是A类的方法")
class B(object):
# def __init__(self):
# = "我是B类的属性"
def fun(self):
print("我是B类的方法")
class C(A, B):
pass
c = C()
print(f"A的属性:{}") # A的属性:我是A类的属性
print(f"C的继承链:{C.__mro__}") # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
c.fun() # 我是A类的方法
子类调用父类同名属性和方法
class A(object):
def __init__(self):
self.a = "我是A类的属性"
def fun(self):
print("我是A类的方法")
class B(object):
def __init__(self):
self.b = "我是B类的属性"
def fun(self):
print("我是B类的方法")
class C(A, B):
def __init__(self):
super(C, self).__init__()
super(A, self).__init__()
self.c = "我是C类的属性"
def fun(self):
"""重写父类方法"""
print("我是重写父类后C的方法")
def a_fun(self):
"""调用A类同名方法"""
super(C, self).fun()
def b_fun(self):
"""调用B类同名方法"""
super(A, self).fun()
c = C()
print(c.a, c.b, c.c) # 我是A类的属性 我是B类的属性 我是C类的属性
c.fun() # 我是重写父类后C的方法
c.a_fun() # 我是A类的方法
c.b_fun() # 我是B类的方法
总结子类调用父类同名属性和方法的三种方案
父类名.同名方法(self)
super(子类名, self).同名方法()
super().同名方法()
对于super(子类名, self).同名方法名()遵循的类的继承链
如何继承带有参数的父类的构造方法?
class A(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"姓名:{}\n年龄:{}"
class B(A):
def __init__(self, name, age, sex):
super(B, self).__init__(name, age)
self.sex = sex
def __str__(self):
return f"{A.__str__(self)}\n性别:{}"
b = B("小丽", 18, "女")
print(b)
私有属性与方法
概念:
如果一个属性或者方法名是以两个下划线开头, 就称为私有属性或者方法
扩展:
单末尾下划线。按约定使用避免与Python关键字冲突。
特点:
私有的属性和方法, 只能在类的内部使用, 不能在类的外部使用
如果一个类中由私有的属性和方法, 假如子类继承了他, 不能继承私有属性和方法
class A(object):
def __init__(self):
self.__name = "小丽" # 私有属性
self.age = 18
def get_name(self):
"""创建公有方法访问私有属性"""
return self.__name
def set_name(self, new_name):
"""创建公有方法访问私有属性"""
self.__name = new_name
def __love(self):
print(f"Wait")
class B(A):
pass
a = A()
print(f"公共方法访问私有属性:{a.get_name()}")
a.set_name("LiLi") # 公共方法修改私有属性
print(a.get_name()) # LiLi
# python中的私有属性不是真正的私有, 可以通过一下手段进行访问
b = B()
print(b._A__name)
b._A__love()
# 注意:即使存在访问手段,我们也不能通过这种方式来访问
我:这是没有晚安的第二个晚上。