实验目的
- 掌握Python类和对象的基本用法
实验内容
写一个叫做Adder的类,有一个方法叫做add(self, x, y),这个方法只是打印"Not Implemented"其它什么也不做。然后定义两个子类来实现add方法:ListAdder类,它的add函数可以把两个列表连接在一起;DictAdder类,它的add方法可以把两个字典的内容合并成一个。试着创建三个类的对象,并调用它们的add方法。接着使用构造函数把数据赋给成员保存起来(比如说给self.data赋一个列表或者一个字典),并重载+运算符(__add__方法)来自动调用add方法(比如x+y就会触发x.add(x.data,y))。把构造函数和运算符重载放在哪个类里面是最好的?什么样的对象可以和你的对象进行加法操作?实际上,你可能发现,让add函数只接受一个参数会更简单(例如add(self,y)),并把这个参数和对象本身的数据相加(比如self.data+y)。这样的add函数比原来的add函数更合理吗?这样让你的类更显得面向对象吗?
- 写一个叫做Mylist的类,它包装了Python内部的列表。它可以进行大部分列表的操作,包括+、下标索引、迭代、切片,以及append、sort等方法。查看Python的参考手册来查看list所有可能的操作。同时你的类可以用已有的列表作初始值来构造,给你的类添加一个构造函数来实现这个功能,把已有列表的数据拷贝到对象内部的成员中去。在交互界面下尝试你的类:
- 为什么在构造时要对初始值进行拷贝?
- 可以用空的切片(比如start[:])来对初始值进行拷贝吗?
- 可以有一个通用的方法把所有对Mylist的操作过渡给内部的列表吗?
- 可以对一个Mylist对象和一个普通列表进行相加吗?两个顺序反一下可以吗?
- +和切片操作应该返回什么类型的对象?索引操作呢?
- 除了可以把一个普通列表作为成员实现Mylist以外,还可以通过继承内置的列表类来实现。哪种方法更简单?为什么?
写一个前面所作的Mylist类的子类MylistSub,在它的每个操作的开始增加一个打印信息的语句,并统计函数调用的次数。MylistSub应该从Mylist继承基本的操作。比如说连接操作,首先它打印一个消息,然后对计数器加1,最后调用父类的方法执行功能。增加一个方法,把操作计数器打印出来。在交互式界面下尝试你的类。你的计数器是对每个对象进行计数还是对每个类进行计数?如何两者都实现?
- 写一个叫做Meta的类,写一个方法拦截所有对成员的访问,并把参数打印到屏幕上。创建一个Meta类的对象,并尝试调用它。如果把这个对象用在表达式中,会发生什么事情?如果对它进行+、切片、索引操作会怎么样?
考虑如图所示的这个类图。用Python的继承对这六个类进行编程实现,然后给每个类增加一个speak方法,每个类打印一条个不相同的消息。给顶层的Animal类增加replay方法,它只是简单的调用self.speak。最后把speak方法从Hacker类中移除。 用如下的方法尝试你的类:
>>> from zoo import Cat, Hacker >>> spot = Cat( ) >>> spot.reply( ) # Animal.reply; calls Cat.speak meow >>> data = Hacker( ) # Animal.reply; calls Primate.speak >>> data.reply( ) Hello world!
考虑如图所示的类结构。 用一系列Python类来实现这个结构,Scene对象(戏剧中的一场)内嵌了Customer、Clerk、Parrot类的对象。让Scene类包含一个action方法(开始演出),而内嵌的Customer、Clerk、Parrot类的对象都有一个line方法(台词),打印出一条个不相同的消息。内嵌的对象要么从父类继承了一个line方法,或者自己定义了一个line方法。 最后,这样测试你的类:
>>> import parrot >>> parrot.Scene( ).action( ) customer: "that's one ex-bird!" clerk: "no it isn't..." parrot: None
- 写一个排序二叉树BSTree类,实现类似集合的功能:insert插入一个元素、in判断元素是否在二叉树中,remove删除一个元素,union合并两个集合,intersect求两个集合的交集。
思考题
- 多态是面向对象程序设计的一个核心思想。在C++、Java等静态类型语言中,多态依赖于继承实现。在继承体系中,基类定义虚函数接口,而在派生类中改写(Override)它。程序通过基类中定义的接口去操作派生类对象来实现多态。在Python中,多态是否要依赖于继承?为什么?试举例说明