一、继承:

继承(Inheritance)我叫小王,我爸是大王。继承的本质是个性对共性的属性与方法的接收,并加入个性特有的属性与方法。

python 多重继承初始化调用 python的多重继承的理解_python多态

一个类继承另一个类,则称继承的类为子类、派生类、衍生类,被继承的类为父类、基类。通过继承实现代码的复用,达到延续和扩展父类信息。继承后子类自动拥有了父类的属性和方法,子类根据需要新增和重写自己特有的属性和方法,实现功能的扩展。

1、理解

继承的本质在于抽象。类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模。同时使用继承可以提高代码的复用性。(事实上,利用组合可以更好的实现代码复用!)

1class Parent:
 2    money = 1000
 3    job = '房地产'
 4
 5    def __init__(self):
 6        print("初始化父类。。。")       
 7
 8
 9class Child(Parent):
10    job = ''
11
12    def __init__(self,job):
13        self.job = job
14        print("初始化子类。。。")   
15
16    def __str__(self):
17        return '属性:"%s", %s' % (self.job, self.money)
18
19c = Child('电竞')
20print(c)

运行结果:

1初始化子类。。。
2属性:"电竞", 1000

2、判断子类    
使用issubclass(cls, A_tuple)判断是否为某一个类的子类,其中cls 就是要判断的是否为A_tuple中类的衍生类或者同类,A_tuple可以是一个元组,也可以是一个元素,为父类的元组,A_tuple中有一个类是cls的父类则返回True。

1class A:
 2    pass
 3class B(A):
 4    pass
 5class C(B):
 6    pass
 7class D(B):
 8    pass
 9
10print(issubclass(B, A), issubclass(C, A))
3、私有信息访问限制

如果子类方法想要访问父类的私有属性和方法时,是不能直接访问的,只能通过调用父类方法访问

1class Parent:
 2    def __init__(self, name):
 3        self.__name = name # 私有属性
 4    def __drinking(self): # 私有方法
 5        print("%s爱抽烟。。" % self.__name)
 6    def get_name(self):
 7        return self.__name
 8class Children(Parent):
 9    pass
10c = Children("小明")
11#print(c.__name) # 会报 no attribute错误
12# c.__drinking() # 会报 no attribute错误
13print(c.get_name())
4、方法重写

方法重写就是当父类的方法不能满足业务时,就可以通过子类重写父类的方法达到效果,而不需要修改父类方法。在Python中重写就是覆盖父类方法,那么我们在调用时都会遵循就近原则。

1class Father:
 2    name = ''
 3    age = 0
 4    def eat(self):
 5        print("爸爸吃一碗!")
 6class Son(Father):
 7    def eat(self):
 8        print("儿子吃一盆!")
 9def main():
10    s = Son()
11    s.eat()
12if __name__ == '__main__':
13    main()

Son类重写了Father的eat方法,当main方法调用eat方法时,会优先考虑自己本类的方法,如果没有才会去寻找父类方法。如:

1class Father:
 2    name = ''
 3    age = 0
 4    def __init__(self, name, age):
 5        self.name = name
 6        self.age = age
 7    def study(self):
 8        print("%s在看python指南!" % self.name)
 9        self.sing()
10    def sing(self):
11        print("爸爸在唱精忠报国")
12class Son(Father):
13    def sing(self):
14        print("%s在唱夏洛特烦恼" % self.name)
15def main():
16    s = Son("大锤", 18)
17    s.study()
18if __name__ == '__main__':
19    main()

二、多态

多态(polymorphism)是很多面向对象编程语言的重要特性,尽管我们的python语言中没有多态这一特性,但是不影响我们对这一特性的了解。不要叹息,我们的python语言特价灵活,有更加灵活的鸭子模型。要是我对你说今天会有好事发生。我并没有说好事是什么,这个好事就是模糊的,究竟是什么好事呢?就是今天我们就会将继承、封装、鸭子模型三大特性斩获囊中。
电脑上的USB接口,就是一个多态,凡是实现了这个接口的电子产品如u盘、打印机、手机都可以与电脑对接,在python中,多态更加灵活,只需要一个对象“看起来像鸭子,走起路来像鸭子,那它被认定是只鸭子”即经典的鸭子模型。

1、理解

在同一个方法中,参数不同导致结果不同的现象叫多态。比如定义一个鸟类,在定义百灵鸟类和鹦鹉类,然后在重写fly方法。定义一个方法,如果传入的是百灵鸟类就会打印百灵鸟的fly方法,如果传入鹦鹉打印鹦鹉的fly方法。

1class Bird:
 2    def fly(self):
 3        print("鸟会飞。。。")
 4class Lark(Bird):
 5    def fly(self):
 6        print("百灵鸟在飞。。。")
 7class Parrot(Bird):
 8    def fly(self):
 9        print("八哥在飞。。。")
10def fly(bird):
11    bird.fly()
12lark= Lark()
13parrot = Parrot()
14fly(lark)
15fly(parrot)
2、实例

王大锤有一个车库,里面有两种车,奔驰和奥迪,那他具体开哪辆呢,就是要到时开车方法里面传入的是什么车,那就开什么车

1import random
 2class Car:
 3    def __init__(self, color, name):
 4        self.color = color
 5        self.name = name
 6    def run(self):
 7        print(self.name + "启动了")
 8class Bmw(Car):
 9    def __init__(self, color):
10        self.color = color
11        self.name = "宝马"    
12class Benz(Car):
13    def __init__(self, color):
14        self.color = color
15        self.name = "奔驰"    
16class Carport:
17    def __init__(self):
18        self.cars = []
19    def fill(self, car):
20        self.cars.append(car)
21    def get_car(self):
22        return self.cars[random.randint(0, len(self.cars)-1)]
23class Person:
24    def drive(self, car):
25        print("我在开%s的%s" % (car.color, car.name))
26if __name__ == '__main__':    
27    port = Carport()
28    port.fill(Bmw("红色"))
29    port.fill(Benz("黄色"))
30    car = port.get_car()    
31    p = Person()
32    p.drive(car)
3、鸭子模型

因为Python是弱类型语言,所以它的多态和其他面向对象语言比如Java不一样,在Java中实现多态必须使用继承,不然编译就会出现类型不符合,而Python本身不会出现这样的情况,因此在实现多态时,并不一定要使用继承,比如刚刚品酒的例子进行修改:

1class MaoTai:
 2    @staticmethod
 3    def show_advertisement():
 4        print("相逢,人生的机缘;相识,人生的财富;相知,人生的感动。 5茅台迎宾酒,迎宾迎天下")
 6class WuLiangYe:
 7    @staticmethod
 8    def show_advertisement():
 9        print("中国的五粮液,世界的五粮液!")
10class JianNanChun:
11    @staticmethod
12    def show_advertisement():
13        print("唐时宫廷酒,盛世剑南春")
14class Person:
15    def drink(self, wine):
16        wine.show_advertisement()
17        print("----")
18if __name__ == '__main__':
19    p = Person()
20    p.drink(MaoTai)
21    p.drink(WuLiangYe)
22    p.drink(JianNanChun)

鸭子模型是动态语言的一个特点,意思就是一个对象“看起来像鸭子,走起路来像鸭子,那它被认定是只鸭子”, 就像刚刚品酒,我定义的MaoTai、WuLiangYe、JianNanChun并不需要集成Wine类,只需要在它们三个类中有一个show_ad的方法,那么在Person类中的drink()方法就可以传入这三个不同的类也能达到打印不同的广告词的效果。这个在静态语言中是没法完成的,因为静态语言对参数的类型有严格的限制。也就是讲动态类型语言的变量或者参数不需要声明的原因,都只需要在运行时校验。

4、super()

上面讲到了重写,子类会覆盖父类的方法,但如果你一定要调用父类方法时,怎么办呢?就使用super()调用

1class Father:
 2    name = ''
 3    age = 0
 4    def __init__(self, name, age):
 5        self.name = name
 6        self.age = age
 7    def kungfu(self):
 8        print("祖传的咏春拳。。")
 9class Son(Father):
10    # 重写父类的方法,但是祖传的咏春还是会的,因此要用super()调用父类
11    def kungfu(self):
12        #super(Son,self).kungfu()
13        super().kungfu()
14        print("会八卦掌、形意拳。。")
15def main():
16    s = Son("小明", 18)
17    s.kungfu()
18if __name__ == '__main__':
19    main()

继承字典类:

1class ObjectDict(dict):
2    def __init__(self, *args, **kwargs):
3        super().__init__(*args, **kwargs)       
4    def __getattr__(self, name):        
5        return self[name]
6if __name__ == '__main__':
7    object_dict = ObjectDict(price=100.1)  
8print(object_dict.price)

来个复杂点的例子:

1class ObjectDict(dict):
 2    def __init__(self, *args, **kwargs):
 3        super(ObjectDict, self).__init__(*args, **kwargs)       
 4    def __getattr__(self, name):
 5        if isinstance(self[name], dict):
 6            return ObjectDict(self[name])
 7        return self[name]
 8if __name__ == '__main__':
 9    object_dict = ObjectDict(b={'name': '高性能MySQL'}, price=100.1)
10    print(object_dict.b, object_dict.b.name)
11    print(object_dict.price)

最后,奉上视频

继承的理解

多态的理解