一、多态
不用知道变量所引用的对象类型,还是能对它进行操作,它会根据对象(或类)的类型不同而表现出不同的行为。
def run_twice(animal): animal.run() animal.run() #call run_twice(Animal()) run_twice(Dog())
多态是怎么实现的?
- “延迟绑定技术”,但不同于静态语言的延迟绑定。
静态语言 vs 动态语言
- 对于静态语言(例如Java)来说,如果需要传入
Animal
类型,则传入的对象必须是Animal
类型或者它的子类,否则,将无法调用run()
方法。 - 对于Python这样的动态语言来说,则不一定需要传入
Animal
类型。我们只需要保证传入的对象有一个run()
方法就可以了。
“鸭子类型”
- Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个
read()
方法,返回其内容。但是,许多对象,只要有read()
方法,都被视为“file-like object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()
方法的对象。
isinstance() 及 issubclass()
- Python 有两个判断继承的函数:isinstance() 用于检查实例类型;issubclass() 用于检查类继承。参见下方示例:
class Person(object): pass class Child(Person): # Child 继承 Person pass May = Child() Peter = Person() print(isinstance(May,Child)) # True print(isinstance(May,Person)) # True
二、继承
类名习惯上用单数名词,首字母大写。
- 子类(subclass)
- 超类(superclass):即父类
多重继承:拥有多个超类,例如
class Dog(Mammal, RunnableMixIn, CarnivorousMixIn): pass
- 如果一个方法从多个超类继承,需注意超类的顺序:会从先继承的超类中获得,使后继承的超类中的同名方法不可见。
三、封装
把属性、方法捆在一起。
访问限制(类似于“public”、“private”的概念):__xxx
- #需要注意的是,在Python中,变量名类似
__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__
、__score__
这样的变量名。
接口:
- 配合
getattr()
、setattr()
以及hasattr()
,我们可以直接操作一个对象的状态:
hasattr(obj, 'x') # 有属性'x'吗?
获得对象的属性和方法:使用dir()
如果要获得一个对象的所有属性和方法,可以使用dir()
函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:
>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']