python学习笔记六 初识面向对象上(基础篇)
- 写重复代码是非常不好的低级行为
- 你写的代码需要经常变更
#定义一个字典, 所有的角色的变量名都是一样的,但调用的时候又能区分开分别是谁。 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]) #Jackdef shot(by_who):#开了枪后要减子弹数pass def got_shot(who):#中枪后要减血who[‘life_value’] -= 10pass def buy_gun(who,gun_name):#检查钱够不够,买了枪后要扣钱pass
继续按照这个思路设计,再完善一下代码,游戏的简单版就出来了,但是在往下走之前,我们来看看上面的这种代码写法有没有问题,至少从上面的代码设计中,我看到以下几点缺陷: 1.无法确保新添加角色时,他们的属性定义是否正确。 比如 weapon 拼写错误程序无法检测;2.角色间无法区分不同的功能 警察和匪徒有不同的功能用函数式编写大家都可以调用,无法区分;3.添加新的属性都要添加一遍 假设要新添加防弹衣功能,需要在字典中每个角色都要添加;4.每个功能使用相同属性都要重新传入一遍 buy_gun,got_shot每次调用都要传入name;5.我们在上面定义了got_shot()后要减血,也就是说减血这个动作是应该通过被击中这个事件来引起的,但其实我不通过got_shot(),直接调用角色roles[role_id][‘life_value’] 减血也可以.
使用面向对象实现:
class Role(object):def __init__(self,name,role,weapon,life_value=100,money=15000):self.name = nameself.role = roleself.weapon = weaponself.life_value = life_valueself.money = moneydef 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’) #生成一个角色
- 代码量少了近一半
- 角色和它所具有的功能可以一目了然看出来
面向对象三大特性
类在实例化 (把一个抽象的类变成一个具体的对象的过程叫做实例化 )对象的时候,会执行初始化方法。 class person(object):def __init__(self,name,age):self.name = nameself.age = ageobj1 = person('koka',24) <=> person.__init__(obj1,'koka',24) 解析: 你执行obj1 = person('koka',24)时,python的解释器其实干了两件事:1.在内存中开辟一块空间指向obj1这个变量名2.调用person这个类并执行其中的__init__(…)方法,相当于person.__init__(obj1,'koka',24),这么做是为什么呢?是为了把'koka',24这2个值跟刚开辟的obj1关联起来,因为关联起来后,你就可以直接obj1.name, obj1.age 这样来调用啦。所以,为实现这种关联,在调用__init__方法时,就必须把obj1这个变量也传进去,否则__init__不知道要把那2个参数跟谁关联呀。所以这个__init__(…)方法里的,self.name = name , self.role = role 等等的意思就是要把这几个值存到obj1的内存空间里。
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。
例如:
猫可以:喵喵叫、吃、喝、拉、撒
狗可以:汪汪叫、吃、喝、拉、撒
如果我们要分别为猫和狗创建一个类,那么就需要为 猫 和 狗 实现他们所有的功能,如下所示:
class 猫:def 喵喵叫(self):print '喵喵叫'def 吃(self):# do somethingdef 喝(self):# do somethingdef 拉(self):# do somethingdef 撒(self):# do somethingclass 狗:def 汪汪叫(self):print '喵喵叫'def 吃(self):# do somethingdef 喝(self):# do somethingdef 拉(self):# do somethingdef 撒(self):# do something伪代码
伪代码
上述代码不难看出,吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。如果使用 继承 的思想,如下实现:
动物:吃、喝、拉、撒
猫:喵喵叫(猫继承动物的功能)
狗:汪汪叫(狗继承动物的功能)
class 动物:def 吃(self):# do somethingdef 喝(self):# do somethingdef 拉(self):# do somethingdef 撒(self):# do something# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类 class 猫(动物):def 喵喵叫(self):print '喵喵叫'# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类 class 狗(动物):def 汪汪叫(self):print '喵喵叫'伪代码
伪代码
class Animal:def eat(self):print "%s 吃 " %self.namedef drink(self):print "%s 喝 " %self.namedef shit(self):print "%s 拉 " %self.namedef pee(self):print "%s 撒 " %self.nameclass Cat(Animal):def __init__(self, name):self.name = nameself.breed = '猫'def cry(self):print '喵喵叫'class Dog(Animal):def __init__(self, name):self.name = nameself.breed = '狗'def cry(self):print '汪汪叫'# ######### 执行 #########c1 = Cat('小白家的小黑猫') c1.eat()c2 = Cat('小黑的小白猫') c2.drink()d1 = Dog('胖子家的小瘦狗') d1.eat()
所以,对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。
注:除了子类和父类的称谓,你可能看到过 派生类 和 基类 ,他们与子类和父类只是叫法不同而已。
学习了继承的写法之后,我们用代码来是上述阿猫阿狗的功能:
class Animal:def eat(self):print "%s 吃 " %self.namedef drink(self):print "%s 喝 " %self.namedef shit(self):print "%s 拉 " %self.namedef pee(self):print "%s 撒 " %self.nameclass Cat(Animal):def __init__(self, name):self.name = nameself.breed = '猫'def cry(self):print '喵喵叫'class Dog(Animal):def __init__(self, name):self.name = nameself.breed = '狗'def cry(self):print '汪汪叫'# ######### 执行 #########c1 = Cat('小白家的小黑猫') c1.eat()c2 = Cat('小黑的小白猫') c2.drink()d1 = Dog('胖子家的小瘦狗') d1.eat()代码实例
继承实例
继承重写
class AddrBookEntry(object):'address book entry class'def __init__(self,nm,ph):self.name = nmself.ph = phprint("Created instance for:",self.name)def UpdatePhone(self,newph):self.ph = newphprint('Updated phone %s for:'%self.ph ,self.name)class EmplAddrBookEntry(AddrBookEntry):'Employee Address Book Entry class'def __init__(self,nm,ph,id,em): #重写initsuper(EmplAddrBookEntry,self).__init__(nm,ph) #继承父类的init#AddrBookEntry.__init__(self,nm,ph)self.empid = idself.email = emdef updateEmail(self,newem):self.email = newemprint('Updated e-mail address %s for:'%self.email,self.name)new = AddrBookEntry("koka",'10010') #父类生成实例 new.UpdatePhone("10000") #使用方法更新 newnew = EmplAddrBookEntry("akok","10086","001","wlgc.com") #子类生成实例 继承父类的nm,ph 重写id,em newnew.updateEmail("12345@qq.com") #子类实例使用自己的方法 newnew.UpdatePhone("10010") #子类实例继承使用父类方法
多重继承
import time class A(object):n = 'A'def f2(self):print("f2 from A")def f1(self):print("f1 from A") class B(A):n = 'B'def f1(self):print("f1 from B")#def f2(self):# print("f2 from B")class C(A):n = 'C'def f1(self):print("f1 from C")def f2(self):print("f2 from C")class D(B,C):n = 'D'def __del__(self):#会在程序结束后执行,释放内存print("deleting the ...")d = D() d.f1() #输出 f1 from B d.f2() #输出 f2 from C # 新式类:D -> B -> C -> A 广度查找(从左至右查找最近的) # 经典类: D-> B -> A 深度查找,在python3.0以后默认为广度查找
多态
实例:class Animal:def __init__(self, name): # Constructor of the classself.name = namedef talk(self): # Abstract method, defined by convention onlyraise NotImplementedError("Subclass must implement abstract method")class Cat(Animal):def talk(self):return 'Meow!'class Dog(Animal):def talk(self):return 'Woof! Woof!'animals = [Cat('Missy'),Dog('Lassie')]for animal in animals:print animal.name + ': ' + animal.talk()
"""def animal_talk(obj): print(obj.talk()) d = Dog("sanjiangyuan")c = Cat("sanjiangshui")animal_talk(c)animal_talk(d)"""
转载于:https://www.cnblogs.com/koka24/p/5211628.html
python学习笔记六 初识面向对象上(基础篇)相关推荐
- Java学习笔记 六、面向对象编程中级部分
Java学习笔记 六.面向对象编程中级部分 包 包的注意事项和使用细节 访问修饰符 访问修饰符的注意事项和使用细节 面向对象编程三大特征 封装 封装的实现步骤(三步) 继承 继承的细节问题 继承的本质 ...
- Python学习笔记六——画小猪佩奇
目录 Python学习笔记六--画小猪佩奇 画布 画笔 属性设置 操纵命令 运动命令 画笔控制命令 全局控制命令 其他命令 Python学习笔记六--画小猪佩奇 使用Python的turtle库可以绘 ...
- Python学习笔记(六)
1. IO编程 1.1 文件读写 1.2 StringIO和BytesIO 1.3 操作文件和目录 1.4 序列化 2. 进程和线程 2.1 多进程 2.2 多线程 2.3 ThreadLocal 2 ...
- Python学习笔记(五.数据分析 ——上)
系列文章持续更新中- 文章目录 前言 一.相关性分析 A.获取股票价格 a.获取日K线的股票价格 b.获取每分钟的股票价格 B. 合并股票价格 C.股票价格相关性分析 二.假设检验 三.方差分析 A. ...
- Python学习之旅(核心编程基础篇003运算符)
Python学习之旅 Python核心编程基础篇2020.12.18 一.算数运算符 二.比较运算符 三.赋值运算符 四.逻辑运算符 五.成员运算符 六.身份运算符 七.三目运算符 八.运算符优先级 ...
- 动力节点王鹤SpringBoot3学习笔记——第二章 掌握SpringBoot基础篇
目录 二.掌控SpringBoot基础篇 2.1 Spring Boot ? 2.1.1 与Spring关系 2.1.2 与SpringCloud关系 2.1.3 最新的Spring Boot3 新 ...
- Spring.NET学习笔记10——方法的注入(基础篇) Level 200
多数用户都会将容器中的大部分对象布署为singleton模式.当一个singleton对象需要和另一个singleton对象协作,或者一个非singleton对象需要和另一个非singleson对象协 ...
- Python学习笔记(六)Python基础_数据类型——字符串
文章目录 字符串 字符串输入 字符串拼接 字符串操作 字符串格式化 访问字符串中的值 字符串切片 字符串遍历 常用的字符串方法 字符串 字符串是 Python 中最常用的数据类型:一般以使用引号' ' ...
- Python小白学习笔记六 (面向对象 1 )
面向对象 Object Oriented 概述 面向过程 1.分析出解决问题的步骤,然后逐步实现. 例如:婚礼筹办 – 发请柬(选照片.措词.制作) – 宴席(场地.找厨师.准备桌椅餐具.计划菜品.购 ...
最新文章
- Scrum指南2020中文版发布/scrum中文网
- 计算机NLP注意力机制思想和实现原理讲的较清晰
- 【ACL 2020】腾讯AI Lab解读三大前沿方向及入选的20篇论文
- 应用内评分_游戏评分低,怎么办?
- we自动化po模式_Web自动化测试—PO设计模式(一)
- 让Windows控制台应用程序支持VT100---原理篇
- Nginx 负载均衡器(1+2)
- Servlet基本_オブジェクトのスコープ
- ext的另一个table布局的例子
- 牛客挑战赛47 A 一道GCD问题
- TableStore轻松实现轨迹管理与地理围栏
- 【转】linux命令:ifconfig命令
- 日均数据量千万级,MySQL、TiDB 两种存储方案的落地对比
- php百度地图地址解析失败,javascript - vue中使用百度地图 提示无法解析
- CSDN Androidclient开展(两):基于如何详细解释Java使用Jsoup爬行动物HTML数据
- 【sklearn第十四讲】决策树之分类篇
- linux怎么卸载软件 apt,linux安装和卸载软件:sudo apt-get install(remove)
- C++调用C#创建的COM组件
- 阿里java面试流程_阿里巴巴JAVA开发工程师面试经验
- Android系统启动流程
热门文章
- php返回json套数组_教你PHP怎么不用框架写优雅的中小网站
- dubbo 服务压测_Dubbo高性能网关--Flurry介绍
- python正则表达式匹配模式屠夫之桥_小甲鱼零基础入门Python学习视频+全套源码课件 Python视频教程 96讲...
- mybatis-generator一些注意点 2021-04-21
- eclipse git 取远程代码_IDEA中的Git操作,看这一篇就够了!
- 前n个正整数相乘的时间复杂度为_初一数学常考的21个知识点,掌握好,轻松110+!...
- 微博抽奖贴为什么到时间了不开奖_热搜第一!微博闹剧,锦鲤“信小呆”被这样处罚...
- vue-quill-editor富文本 回显数据样式失效
- linux动态可执行文件,Linux中ELF格式 可执行文件+动态链接器 的加载
- unity中链接字符串和变量显示_unity3d根据字符串读取属性.