AYE89

coding & learning

导航

Python的多态、继承与封装

Posted on 2018-03-16 14:41  AYE89  阅读(234)  评论(0编辑  收藏  举报

一、多态

不用知道变量所引用的对象类型,还是能对它进行操作,它会根据对象(或类)的类型不同而表现出不同的行为。

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']