01Python基础阶段_Day09
-
子类中访问父类中的私有属性和私有方法
如果想使用父类中的私有属性和私有方法,那么就需要在父类中,为这些私有的属性和方法,提供相应的公有的接口方法来间接访问 -
如何为父类中的属性进行初始化
在子类中如果定义了自己的初始化方法,那么这时父类的初始化方法就不会再执行了
那么就导致父类中定义的属性无法初始化,子类对象就无法使用继承自父类的属性
如果想正常初始化,需要在子类的初始化方法中,手动调用父类的初始化方法
现阶段调用格式:
父类名.init(self,父类中需要属性参数列表) -
子类中重写和调用父类的方法
在子类继承父类时,子类会拥有父类中的方法.
但是子类并不需要或不满足父类方法中提供的功能,这时就需进行对父类方法重写重写之后,调用该方法时,执行谁?
答案: 调用重写后子类中的方法 -
子类方法中调用父类的同名方法
-
多层继承
继承关系有多层,祖孙三代查找方法:
父类名.方法名(self)
``
# 子类初始化父类的属性
# 父类
class Father(object):
def __init__(self, name):
print("Farther init run...")
self.name = name
class Son(Father):
def __init__(self, name, age):
# 因为子类提供了init方法后,那么在使用子类实例对象时,就会调用子类自己的init方法
# 那么就不会再调用父类的init方法了,父类当中的属性就不会有绑定的机会
# 如果想父类中的属性可以得到,需要执行父类中的init方法
Father.__init__(self, name)
print("son init run...")
self.age = age
# 测试
s = Son("Tom", 12)
print(s.name)
print(s.age)
# 子类重写父类中的方法
class Father(object):
# 实现治病
def cure(self):
print("父类是个老中医")
class Son(Father):
def cure(self):
# 直接使用父类名.方法名的形式引用父类的功能
Father.cure(self)
print("子类出国深造")
s = Son()
s.cure()
# 多层继承
class A(object):
def a(self):
print("a function..")
def __init__(self, a):
self.a = a
class B(A):
def b(self):
print("b function..")
def __init__(self, a, b):
A.__init__(self, a)
self.b = b
class C(B):
# C类中重写了B类中的方法
def b(self):
B.b(self)
print("B in C function...")
def c(self):
print("c function..")
def __init__(self, a, b, c):
B.__init__(self, a, b)
self.c = c
class D(C):
def d(self):
print("d function..")
def __init__(self, a, b, c, d):
C.__init__(self, a, b, c)
self.d = d
# 测试
d = D(1,2,3,4)
# d.a()
# d.b()
# d.c()
# d.d()
print(d.a)
print(d.b)
print(d.c)
print(d.d)
-
多继承
格式:
class 类名(父类名1,…):
pass -
多继承的初始化
父类名调用 理解
super()调用 使用
super(类名,self) 了解super执行过程:
在 self 这个对象的所属类中,通过 mro 找到方法解析顺序
在顺序中,找当前类名的下一个类来初始化或查找方法在多继承时,如果继承的多个类同时继承同一个父类,那么这时会出现初始化问题
这个共同父类会被初始化多次.类名.mro 得到了一个元组,元组中的元素是当前类在继承关系上的一个顺序
方法解析顺序
method relational ordered这个顺序不是我们确定的,是由在确定某个类的继承关系关系后,由解释器来确定这个顺序
super对象是基于类的mro顺序来对当前类进行初始化的
基于这个mro顺序可以保证,所有的继承关系的上类,都只执行一次mro -> 一个类的继承书写顺序会影响mro顺序
-
多继承调用指定父类中方法
父类名.方法()
super().方法() -
多态
多种形态
程序中的意义:
当调用一个方法名的时候,得到的结果不同
在一般的面向对象语言中,多态是由继承来实现的
但是在python中,python,天生具有多态性鸭子类型: Duck Typing
一只鸟如果长的鸭子,叫声像鸭子,那么就认为它就是鸭子 -
实例对象属性和实例对象方法
以 对象名.xxx 的形式调用的都是实例的属性或实例的方法
实例属性和实例方法只能由实例对象调用
-
类对象和类属性
类属性可以使用实例对象来引用,但是不能修改
一般情况下:类属性 都只使用 类对象 来调用类对象.类属性
-
类方法
-
静态方法
``
'''
多继承:横向
多层继承:纵向
'''
class Farther(object):
def func_fa(self):
print("Father function....")
class Mother(object):
def func_ma(self):
print("Mother function....")
# 上面的两个类有一个公共子类
class Son(Farther, Mother):
def play(self):
print("Son play....")
s = Son()
s.play()
s.func_ma()
s.func_fa()
# 多继承的初始化问题
# 在这种继承关系上,这个共同点父类Person会被初始化多次,这是继承时的问题
# 是由于父类名调用实现初始化方法的时候引起的
class Person(object):
def __init__(self, aaa):
print("Person init...")
self.aaa = aaa
class Father(Person):
def __init__(self, name, *args):
# super(Father, self).__init__(*args)
super().__init__(*args)
print("Father init...")
self.name = name
class Mother(Person):
def __init__(self, age, *args):
# super(Mother, self).__init__(*args)
super().__init__(*args)
print("Mother init...")
self.age = age
class Son(Father, Mother):
# 注意这个参数位置得与后面调用时的参数顺序一致
def __init__(self, gender, name, age, aaa):
# 参数一是当前类名,参数二是当前类的实例对象
# 在参数二对象的所属类的mro关系中找参数一的下一个类进行初始化
# super(Son, self).__init__(name, age, aaa)
# 简化形式
super().__init__(name, age, aaa)
self.gender = gender
s = Son("男", "tom", 12, 1)
print(s.aaa)
print(s.name)
print(s.age)
print(s.gender)
print(Son.__mro__)
f = Father("Jack", 2)
print(f.aaa)
print(f.name)
print(Father.__mro__)
# 类的继承书写顺序会影响mro顺序
class A(object):
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
print(D.__mro__)
# 多重多继承时,方法的查找顺序也参考mro
# 多态
# 实例属性和实例方法
class Cat(object):
def __init__(self, name):
# 定义一个实例属性
self.name = name
# 定义一个实例方法
def info(self):
print(self.name)
tom = Cat("Tom")
# 使用实例属性
print(tom.name)
tom.info()
# Python中万物皆对象
# 类名不能调用实例对象和实例方法,因为类对象存在时,不一定有实例对象存在
# 类对象和类属性
class ClassRoom(object):
# 当定义一个类属性时,相当于这个类中的全局变量
# 该类的所有对象都可以使用该类属性
# 可以在所有对象间进行数据共享
kong_tiao = "格力空调"
cr901 = ClassRoom()
print(cr901.kong_tiao)
cr901.kong_tiao = "海尔空调"
print(cr901.kong_tiao)
ClassRoom.kong_tiao = "某空调"
cr902 = ClassRoom()
print(cr901.kong_tiao)
print(cr902.kong_tiao)