- 论坛徽章:
- 0
|
8、面向对象编程:封装、继承、虚拟函数、接口、多继承、模板
Python是一种典型的动态类型语言,由于他的动态性:
- 天生支持虚拟函数、接口、模板等特征,无须引入特定的关键字
- 在多继承中不存在“菱形继承”引发的问题
下面我们通过举例的方式学习面向对象语言中的各种特性
1、封装
- class Person:
- def __init__(self, name):
- self.name = name
- def getName(self):
- return self.name
- person = Person('person')
- print 'name = %s' % person.getName()
- 程序输出:
- name = person
复制代码
与C++不同的地方:
- 类的成员函数的第一个参数是指向这个对象的self引用
- 在成员函数里,必须通过self引用访问其他的成员变量或者成员函数
- class Person:
- def __init__(self, name):
- self.name = name
- getName()
- def getName(self):
- return self.name
- person = Person('person')
- print 'name = %s' % person.getName()
- 运行时刻出错,NameError: global name 'getName' is not defined
复制代码
- 构造函数的名称为__init__
2、继承
- class Chinese(Person):
- def __init__(self, name, company):
- Person.__init__(self, name)
- self.company = company
- def love(self):
- print '%s is Chinese, he love working' % self.name
- def work(self):
- print '%s is working in %s' % (self.name, self.company)
- class Japanese(Person):
- def __init__(self, name, interesting):
- Person.__init__(self, name)
- self.interesting = interesting
- def love(self):
- print '%s is Japanese, he love playing' % self.name
- def play(self):
- print '%s is playing %s' % (self.name, self.interesting)
- zhangSan = Chinese('Zhang San', 'HuaWei')
- zhangSan.love()
- zhangSan.work()
- sanJing = Japanese('San Jing', 'Basketball')
- sanJing.love()
- sanJing.play()
- 程序输出:
- Zhang San is Chinese, he love working
- Zhang San is working in HuaWei
- San Jing is Japanese, he love playing
- San Jing is playing Basketball
复制代码
3、虚拟函数
- zhangSan = Chinese('Zhang San', 'Hua Wei')
- sanJing = Japanese('San Jing', 'Basketball')
- persons = [zhangSan, sanJing]
- for person in persons:
- person.love()
- 程序输出:
- Zhang San is Chinese, he love working
- San Jing is Japanese, he love playing
复制代码
这个例子建立了继承于Person的Chinese和Japanese类,Chinese中定义了love和work两个成员函数,Japanese中定义了love和play两个成员函数,注意:
- Python中没有virtual关键字,默认成员函数都是虚函数,这一点与java类似。
- 在Chinese和Japanese的父类Person中无须声明两者共同的接口(love函数),这一点与java不同
4、接口
- class Cat:
- def __init__(self, name, food):
- self.name = name
- self.food = food
- def love(self):
- print '%s is Cat, he love eating %s' % (self.name, self.food)
- def callLove(object):
- object.love()
- zhangSan = Chinese('Zhang San', 'HuaWei')
- sanJing = Japanese('San Jing', 'Basketball')
- mimi = Cat('MIMI', 'fish')
- objects = [zhangSan, sanJing, mimi]
- for object in objects:
- callLove(object)
- 程序输出:
- Zhang San is Chinese, he love working
- San Jing is Japanese, he love playing
- MIMI is Cat, he love eating fish
复制代码
注意:- Chinese和Japanese有共同的祖先Person,而Cat和Chinese、Japanese完全不相关
- 三者都有共同的接口:love函数
- callLove函数的参数是无类型的,实现以上功能,无须像Java一样要引入interface的概念
5、多继承
- class Mix(Chinese, Japanese):
- def __init__(self, cname, jname, company, interesting):
- Chinese.__init__(self, cname, company)
- Japanese.__init__(self, jname, interesting)
- mix = Mix('Zhang San', 'San Jing', 'HuaWei', 'Basketball')
- mix.love()
- mix.work()
- mix.play()
- 程序输出:
- San Jing is Chinese, he love working
- San Jing is working in HuaWei
- San Jing is playing Basketball
复制代码
- 这是一个所谓的菱形继承,但是Mix类中只有一份name的拷贝
- Mix的构造函数中,先调用Chinese的构造函数,把name初始化为Zhang San;随后调用Japanese的构造函数,把name有改为San Jing,因此后面打印出来的名字都是San Jing
- work是Chinese特有的方法,调用正常
- play是Japanese特有的方法,调用正常
- love是Chinese和Japanese共有的方法,这里调用的是Chinese的love方法
6、模板
Python是动态类型的语言,天生支持模板,看两个例子:
函数模板
- def min(a, b):
- if (a < b):
- return a
- else:
- return b
- print(min(1, 2))
- print(min(1.5, 2.5))
复制代码
类模板
- objects = [Person('person'), Cat('mimi')]
复制代码
Python中内置的高级数据类型有:列表、字典、元组,它们可以存储任意类型的元素,实现容器时无须像C++的stl需要template的支持,这一点与Java类似。
[ 本帖最后由 missjiang 于 2007-9-25 19:34 编辑 ] |
|