多态首先是建立在继承的基础上的,先有继承才能有多态。多态是指不同的子类在继承父类后分别都重写覆盖了父类的方法,即父类同一个方法,在继承的子类中表现出不同的形式。多态成立的另一个条件是在创建子类时候必须使用父类new子类的方式。
Fu f1 = new Zi1(); Fu f2 = new Zi2(); f1.c(); f2.c();
子类Zi1,Zi2继承了父类Fu,并且重写了父类的方法c()
然后通过f1,和f2去调用子类重写父类后的这个方法。即还有一个成立条件是子类必须重写父类的方法。
面向对象的三个基本特征是:封装、继承、多态。
比如,你和你朋友同时继承了人这个类中打人的方法,但是你用拳头打人和你朋友用巴掌打人的方法都是打人方法,却表现出不同的形式,这就是现实生活中多态的理解。
关于多态,有一个被称作“鸭子类型”(duck typeing)的东西,其含义在维基百科中被表述为:
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。这个概念的名字来源于由 James Whitcomb Riley 提出的鸭子测试(见下面的“历史”章节),“鸭子测试”可以这样表述:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在 python 中多态的经典使用可以用两句话来总结对扩展开放和对修改封闭,即著名的「开闭」原则。对扩展开放即可以随意的增加父类的子类;对修改封闭即对于依赖父类的函数,新增子类对该函数无任何影响无需做任何修改。
我们可以通过以下代码来加深理解:
#!/usr/bin/env python3 # -*- coding:utf-8 -*- class Person: def __init__(self, name, age): self.name = name self.age = age def print_age(self): print("%s's age is %s" % (self.name, self.age)) class Man(Person): def print_age(self): print("Mr. %s's age is %s" %(self.name, self.age)) class Woman(Person): def print_age(self): print("Ms. %s's age is %s" %(self.name, self.age)) def person_age(person): person.print_age() person = Person("kevin", 23) man = Man("Bob", 33) woman = Woman("Lily", 28) person_age(person) person_age(man) person_age(woman)
以上代码执行结果如下:
kevin's age is 23 Mr. Bob's age is 33 Ms. Lily's age is 28
在以上代码中函数 person_age 函数的输入参数为类 Person 的实例,但是在实际执行过程中 Person 的子类 Man 和 Woman 的示例同样可以在 person_age 函数中正常运行,这既是类的多态的作用。实际上任何实现了函数 print_age 函数的类均可作为 person_age 函数的参数且能够正常工作,这既是前面提到的「鸭子类型」。
本文链接:http://so.lmcjl.com/news/5349/