当前课程知识点:Python 交互式程序设计导论 >  第6周 >  A 课程视频(类) >  面向对象编程(类和对象进阶)

返回《Python 交互式程序设计导论》慕课在线视频课程列表

面向对象编程(类和对象进阶)在线视频

面向对象编程(类和对象进阶)

下一节:对象可视化跟踪执行

返回《Python 交互式程序设计导论》慕课在线视频列表

面向对象编程(类和对象进阶)课程教案、知识点、字幕

上一节课老师向大家介绍了面向对象的基本理论

以及面向对象程序设计的一些基本特点

在这节课中我们将继续深入学习相关的内容

带领大家思考一些非常重要的问题

比如说,我们为什么要用“类”?

面向对象程序设计的优越性体现在哪里?

我们会通过一个实例带领大家深入研究回答这些问题

好,下面我们开始今天的内容

作为面向对象程序理论的初学者

同学们呢可能会有这样的困惑或疑问

我为什么要学这样一个新的理论?

我没有学它我也一样能写程序编代码

其实我在当年学习这样理论的时候呢,也有几个问题一直困扰着我

我为什么要用类?面向对象的优越性到底体现在哪里?

第二个呢,如何设计类之间的关系?

第三,类中应该封装哪些数据和操作?

我们在编程过程当中必须要解决和明确这几个问题

下面呢我们不谈理论,通过一个实际的例子,我们来看一下

这个程序呢非常简单,同学们请看

实际上在程序一运行

这个小球会沿着这个直线从左上角一直运行到右下角并停止

这样一个程序相信各位同学到今天应该是非常容易能够写出来

应该能写出来,好这里呢,我把代码给大家简单介绍一下

好我们来看一下,首先,导入相关的开发包,定义了两个常量

这两个常量呢,几乎所有这种带界面的这样的程序呢

可能我都会定义,它指的是画布的宽和高

那么x和y这个初始坐标实际上是指的直线的一个点

就是左上角

那么对draw函数来讲,这里面的代码也非常容易,也好理解

这一部分首先我定义了x和y是global全局的

也就意味着,我后续的一些对x和y的修改是针对这两个全局变量的

那么呢通过canvas.draw_line去画这条线,这是直线的一个点

这是直线的另外一个点

显然这两个点一个是画布的左上角[0,0],一个是画布的右下角

那么两点决定一条直线,这条直线我当然能够画得出来

这是线宽,这是线条的颜色 非常好理解

那么下面这句话呢是绘制一个小球,好,小球的位置x和y

注意这两个参数其实就是这里的全局变量

好,后面的内容呢我就不再多说了,非常好理解

下面呢我们开始修改小球的位置,只有不断的修改和刷新

这个小球才会动起来,我们来看一下。

我们首先不来看这个if语句,直接看里面的内容

第一句话是x=x+1,显然我们是让小球的横坐标增加了一个像素

那么它的纵坐标等于什么呢?等于一个表达式

这个表达式看起来有一点点复杂,实际上呢这用到的是同学们在集合里面学到的直线的这样一个方程式

知道了直线中一个点的x坐标,你就可以利用这个方程求出它的纵坐标y,这个很好理解

如果同学们忘了这个公式,可以查阅一下相关资料,在这我就不解释了

实际上这两句话的意思是x作为自变量,我让它每次增加一个像素

你用这个方程式来求出对应的y是多少,仅仅是用来更新小球的位置

再来看这个条件

实际上这句话呢是用控制小球不要超出画布的宽度

小球的x坐标不要超出画布的宽度

如果超出了,你就不许动了

好,那么整个draw函数是1秒钟刷新60次

意味着小球呢在1秒钟之内它的横坐标会发生60次变化

纵坐标也同时会发生变化

这个时候它就会沿着这样一个x、y的这个方向

沿着这条直线进行运动

下面三句话非常简单

创建一个界面

然后注册屏幕绘制函数draw,然后启动这个程序

好,我们在Pycharm中看一下实际的运行效果

好,我们来看一下,运行一下,大家看,非常简单

实际上就是在draw函数中不断刷新小球中心坐标x、y

好,停止了,这个时候小球的中心

显然已经到了画布的最右边,如果再往下移动就会超出的

这就是我if语句判断的一个条件

那么下面呢我想请大家思考一个问题

这样一个程序我们每一个人应该都能编写出来

但是呢我想对这个程序进行一个扩充

我现在不仅仅想让小球沿直线进行运用

我还想让小球沿其它的弧形或者其它的曲线进行运动

那么请同学思考一下,如果在原有的程序中让你修改你会怎么做呢?

同学们可能会觉得很困难,因为如果在这个程序的基础之上

我要修改为曲线的话,实际上相当于重新编写一个程序

如果我再改成其他的抛物线或者是其它的运动轨迹

那这个时候实际上你会编写很多个类似的程序

好,那么下面如果我们要把这个程序稍加改造

以面向对象的编程模式来实现它,我们看看会有什么样的效果

在这里呢我为了节约时间我已经把主要的代码呢,已经实现了

我们直接来先运行一下,看一下效果,好,我们来看一下,我们先来执行直线,按直线运行

大家看,跟刚才的那个程序实例呢效果是完全一样的

好,那么下面我把它改成曲线,这个半圆,怎么做呢?

我只需要把这个field,这个对象修改一下就可以了

运行一下,它会沿着这个半圆运行,到这里停止,非常简单

我的源程序几乎不用做什么太大的变化,好,怎么实现的呢?

我们下面来分析一下这个源代码,同学们好好体会一下

当程序规模或者是可扩展性到达一定要求的时候

这个时候呢面向对象的程序设计思想的优越性就会体现出来

好,我们来看一下,好,首先,我依然是定义了四个常量

一个是画布的宽度,一个是画布的高度,这个毫无疑问

下面呢是小球的半径,这个是小球的颜色,这个非常简单

好,我们再往下看,在这里呢我定义了三个class类

好,我们来看,第一个类呢是Line,直线

第二个类呢是Circle,圆

第三个类呢是Ball,小球

三者之间是什么关系,大家可以想一想

实际上小球运动它并不是自由运动的

它需要按照一定的轨迹,这个轨迹是谁给它的呢?

实际上是由Line或者是Circle传给这个Ball的

它会告诉你小球你要按照Line运行还是按照Circle运行

实际上是由这两个类来对它进行限制,那这个时候呢

Ball这个class里面实际上要接受你要求我要按照什么轨迹运行的对应的class

我们首先来看一下Ball

好,同学们来看一下,代码也是不长,十来行,我们来看一下

在这个Ball里面我们首先有一个初始的方法

里面有半径,颜色,这个好理解

实际上就是我们前面的这个定义的常量,传入进来就可以了

关键的问题是domain,这个属性很奇怪

很多同学可能觉得,什么意思?

实际上这个属性就是用来告诉小球你要按照domain这个属性规定的轨迹来运行

讲到这可能很多细心的同学已经发现

我们实际上是要把Line和Circle生成的对象传入到domain这个属性里面

没错我们继续分析

好,在初始化里面大家可以看到

对它的半径属性,颜色属性和domain属性进行赋值

然后对它的pos,就是初始化的位置也进行赋值,这非常容易

然后update里面呢,大家注意看这,非常重要,这非常重要

实际上主要难理解的代码都在这里,大家看,domain是一个你要运行的轨迹的对象

那么在这里呢我们计算domain返回的坐标x、y,并且把它赋给小球的pos

也就是小球的中心点坐标

那么为什么domain会有calculate这样一个计算的方法或者函数呢?

实际上是我们在class Line和class Circle中定义好的,我们来看一下

好,我们来看一下,那么这个Line class里面注意看

pos1,pos2分别是两个点的坐标

表示的是两点决定一条直线,这个ins函数主要是看什么的?

大家来看,判断x是否越界,什么意思?

就是超出画布范围了,所以我们要判断一下是否在我们的画布范围之内

比如说我在画这条直线的时候

两个点我一个给的左上角[0,0],一个给的右下角是WIDTH和HEIGHT

那这个时候pos2的0坐标实际上就是WIDTH的值,那么x小于WIDTH才是在画布内部

否者就会超出画布,所以呢这个ins就是用来判断小球不能越界

不能超出画布范围,仅此而已

那么get_start这个函数呢返回的是小球的起始位置,这个很好理解

小球从哪开始运动啊?对吧

你的轨迹有一个起点,有一个终点,然后关键是在这里

calculate这个方法实际上是用来计算小球的中心点的坐标

当然直线的计算公式和半圆或者其它曲线的计算公式是不相同的

大家看一下,在这里呢看上去很长的一个表达式

大家看一下很长的一个表达式,实际上呢仅仅是用来计算小球的x和y中心点的坐标

当然同学们想一想我知道了直线的方程式,我也知道了它的起始位置

每次给x增加1,当然可以计算出y的值

所以呢这就是返回给我一个x,我返回它对应的纵坐标

那么draw很简单,draw就是把自身自己的轨迹形状绘制在屏幕上

我这是直线class,所以呢使用draw_line来绘制的

好,同样的道理我们来看一下Circle这个class

初始化很简单,我在这不多说了

无非是中心点的坐标,半圆和border它的边界的线宽

那么依然它会有同名的方法ins,这个呢仍然是来判断小球不能越界

小球不能越界,什么意思呢?

就是小球你运行的时候你总得有个边界,不能超出这个范围

比如说我按半圆去运行的话,那么小球从左边一直运行到右边就停到这里了

如果再运行的话就会超出边界,这主要做这样一个判断

返回的是布尔型,get_start也是返回小球运行的起点位置

calculate这个方法同样也是用来计算y的值

你给我一个x我会返回你一个y

当然这个y的计算公式显然要比直线复杂一些

牵扯到开根号,为什么呢?大家还记得圆的方程式吗?

如果同学们忘了,可以查阅一下网上的相关资料,非常简单的一个初等数学里面的公式

给我一个x的自变量,我会算出一个y值

所以呢我可以返回给你小球新的位置,当然这里面可能还需要有取绝对值

或者取整这样一些操作,都调用的是math底下的函数

好,最后呢绘制自己,绘制这样一个圆

注意在界面上看我们看到的是半圆是因为我把整个圆绘制在屏幕画布的下部

所以它只显示半圆,为了使代码更简单一些

讲到这里可能同学们有点糊涂

老师前面讲了class Line,class Circle这两个类究竟是干什么用的?

它们俩之间到底是什么关系?

实际上它们俩都是为我的这个class Ball小球这个类服务的

它们俩实际上是最终会被实例化传入到domain这个属性当中

用很简单的话来描述就是

小球要按照什么轨迹来运动取决于domain接受的是Line还是Circle

如果domain接收到的是Line这个对象,那么它就是按照直线运动

如果接收到的是Circle这个对象,它就是按曲线运动

对小球来讲它不需要关心其它的事情,它只盯着domain这个属性就可以了

大家注意一下,好,那么下面就简单了,大家看一下

我在这里呢创建了一个,大家看这两句话,我先把下面的注释掉

大家看,我在这里呢创建了一个field,我把它当成一个域

也就是小球运行的轨迹,它呢是一个什么类型的对象呢?

是一个Line,这个Line是什么意思呀?

就是我在这里定义的一个class类Line

这句话的含义就是我定义了一个对象,对象名叫field,这个对象是什么类型的呢?

是一个Line,是一个直线

那我传进去两个点的参数,这个时候这个Line就会被定义好,field就会被定义好

注意这实际上就是要传入到Ball那个class当中的domain域的domain属性的

我们来看,下面呢我们会创建一个ball

这个ball呢当然是用的是ball这个class

传入三个参数,注意半径常量,颜色常量,注意最后一个我传入的是field

这个field传入进来,从现在的代码上来看,当然是一个直线了

毫无疑问是一个直线,那么传进来的这个参数就会被赋给domain这个属性

那么下面对于ball来讲它只需要管domain返回给我的ins这个方法是否有效

calculate这个方法是否有效

如果没有问题,那我就可以按照你给指定的轨迹运行了

好,最后三句话呢就是我们创建界面,注册绘制函数和启动程序

对我的draw函数来讲,每1秒执行60次,无非是绘制域本身,就是图形轨迹本身

比如说直线或者是圆圈,那么第二句呢就是更新小球的位置

然后把小球绘制在画布上,仅此而已

好,我们来运行一下,直线我们已经看过了

我们再来看一下曲线

大家看,沿曲线运动,那我想改成直线呢

实际上我只需要告诉程序,我现在的domain换了

我现在的域呢不是曲线了,我现在是直线了,为什么呢?

它们俩是同名的,反正最终都是传给了ball这个对象,所以呢我再来运行一下

好,大家看,如果我的程序按照这样一个面向对象的程序思想来设计和编写的话

我对它做很小的修改就可以把这个程序的功能扩充的非常丰富

比如说我除了半圆,我可能还有曲线,抛物线各种等等各种各样的轨迹

其实无非就是创建多个这样的domain的class

好,回顾一下,在这个事例中,我重点想给大家介绍就是这三个class之间的关系

Ball是我最终要绘制在屏幕上的小球的定义

那么在这个小球的定义里面

除了半径和颜色以外,还有一个非常重要的属性,就是domain

这个domian是用来限制小球运行的轨迹的,那么这个domain是什么东西呢?

实际上是由我的另外两个class,Line和Circle决定的

当然,有些同学可能还会创建第三个,第四个,第五个class

那这个时候你的小球就可以沿着更丰富的轨迹去运行了

那么如果我要扩充这个程序,所有代码都不需要修改

只需要定义新的class并且保证这个class里面有ins,有ins这个方法

有get_start方法,有calculate方法

有draw方法,就可以执行,其它代码都不需要变

好,通过这个例子呢,我们来回答在开课之前我们讨论的那三个问题

为什么要用类?

面向对象的优越性究竟体现在哪里?

同学们思考一下,当我的程序很小,我可以用很灵活很朴素的语言来实现

如果你的程序逐渐变大,变成大规模的程序

你就要对程序进行合理的结构设计,否则你可能会用很多的代码来完成很简单的功能

说明你的代码的结构本身不是最优化的

第二,面向对象的优越性体现在哪里呢?

通过刚才这个例子同学们应该能够体会的到

实际上面向对象它会使得我们的程序有非常优化的结构和良好的可扩展性和灵活性

比如说刚才我们可以很容易的把直线轨迹扩展到曲线

半圆,甚至还可以扩展到抛物线,三角函数的曲线等等

第二点,如何设计类之间的的关系?

在刚才这个程序中实际上class Line直线类

和class Circle圆圈的这个类和class Ball

这三者之间就是我在这提的从属关系,什么意思呢?

Ball这个类,小球这个类,实际上,Ball这个类

实际上有一个domain属性,而domain这个属性

实际上是要传入class Line或者是Circle

也就是说Line这个class和Circle这个class

最终是作为属性传入到Ball这个class的

这就是一种从属关系,当然对类还有一个非常典型的关系

叫继承关系,这个呢我在这就不多说了

在这个例子当中体现的是一种从属关系

也就是说Ball是要调用其它两个类的

好,最后一个问题也非常重要,那么类当中究竟应该封装哪些数据及操作呢?

在这我只希望大家记住6个字

类中应该封装哪些数据及操作有一个原则叫“高内聚,低耦合”,什么意思?

就是在类中所定义的属性和方法必须有紧密的关联程度,叫“高内聚”

它们之间有非常紧密的互操作性,有非常紧密的联系

我们才把它定义在一个类当中,那么类和类之间尽量的“低耦合”,什么意思呢?

他们之间联系的紧密程度应该越低越好,只有这样大家想一想

当我程序规模不断扩大需要多个人合作的时候

我们才可以把整个程序分模块对任务进行分工

而我们可以把这些模块很灵活的组合起来

就是我要的程序,所以呢请大家注意

记住这6个字,“高内聚,低耦合”是我们对程序设计中类定义的时候

类设计的时候要遵循的一个原则

好了今天呢通过这样一个事例给大家初步探讨了一下所谓的面向对象编程的一些优越性

和我们如何去设计类,以及类中应该究竟封装哪些数据及操作

好,请同学们在课后呢继续认真思考一下这几个问题

非常重要,今天的课就讲到这里

Python 交互式程序设计导论课程列表:

第0周

-课程简介

--课程简介

-A 课程视频(算数操作符及表达式)

--绪论

--Python交互式解释器使用方法

--PyCharm集成开发环境介绍

--算数操作符及表达式

-B 课程视频(变量及赋值)

--变量

--项目提交

--“我喜欢Python”热身小项目

-C 辅助视频(计算机结构、Python开发环境安装)

--Windows平台安装Python开发环境

--Mac平台安装Python开发环境

-D 辅助视频(如何提交项目)

--项目提交

-第0周--小测验

-本周项目:"我喜欢Python"

--项目发布、完成、提交及评分流程

--游戏说明

--程序说明

--编码步骤

--评分标准

--项目模板

--项目提交

第1周

-A 课程视频(函数)

--函数

--其它操作符

--随机函数

-B 课程视频(逻辑及表达式)

--逻辑值和比较

--条件

--编程技巧

--“老虎杠子鸡虫”游戏

-第1周--小测验

-本周项目:“老虎杠子鸡虫”游戏

--游戏说明

--程序说明

--编码步骤

--评分标准

--项目模板

第2周

-A 课程视频(Python交互式应用)

--事件驱动编程

--事件可视化跟踪执行

--SimpleGUITk

--按钮

-B 课程视频(输入框、全局变量)

--输入框

--局部变量和全局变量

--编程技巧

--“猫咪藏在哪个房间”游戏

-第2周--小测验A

-第2周--小测验B

-本周项目:猫咪藏在哪个房间

--游戏说明

--程序说明

--编码步骤

--评分标准

--项目模板

第3周

-A 课程视频(画布绘图)

--画布和图形绘制

--字符串处理

--绘图和计时器可视化跟踪执行

--图片和音效

-B 课程视频(计时器)

--计时器

--交互式绘图

--“神奇时钟”游戏

--编程技巧

-第3周--小测验A

-第3周--小测验B

-本周项目:“神奇时钟”

--游戏说明

--程序说明

--编码步骤

--评分标准

--项目模板

第4周

-A 课程视频(列表)

--列表

--键盘输入

--列表及变化可视化跟踪执行

--碰撞和反射

-B 课程视频(键盘控制)

--速度控制

--运动

--编程技巧

--“桌上冰球”游戏

-第4周--小测验A

-第4周--小测验B

-本周项目:“桌上冰球”游戏

--游戏说明

--程序说明

--编码步骤

--评分标准

--项目模板

第5周

-A 课程视频(鼠标输入、列表进阶)

--鼠标输入

--Video

--Video

--Video

-B 课程视频(字典和图片)

--Video

--Video

--Video

--Video

-第5周--小测验A

-第5周--小测验B

-本周项目:“世界杯八强连连看”

--游戏说明

--程序说明

--编码步骤

--评分标准

--项目模板

第6周

-A 课程视频(类)

--面向对象编程(类和对象入门)

--面向对象编程(类和对象进阶)

--对象可视化跟踪执行

--华容道中的类

-B 课程视频(平铺图片)

--平铺图片

--理解对象

--编程技巧

--“华容道”游戏

-第6周--小测验A

-第6周--小测验B

-本周项目:“华容道”游戏

--游戏说明

--程序说明

--编码步骤

--评分标准

--项目模板

第7周

-A 课程视频(类进阶及文件操作)

--集合

--文件操作

--文字块类

--处理停止的文字块

-B 课程视频(游戏状态控制)

--游戏记分规则

--游戏结束的条件及处理

--编程技巧

--“决战三字经”游戏

-第7周--小测验A

-第7周--小测验B

-本周项目:决战三字经

--游戏说明

--程序说明

--编程步骤

--评分标准

--项目模板

第8周

-A、课程视屏(精灵集合)

--Video

--精灵类

--战士类

--编程技巧

-B、课程视屏(动画)

--精灵碰撞

--精灵动画

--编程技巧

--保卫家园游戏

-第8周--小测验

-本周项目:守卫家园

--游戏说明

--程序说明

--编程步骤

--评分标准

--项目模板

面向对象编程(类和对象进阶)笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。