单页网站案例分析,深圳网站制作开发排名,盛成广告传媒做网站的,外贸网站 站长工具本节内容#xff1a;面向对象编程介绍为什么要用面向对象进行开发#xff1f;面向对象的特性#xff1a;封装、继承、多态类、方法、引子 你现在是一家游戏公司的开发人员#xff0c;现在需要你开发一款叫做人狗大战的游戏#xff0c;你就思考呀#xff0c;人狗作…本节内容 面向对象编程介绍 为什么要用面向对象进行开发 面向对象的特性封装、继承、多态 类、方法、 引子 你现在是一家游戏公司的开发人员现在需要你开发一款叫做人狗大战的游戏你就思考呀人狗作战那至少需要2个角色一个是人 一个是狗且人和狗都有不同的技能比如人拿棍打狗 狗可以咬人怎么描述这种不同的角色和他们的功能呢 你搜罗了自己掌握的所有技能写出了下面的代码来描述这两个角色 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def person(name,age,sex,job): data { name:name, age:age, sex:sex, job:job } return data def dog(name,dog_type): data { name:name, type:dog_type } return data 上面两个方法相当于造了两个模子游戏开始你得生成一个人和狗的实际对象吧怎么生成呢 1 2 3 4 5 d1 dog(李磊,京巴) p1 person(严帅,36,F,运维) p2 person(林海峰,27,F,Teacher) 两个角色对象生成了狗和人还有不同的功能呀狗会咬人人会打狗对不对? 怎么实现呢。。想到了 可以每个功能再写一个函数想执行哪个功能直接 调用 就可以了对不 1 2 3 4 5 6 def bark(d): print(dog %s:wang.wang..wang...%d[name]) def walk(p): print(person %s is walking... %p[name])brbr 1 2 3 d1 dog(李磊,京巴) p1 person(严帅,36,F,运维) p2 person(林海峰,27,F,Teacher) 1 walk(p1) bark(d1) 上面的功能实现的简直是完美 但是仔细玩耍一会你就不小心干了下面这件事 1 2 p1 person(严帅,36,F,运维) bark(p1) #把人的对象传给了狗的方法 事实 上这并没出错。很显然人是不能调用狗的功能的如何在代码级别实现这个限制呢 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 def person(name,age,sex,job): def walk(p): print(person %s is walking... % p[name]) data { name:name, age:age, sex:sex, job:job, walk:walk } return data def dog(name,dog_type): def bark(d): print(dog %s:wang.wang..wang...%d[name]) data { name:name, type:dog_type, bark:bark } return data 1 2 3 d1 dog(李磊,京巴) p1 person(严帅,36,F,运维) p2 person(林海峰,27,F,Teacher)brbr 1 d1[bark](p1) #把人的对象传给了狗的方法 你是如此的机智这样就实现了限制人只能用人自己的功能啦。 但我的哥不要高兴太早刚才你只是阻止了两个完全 不同的角色 之前的功能混用 但有没有可能 同一个种角色但有些属性是不同的呢 比如 大家都打过cs吧cs里有警察和恐怖份子但因为都 是人 所以你写一个角色叫 person(), 警察和恐怖份子都 可以 互相射击但警察不可以杀人质恐怖分子可以这怎么实现呢 你想了说想说简单只需要在杀人质的功能里加个判断如果是警察就不让杀不就ok了么。 没错 这虽然 解决了杀人质的问题但其实你会发现警察和恐怖分子的区别还有很多同时又有很多共性如果 在每个区别处都 单独做判断那得累死。 你想了想说 那就直接写2个角色吧 反正 这么多区别 我的哥 不能写两个角色呀因为他们还有很多共性 写两个不同的角色就代表 相同的功能 也要重写了是不是我的哥 。。。 好了 话题就给你点到这 再多说你的智商 也理解不了了 面向过程 VS 面向对象 编程范式 编程是 程序 员 用特定的语法数据结构算法组成的代码来告诉计算机如何执行任务的过程 一个程序是程序员为了得到一个任务结果而编写的一组指令的集合正所谓条条大路通罗马实现一个任务的方式有很多种不同的方式 对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别即为编程范式。 不同的编程范式本质上代表对各种类型的任务采取的不同的解决问题的思路 大多数语言只支持一种编程范式当然也有些语言可以同时支持多种编程范式。 两种最重要的编程范式分别是面向过程编程和面向对象编程。 面向过程编程(Procedural Programming)Procedural programming uses a list of instructions to tell the computer what to do step-by-step. 面向过程编程依赖 - 你猜到了- procedures一个procedure包含一组要被进行计算的步骤 面向过程又被称为top-down languages 就是程序从上到下一步步执行一步步从上到下从头到尾的解决问题 。基本设计思路就是程序一开始是要着手解决一个大的问题然后把一个大问题分解成很多个小问题或子过程这些子过程再执行的过程再继续分解直到小问题足够简单到可以在一个小步骤范围内解决。 举个典型的面向过程的例子 数据库备份 分三步连接数据库备份数据库测试备份文件可用性。 代码如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 def db_conn(): print(connecting db...) def db_backup(dbname): print(导出数据库...,dbname) print(将备份文件打包移至相应目录...) def db_backup_test(): print(将备份文件导入测试库看导入是否成功) def main(): db_conn() db_backup(my_db) db_backup_test() if __name__ __main__: main() 这样做的问题也是显而易见的就是如果你要对程序进行修改对你修改的那部分有依赖的各个部分你都也要跟着修改 举个例子如果程序开头你设置了一个变量值 为1 但如果其它子过程依赖这个值 为1的变量才能正常运行那如果你改了这个变量那这个子过程你也要修改假如又有一个其它子程序依赖这个子过程 那就会发生一连串的影响随着程序越来越大 这种编程方式的维护难度会越来越高。 所以我们一般认为 如果你只是写一些简单的脚本去做一些一次性任务用面向过程的方式是极好的但如果你要处理的任务是复杂的且需要不断迭代和维护 的 那还是用面向对象最方便了。 面向对象编程 OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单并且可以大大提高程序开发效率 另外基于面向对象的程序可以使它人更加容易理解你的代码逻辑从而使团队开发变得更从容。 面向对象的几个核心特性如下 Class 类一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性variables(data)、共同的方法 Object 对象 一个对象即是一个类的实例化后实例一个类必须经过实例化后方可在程序中调用一个类可以实例化多个对象每个对象亦可以有不同的属性就像人类是指所有人每个人是指具体的对象人与人之前有共性亦有不同 Encapsulation 封装在类中对数据的赋值、内部调用对外部用户是透明的这使类变成了一个胶囊或容器里面包含着类的数据和方法 Inheritance 继承一个类可以派生出子类在这个父类里定义的属性、方法自动被子类继承 Polymorphism 多态多态是面向对象的重要特性,简单点说:“一个接口多种实现”指一个基类中派生出了不同的子类且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现这就是同一种事物表现出的多种形态。编程其实就是一个将具体世界进行抽象化的过程多态就是抽象化的一种体现把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。对不同类的对象发出相同的消息将会有不同的行为。比如你的老板让所有员工在九点钟开始工作, 他只要在九点钟的时候说“开始工作”即可而不需要对销售人员说“开始销售工作”对技术人员说“开始技术工作”, 因为“员工”是一个抽象的事物, 只要是员工就可以开始工作他知道这一点就行了。至于每个员工当然会各司其职做各自的工作。多态允许将子类的对象当作父类的对象使用某父类型的引用指向其子类型的对象,调用的方法是该子类型的方法。这里引用和调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定 面向对象编程(Object-Oriented Programming )介绍 对于编程语言的初学者来讲OOP不是一个很容易理解的编程方式大家虽然都按老师讲的都知道OOP的三大特性是继承、封装、多态并且大家也都知道了如何定义类、方法等面向对象的常用语法但是一到真正写程序的时候还是很多人喜欢用函数式编程来写代码特别是初学者很容易陷入一个窘境就是“我知道面向对象我也会写类但我依然没发现在使用了面向对象后对我们的程序开发效率或其它方面带来什么好处因为我使用函数编程就可以减少重复代码并做到程序可扩展了为啥子还用面向对象”。 对于此我个人觉得原因应该还是因为你没有充分了解到面向对象能带来的好处今天我就写一篇关于面向对象的入门文章希望能帮大家更好的理解和使用面向对象编程。 无论用什么形式来编程我们都要明确记住以下原则 写重复代码是非常不好的低级行为你写的代码需要经常变更 开发正规的程序跟那种写个运行一次就扔了的小脚本一个很大不同就是你的代码总是需要不断的更改不是修改bug就是添加新功能等所以为了日后方便程序的修改及扩展你写的代码一定要遵循易读、易改的原则专业数据叫可读性好、易扩展。 如果你把一段同样的代码复制、粘贴到了程序的多个地方以实现在程序的各个地方调用 这个功能那日后你再对这个功能进行修改时就需要把程序里多个地方都改一遍这种写程序的方式是有问题的因为如果你不小心漏掉了一个地方没改那可能会导致整个程序的运行都 出问题。 因此我们知道 在开发中一定要努力避免写重复的代码否则就相当于给自己再挖坑。 还好函数的出现就能帮我们轻松的解决重复代码的问题对于需要重复调用的功能只需要把它写成一个函数然后在程序的各个地方直接调用这个函数名就好了并且当需要修改这个功能时只需改函数代码然后整个程序就都更新了。 其实OOP编程的主要作用也是使你的代码修改和扩展变的更容易那么小白要问了既然函数都能实现这个需求了还要OOP干毛线用呢 呵呵说这话就像古时候人们打仗杀人都用刀后来出来了枪它的主要功能跟刀一样也是杀人然后小白就问既然刀能杀人了那还要枪干毛线哈哈显而易见因为枪能更好更快更容易的杀人。函数编程与OOP的主要区别就是OOP可以使程序更加容易扩展和易更改。 小白说我读书少你别骗我口说无凭证明一下好吧那我们就下面的例子证明给小白看。 相信大家都打过CS游戏吧我们就自己开发一个简单版的CS来玩一玩。 暂不考虑开发场地等复杂的东西我们先从人物角色下手 角色很简单就俩个恐怖份子、警察他们除了角色不同其它基本都 一样每个人都有生命值、武器等。 咱们先用非OOP的方式写出游戏的基本角色 1 2 3 4 5 6 7 8 9 10 11 #role 1 name Alex role terrorist weapon AK47 life_value 100 #rolw 2 name2 Jack role2 police weapon2 B22 life_value2 100 上面定义了一个恐怖份子Alex和一个警察Jack,但只2个人不好玩呀一干就死了没意思那我们再分别一个恐怖分子和警察吧 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #role 1 name Alex role terrorist weapon AK47 life_value 100 money 10000 #rolw 2 name2 Jack role2 police weapon2 B22 life_value2 100 money2 10000 #role 3 name3 Rain role3 terrorist weapon3 C33 life_value3 100 money3 10000 #rolw 4 name4 Eric role4 police weapon4 B51 life_value4 100 money4 10000 4个角色虽然创建好了但是有个问题就是每创建一个角色我都要单独命名name1,name2,name3,name4…后面的调用的时候这个变量名你还都得记着要是再让多加几个角色估计调用时就很容易弄混啦所以我们想一想能否所有的角色的变量名都是一样的但调用的时候又能区分开分别是谁 当然可以我们只需要把上面的变量改成字典的格式就可以啦。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 roles { 1:{name:Alex, role:terrorist, weapon:AK47, life_value: 100, money: 15000, }, 2:{name:Jack, role:police, weapon:B22, life_value: 100, money: 15000, }, 3:{name:Rain, role:terrorist, weapon:C33, life_value: 100, money: 15000, }, 4:{name:Eirc, role:police, weapon:B51, life_value: 100, money: 15000, }, } print(roles[1]) #Alex print(roles[2]) #Jack 很好这个以后调用这些角色时只需要roles[1],roles[2]就可以啦角色的基本属性设计完了后我们接下来为每个角色开发以下几个功能 被打中后就会掉血的功能开枪功能换子弹买枪跑、走、跳、下蹲等动作保护人质仅适用于警察不能杀同伴。。。我们可以把每个功能写成一个函数类似如下 1 2 3 4 5 6 7 8 9 10 11 def shot(by_who): #开了枪后要减子弹数 pass def got_shot(who): #中枪后要减血 who[‘life_value’] - 10 pass def buy_gun(who,gun_name): #检查钱够不够,买了枪后要扣钱 pass ... so far so good, 继续按照这个思路设计再完善一下代码游戏的简单版就出来了但是在往下走之前我们来看看上面的这种代码写法有没有问题至少从上面的代码设计中我看到以下几点缺陷 每个角色定义的属性名称是一样的但这种命名规则是我们自己约定的从程序上来讲并没有进行属性合法性检测也就是说role 1定义的代表武器的属性是weapon, role 2 ,3,4也是一样的不过如果我在新增一个角色时不小心把weapon 写成了wepon , 这个程序本身是检测 不到的terrorist 和police这2个角色有些功能是不同的比如police是不能杀人质的但是terrorist可能随着这个游戏开发的更复杂我们会发现这2个角色后续有更多的不同之处 但现在的这种写法我们是没办法 把这2个角色适用的功能区分开来的也就是说每个角色都可以直接调用任意功能没有任何限制。我们在上面定义了got_shot()后要减血也就是说减血这个动作是应该通过被击中这个事件来引起的,我们调用get_shot()got_shot这个函数再调用每个角色里的life_value变量来减血。 但其实我不通过got_shot()直接调用角色roles[role_id][‘life_value’] 减血也可以呀但是如果这样调用的话那可以就是简单粗暴啦因为减血之前其它还应该判断此角色是否穿了防弹衣等如果穿了的话伤害值肯定要减少got_shot()函数里就做了这样的检测你这里直接绕过的话程序就乱了。 因此这里应该设计 成除了通过got_shot(),其它的方式是没有办法给角色减血的不过在上面的程序设计里是没有办法实现的。 现在需要给所有角色添加一个可以穿防弹衣的功能那很显然你得在每个角色里放一个属性来存储此角色是否穿 了防弹衣那就要更改每个角色的代码给添加一个新属性这样太low了不符合代码可复用的原则 上面这4点问题如果不解决以后肯定会引出更大的坑有同学说了解决也不复杂呀直接在每个功能调用时做一下角色判断啥就好了没错你要非得这么霸王硬上弓的搞也肯定是可以实现的那你自己就开发相应的代码来对上面提到的问题进行处理好啦。 但这些问题其实能过OOP就可以很简单的解决。 之前的代码改成用OOP中的“类”来实现的话如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Role(object): def __init__(self,name,role,weapon,life_value100,money15000): self.name name self.role role self.weapon weapon self.life_value life_value self.money money def shot(self): print(shooting...) def got_shot(self): print(ah...,I got shot...) def buy_gun(self,gun_name): print(just bought %s %gun_name) r1 Role(Alex,police,AK47’) #生成一个角色 r2 Role(Jack,terrorist,B22’) #生成一个角色 先不考虑语法细节相比靠函数拼凑出来的写法上面用面向对象中的类来写最直接的改进有以下2点 代码量少了近一半角色和它所具有的功能可以一目了然看出来 在真正开始分解上面代码含义之之前我们现来了解一些类的基本定义 类的语法 1 2 3 4 5 6 7 8 9 class Dog(object): print(hello,I am a dog!) d Dog() #实例化这个类 #此时的d就是类Dog的实例化对象 #实例化其实就是以Dog类为模版在内存里开辟一块空间存上数据赋值成一个变量名 上面的代码其实有问题想给狗起名字传不进去。 1 2 3 4 5 6 7 8 9 10 11 12 13 class Dog(object): def __init__(self,name,dog_type): self.name name self.type dog_type def sayhi(self): print(hello,I am a dog, my name is ,self.name) d Dog(LiChuang,京巴) d.sayhi() 为什么有__init__? 为什么有self? 此时的你一脸蒙逼相信不画个图你的智商是理解不了的 画图之前 你先注释掉这两句 1 2 3 4 # d Dog(LiChuang, 京巴) # d.sayhi() print(Dog) 没实例直接打印Dog输出如下 1 class __main__.Dog 这代表什么?代表 即使不实例化这个Dog类本身也是已经存在内存里的对不对 yes, cool那实例化时会产生什么化学反应呢 根据上图我们得知其实self,就是实例本身你实例化时python会自动把这个实例本身通过self参数传进去。 你说好吧假装懂了 但下面这段代码你又不明白了 为何sayhi(self),要写个self呢 1 2 3 4 5 class Dog(object): ... def sayhi(self): print(hello,I am a dog, my name is ,self.name) 这个原因我课上在讲。。。 1 brbrbrbr 好了明白 了类的基本定义接下来我们一起分解一下上面的代码分别 是什么意思 1 2 3 4 5 6 7 class Role(object): #定义一个类 class是定义类的语法Role是类名(object)是新式类的写法必须这样写以后再讲为什么 def __init__(self,name,role,weapon,life_value100,money15000): #初始化函数在生成一个角色时要初始化的一些属性就填写在这里 self.name name #__init__中的第一个参数self,和这里的self都 是什么意思 看下面解释 self.role role self.weapon weapon self.life_value life_value self.money money 上面的这个__init__()叫做初始化方法(或构造方法) 在类被调用时这个方法(虽然它是函数形式但在类中就不叫函数了,叫方法)会自动执行进行一些初始化的动作所以我们这里写的__init__(self,name,role,weapon,life_value100,money15000)就是要在创建一个角色时给它设置这些属性那么这第一个参数self是干毛用的呢 初始化一个角色就需要调用这个类一次 1 2 r1 Role(Alex,police,AK47’) #生成一个角色 , 会自动把参数传给Role下面的__init__(...)方法 r2 Role(Jack,terrorist,B22’) #生成一个角色 我们看到上面的创建角色时我们并没有给__init__传值程序也没未报错是因为类在调用它自己的__init__(…)时自己帮你给self参数赋值了 1 2 r1 Role(Alex,police,AK47’) #此时self 相当于 r1 , Role(r1,Alex,police,AK47’) r2 Role(Jack,terrorist,B22’)#此时self 相当于 r2, Role(r2,Jack,terrorist,B22’) 为什么这样子你拉着我说你有些犹豫怎么会这样子 你执行r1 Role(Alex,police,AK47’)时python的解释器其实干了两件事 在内存中开辟一块空间指向r1这个变量名调用Role这个类并执行其中的__init__(…)方法相当于Role.__init__(r1,Alex,police,’AK47’),这么做是为什么呢 是为了把Alex,police,’AK47’这3个值跟刚开辟的r1关联起来是为了把Alex,police,’AK47’这3个值跟刚开辟的r1关联起来是为了把Alex,police,’AK47’这3个值跟刚开辟的r1关联起来重要的事情说3次 因为关联起来后你就可以直接r1.name, r1.weapon 这样来调用啦。所以为实现这种关联在调用__init__方法时就必须把r1这个变量也传进去否则__init__不知道要把那3个参数跟谁关联呀。明白了么哥所以这个__init__(…)方法里的self.name name , self.role role 等等的意思就是要把这几个值 存到r1的内存空间里。如果还不明白的话哥去测试一下智商吧 应该不会超过70哈哈。 为了暴露自己的智商此时你假装懂了但又问 __init__(…)我懂了但后面的那几个函数噢 不对后面那几个方法 为什么也还需要self参数么 不是在初始化角色的时候 就已经把角色的属性跟r1绑定好了么 good question, 先来看一下上面类中的一个buy_gun的方法 1 2 def buy_gun(self,gun_name): print(“%s has just bought %s” %(self.name,gun_name) ) 上面这个方法通过类调用的话要写成如下 1 2 r1 Role(Alex,police,AK47) r1.buy_gun(B21”) #python 会自动帮你转成 Role.buy_gun(r1,”B21) 执行结果 #Alex has just bought B21 依然没给self传值 但Python还是会自动的帮你把r1 赋值给self这个参数 为什么呢 因为你在buy_gun(..)方法中可能要访问r1的一些其它属性呀 比如这里就访问 了r1的名字怎么访问呢你得告诉这个方法呀于是就把r1传给了这个self参数然后在buy_gun里调用 self.name 就相当于调用r1.name 啦如果还想知道r1的生命值 有多少直接写成self.life_value就可以了。 说白了就是在调用类中的一个方法时你得告诉人家你是谁。 好啦 总结一下2点 上面的这个r1 Role(Alex,police,AK47’)动作叫做类的“实例化” 就是把一个虚拟的抽象的类通过这个动作变成了一个具体的对象了 这个对象就叫做实例刚才定义的这个类体现了面向对象的第一个基本特性封装其实就是使用构造方法将内容封装到某个具体对象中然后通过对象直接或者self间接获取被封装的内容面向对象的特性 封装 封装最好理解了。封装是面向对象的特征之一是对象和类概念的主要特性。 封装也就是把客观事物封装成抽象的类并且类可以把自己的数据和方法只让可信的类或者对象操作对不可信的进行信息隐藏。 继承 面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力它可以使用现有类的所有功能并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”。 被继承的类称为“基类”、“父类”或“超类”。 继承的过程就是从一般到特殊的过程。 要实现继承可以通过“继承”Inheritance和“组合”Composition来实现。 在某些 OOP 语言中一个子类可以继承多个基类。但是一般情况下一个子类只能有一个基类要实现多重继承可以通过多级继承来实现。 继承概念的实现方式主要有2类实现继承、接口继承。 Ø 实现继承是指使用基类的属性和方法而无需额外编码的能力 Ø 接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法) 在考虑使用继承时有一点需要注意那就是两个类之间的关系应该是“属于”关系。例如Employee 是一个人Manager 也是一个人因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类因为腿并不是一个人。 抽象类仅定义将由子类创建的一般属性和方法。 OO开发范式大致为划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。 继承示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #!_*_coding:utf-8_*_ #__author__:Alex Li class SchoolMember(object): members 0 #初始学校人数为0 def __init__(self,name,age): self.name name self.age age def tell(self): pass def enroll(self): 注册 SchoolMember.members 1 print(\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m %(self.name,SchoolMember.members)) def __del__(self): 析构方法 print(\033[31;1mmember [%s] is dead!\033[0m %self.name) class Teacher(SchoolMember): def __init__(self,name,age,course,salary): super(Teacher,self).__init__(name,age) self.course course self.salary salary self.enroll() def teaching(self): 讲课方法 print(Teacher [%s] is teaching [%s] for class [%s] %(self.name,self.course,s12)) def tell(self): 自我介绍方法 msg Hi, my name is [%s], works for [%s] as a [%s] teacher ! %(self.name,Oldboy, self.course) print(msg) class Student(SchoolMember): def __init__(self, name,age,grade,sid): super(Student,self).__init__(name,age) self.grade grade self.sid sid self.enroll() def tell(self): 自我介绍方法 msg Hi, my name is [%s], Im studying [%s] in [%s]! %(self.name, self.grade,Oldboy) print(msg) if __name__ __main__: t1 Teacher(Alex,22,Python,20000) t2 Teacher(TengLan,29,Linux,3000) s1 Student(Qinghua, 24,Python S12,1483) s2 Student(SanJiang, 26,Python S12,1484) t1.teaching() t2.teaching() t1.tell() 多态 多态性polymorphisn是允许你将父对象设置成为和一个或更多的他的子对象相等的技术赋值之后父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说就是一句话允许将子类类型的指针赋值给父类类型的指针。 那么多态的作用是什么呢我们知道封装可以隐藏实现细节使得代码模块化继承可以扩展已存在的代码模块类它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用多态的作用就是为了类在继承和派生的时候保证使用“家谱”中任一类的实例的某一属性时的正确调用。 Pyhon 很多语法都是支持多态的比如 len(),sorted(), 你给len传字符串就返回字符串的长度传列表就返回列表长度。 Python多态示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #_*_coding:utf-8_*_ class Animal(object): def __init__(self, name): # Constructor of the class self.name name def talk(self): # Abstract method, defined by convention only raise NotImplementedError(Subclass must implement abstract method) class Cat(Animal): def talk(self): print(%s: 喵喵喵! %self.name) class Dog(Animal): def talk(self): print(%s: 汪汪汪 %self.name) def func(obj): #一个接口多种形态 obj.talk() c1 Cat(小晴) d1 Dog(李磊) func(c1) func(d1) 领域模型 好了你现在会了面向对象的各种语法了 那请看下本章最后的作业需求我相信你可能是蒙蔽的 很多同学都是学会了面向对象的语法却依然写不出面向对象的程序原因是什么呢原因就是因为你还没掌握一门面向对象设计利器 你说我读书少别骗我 什么利器 答案就是:领域建模。 从领域模型开始,我们就开始了面向对象的分析和设计过程,可以说,领域模型是完成从需求分析到面向 对象设计的一座桥梁。 领域模型,顾名思义,就是需求所涉及的领域的一个建模,更通俗的讲法是业务模型。 参考百度百科(http://baike.baidu.cn/view/757895.htm ),领域模型定义如下: 从这个定义我们可以看出,领域模型有两个主要的作用: 发掘重要的业务领域概念建立业务领域概念之间的关系 领域建模三字经 领域模型如此重要,很多同学可能会认为领域建模很复杂,需要很高的技巧。然而事实上领域建模非常简 单,简单得有点难以让人相信,领域建模的方法概括一下就是“找名词”! 许多同学看到这个方法后估计都会笑出来:太假了吧,这么简单,找个初中生都会啊,那我们公司那些分 析师和设计师还有什么用哦? 分析师和设计师当然有用,后面我们会看到,即使是简单的找名词这样的操作,也涉及到分析和提炼,而 不是简单的摘取出来就可,这种情况下分析师和设计师的经验和技能就能够派上用场了。但领域模型分析 也确实相对简单,即使没有丰富的经验和高超的技巧,至少也能完成一个能用的领域模型。 虽然我们说“找名词”很简单,但一个关键的问题还没有说明:从哪里找? 如果你还记得领域模型是“需求到面向对象的桥梁”,那么你肯定一下子就能想到:从需求模型中找,具 体来说就是从用例中找。 归纳一下域建模的方法就是“从用例中找名词”。 当然,找到名词后,为了能够更加符合面向对象的要求和特点,我们还需要对这些名词进一步完善,这就 是接下来的步骤:加属性,连关系! 最后我们总结出领域建模的三字经方法:找名词、加属性、连关系。 找名词 who : 学员、讲师、管理员 用例 1. 管理员 创建了 北京 和 上海 两个校区 2. 管理员 创建了 Linux \ Python \ Go 3个课程 3. 管理员 创建了 北京校区的Python 16期 Go开发第一期和上海校区的Linux 36期 班级 4. 管理员 创建了 北京校区的 学员 小晴 并将其 分配 在了 班级 python 16期 5. 管理员 创建了 讲师 Alex , 并将其分配 给了 班级 python 16期 和全栈脱产5期 6. 讲师 Alex 创建 了一条 python 16期的 上课纪录 Day6 7. 讲师 Alex 为Day6这节课 所有的学员 批了作业 小晴得了A, 李磊得了C-, 严帅得了B 8. 学员小晴 在 python 16 的 day6里 提交了作业 9. 学员李磊 查看了自己所报的所有课程 10 学员 李磊 在 查看了 自己在 py16期 的 成绩列表 然后自杀了 11. 学员小晴 跟 讲师 Alex 表白了 名词列表 管理员、校区、课程、班级、上课纪录、作业、成绩、讲师、学员 加属性 连关系 有了类,也有了属性,接下来自然就是找出它们的关系了。 本节作业: 选课系统 角色:学校、学员、课程、讲师要求:1. 创建北京、上海 2 所学校2. 创建linux , python , go 3个课程 linux\py 在北京开 go 在上海开3. 课程包含周期价格通过学校创建课程 4. 通过学校创建班级 班级关联课程、讲师5. 创建学员时选择学校关联班级5. 创建讲师角色时要关联学校 6. 提供两个角色接口6.1 学员视图 可以注册 交学费 选择班级6.2 讲师视图 讲师可管理自己的班级 上课时选择班级 查看班级学员列表 修改所管理的学员的成绩 6.3 管理视图创建讲师 创建班级创建课程 7. 上面的操作产生的数据都通过pickle序列化保存到文件里 转载于:https://www.cnblogs.com/linglingling/p/8931503.html