多态和封装
目录
多态
多态指相同的操作或讯息在不同对象上产生不同的行为。Python 中的多态体现在对参数类型不做限制。
>>> "This is a book".count("s")
2
>>> [1,2,4,3,5,3].count(3)
2
同样的 count() 方法作用在字符串和列表上,处理逻辑不同但都能正常工作。
>>> f = lambda x,y: x+y
>>> f(2, 3)
5
>>> f("qiw", "sir")
'qiwsir'
>>> f(["python","java"], ["c++","lisp"])
['python', 'java', 'c++', 'lisp']
lambda 函数对参数类型无限制,+ 操作符根据对象类型而异。这就是多态。
鸭子类型
在 Python 中,“如果它走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那就把它当作鸭子”。即:一个对象的有效语义由其当前的方法和属性决定,而不是由其类型。
继承中的多态
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
class Animal:
def __init__(self, name=""):
self.name = name
def talk(self):
pass
class Cat(Animal):
def talk(self):
print "Meow!"
class Dog(Animal):
def talk(self):
print "Woof!"
a = Animal()
a.talk()
c = Cat("Missy")
c.talk()
d = Dog("Rocky")
d.talk()
输出:
Meow!
Woof!
同一个 talk() 方法在不同子类中有不同的实现。
封装和私有化
封装是将某些部分隐藏起来,使程序外部无法调用。Python 中使用双下划线前缀来私有化属性和方法。
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
class ProtectMe:
def __init__(self):
self.me = "qiwsir"
self.__name = "kivi"
def __python(self):
print "I love Python."
def code(self):
print "Which language do you like?"
self.__python()
if __name__ == "__main__":
p = ProtectMe()
print p.me
print p.__name # AttributeError: 'ProtectMe' object has no attribute '__name'
类内部可以调用私有方法,但类外部无法访问。
使用 property 访问私有属性
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
class ProtectMe:
def __init__(self):
self.me = "qiwsir"
self.__name = "kivi"
@property
def name(self):
return self.__name
if __name__ == "__main__":
p = ProtectMe()
print p.name # kivi
使用 @property 装饰器可以以属性的形式访问私有属性,实现受控访问。