python面向对象
简介
面向对象,是很多高级语言的一种特性,与之相对的是的面向过程的语言,比如c 。网上有很多大牛对这块做详解,我这个小白就不阐述了。
面向对象涉及方面
既然要使用面向对象,首先我们要知道面向对象写法涉及哪些内容,要学习哪些概念,具体有以下几种
- 类(class):用来定义类的,也是描述具有相同属性和方法的对象的集合,它定了该集合中每个对象所共有的属性和方法,对象是类的实例
- 类变量:类变量在整个实例化的对象中是公用的,类变量定义在类中且在函数体之外,类变量通常不作为实例变量使用
- 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据
- 方法重写:定义在方法中的变量,只作用于当前实例的类
- 继承:即一个派生类,继承基类的字段和方法,继承也允许把一个派生类的对象作为一个基类对象对待,例如:有一个设计,一个dog类型的对象派生自any类,那么dog也是any类
- 实例化:创建一个类的实例,类的具体对象,就是我们写完一个类时,它是虚拟的,不存在的,只有当我们用这个类去定义一个变量时(实例)才能进行使用。
- 方法:类中定义的函数
- 对象:通过类定义的数据结构实例,对象包括连个数据成员(类变量和实例变量)和方法
简单类的定义
""" 类的定义 """ class human(): # 这是一个表示人的类 """ 这是一个表示人的类,那么它里面就应该有人能做的各种操作 """ def sj(self): # self为必填项,每个方法都要填的,不填就会报错 print("这个人能够睡觉") def cf(self): print("这个人能够吃法") def pb(self): print("这个人能跑步") join = human() # 这里我用表示人的类定义了一个叫join的人 join.sj() # join可以睡觉 join.pb() # join可以跑步 join.cf() # join可以吃饭
类的构造
""" 类的定义 """ class human(): # 这是一个表示人的类 """ 这是一个表示人的类,那么它里面就应该有人能做的各种操作 """ def __init__(self,name,sex,age): # 这是一个语法,构造函数,用来生成这个类的基本属性 self.name = name self.sex = sex self.age = age """ 这里的self.age可以理解为这个类本身的基本属性,而右边的 age,没有意义,只是外面传来的一个数据,这里的写法可以想 象成我们给这个self(指这个类,可以想成一个人)给了一个名字 ,然后又给了姓名,最后给了年龄 """ def agee(self): print(self.age) cheney = human("cheney","男",14) # 给这个对象进行初始化 cheney.agee() # 打印出这个人的年龄
简单练习
练习一:游戏人生程序
1、创建三个游戏人物,分别是:
- 苍井井,女,18,初始战斗力1000
- 东尼木木,男,20,初始战斗力1800
- 波多多,女,19,初始战斗力2500
2、游戏场景,分别:
- 草丛战斗,消耗200战斗力
- 自我修炼,增长100战斗力
- 多人游戏,消耗500战斗力
class human(): def __init__(self,name,sex,age,sword): self.name = name self.sex = sex self.age = age self.sword = sword def hassock(self): """草丛战斗,消耗200战力""" self.sword = self.sword - 200 print("{}进行了草丛战斗,减少200战力".format(self.name)) def practice(self): """自我修炼,增长100战力""" self.sword = self.sword + 100 print("{}进行了自我修炼,增加了100战力".format(self.name)) def playgame(self): """多人游戏,消耗200战力""" self.sword = self.sword - 500 print("{}进行了多人游戏,减少了500战力".format(self.name)) def show(self): """详情显示""" print("姓名:{}".format(self.name)) print("性别:{}".format(self.sex)) print("年龄:{}".format(self.age)) print("战力:{}".format(self.sword)) A = human('苍井井','女',18,1000) B = human('东尼木木','男',20,1800) C = human('波多多','女',19,2500) A.playgame() A.practice() A.show() B.hassock() B.show() C.playgame() C.show()
类的继承(子类与父类)
class AI1(): # 这个是父类,没有这个型号的AI就没有其他型号的AI """ 因为这里AI1是其他AI的最基础的一代,所以它会的只有这两项,但同时 其他AI都是此基础的加强,所以都继承了这一代AI的所有特性,并向这不 同方向在发展,AI2是家用型,AI3是侦察兵,这里的self.name是其他型 号调用才能进行显示,因为第一代AI没有给出构造的名字,所有没有名字 显示,如果构造进行打印,这里会出错。 """ def boxing(self): print("{}会拳击".format(self.name)) def grapple(self): print("{}会格斗".format(self.name)) class AI2(AI1): # 子类 def __init__(self,name): self.name = name def rice(self): print("{}会做饭".format(self.name)) def smart(self): print("{}有点帅".format(self.name)) class AI3(AI1): # 子类 def __init__(self,name): self.name = name def spy(self): print("{}会侦查".format(self.name)) def hide(self): print("{}会隐藏".format(self.name)) def spear(self): print("{}会枪械".format(self.name)) A = AI2("T-200") B = AI3("T-500") # C = AI1() # C.boxing() 这里是错误的写法 A.rice() A.boxing() A.grapple() B.boxing() B.grapple() B.spear()
多继承
上面我们学习了单继承
那么问题来了,多继承呢?
- 是否可以继承多个类?
- 如果继承的多个类每个类中都定了相同的函数,那么哪一个会被使用呢?
1、Python的类可以继承多个类,java和c#中则只能继承一个类
2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
深度优先:在A中如果我们要寻找test()这个函数,那么它的查询规则则是,先从A中查询有没有,再从B中查询有没有,然后在D中查询有没有,最后在C中查询有没有
广度优先:在下图中可以直观的看到是以层级展开查找的,如果A后面还有子类E,那么第4个查找就是这个E
- 当类是经典类时,多继承的情况下,会按照深度优先方式查找
- 当类是新式类时,多继承情况下,会按照广度优先方式查找
经典类和新式类,从字面上可以看出一个老一个新,新的必然包括了更多的功能,也是之后推荐的写法,从写法上区分的话,如果当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类
深度优先(经典):当调用A类test函数时,如下图所示,先查找A类中有无test函数,再查找B类,再查找D类,最后查找C类。
class D(): def test(self): print("D") class C(D): def test(self): print("C") class B(D): def test(self): print("B") class A(B,C): def test(self): print("A") a=A() a.test()
广度优先(新式):当调用A类test函数时,如下图所示,先查找A类有无test函数,再查找B类,再查找C类,最后查找D类。
区别:深度优先和广度优先只是查找的顺序变了
- Python2中带object的叫经典类,不带object的叫新式类,但是在Python3中取消了这一特性,所有的类默认为新式类
- 加了object有很多好处,平时写程序时,如果你使用的是Python2,不妨加上object,养成好习惯
多态
class human(): def __init__(self,name,sex): self.name = name self.sex = sex def show(self): print("姓名:{}".format(self.name)) print("性别:{}".format(self.sex)) class person(human): def show(self): print("性别:{}".format(self.sex)) print("姓名:{}".format(self.name)) AI = person("cheney",'男') AI.show()
多态的好处是,当我们传入更多的子类时,我们只需要继承human就行,而show函数可以重写,也可以不重写,也可以重写一个特有的,这就是多态,调用方只管调用,不管细节,而我们新增一个human子类时,只要确保新方法编写正确,而不用管原来的代码,这就是著名的“开闭原则”:
- 对扩展开发:允许子类重写方法函数
- 对修改封闭:不重写,直接继承父类方法函数
总结
- 以上就是全部我对于Python面向对象的理解,总结如下:
- 面向对象是另一种编程思想,相对于面向过程的编程思想,它更灵活多变,具体要把我类和对象的概念,就是把抽象的东西具体化
- 类中的所有事物都是以方法函数的形式存活,不像过程那样先做什么后做什么,类就是一个实例,就是一个物体,里面的所有方法,都是它的属性和可以做的事情
- 面向对象有三大特征:封装,集成和多态