python多态_再谈继承,Python里有什么不同以及多态

一、继承:

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

1e7e019b6f25359d2a2fd183254ff120.png

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

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)

最后,奉上视频

继承的理解

多态的理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
继承是面向对象编程中的一种重要概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。子类可以通过继承来获得父类的特性,并且可以在此基础上添加自己的特性或修改父类的行为。 在Python中,继承可以通过在定义子类时在类名后面加上父类名来实现。子类可以访问父类的属性和方法,并且可以重写父类的方法以实现自己的逻辑。 多态是面向对象编程中的另一个重要概念,它允许不同的对象对同一个消息做出不同的响应。多态性通过方法的重写和方法的重载来实现。 在Python中,多态性是通过动态类型和动态绑定来实现的。动态类型意味着变量的类型是在运行时确定的,而不是在编译时确定的。动态绑定意味着方法的调用是根据对象的类型来确定的,而不是根据变量的类型来确定的。 下面是一个简单的示例代码,演示了继承多态Python中的应用: ```python class Animal: def __init__(self, name): self.name = name def sound(self): pass class Dog(Animal): def sound(self): return "Woof!" class Cat(Animal): def sound(self): return "Meow!" def make_sound(animal): print(animal.sound()) dog = Dog("Buddy") cat = Cat("Kitty") make_sound(dog) # 输出:Woof! make_sound(cat) # 输出:Meow! ``` 在上面的代码中,Animal是一个基类,它定义了一个抽象方法sound。Dog和Cat是Animal的子类,它们分别重写了sound方法。make_sound函数接受一个Animal类型的参数,并调用该参数的sound方法。当我们传入一个Dog对象时,输出的是"Woof!",传入一个Cat对象时,输出的是"Meow!"。这就是多态性的体现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值