面向对象,是很多高级语言的一种特性,与之相对的是的面向过程的语言,比如c 。网上有很多大牛对这块做详解,我这个小白就不阐述了。
既然要使用面向对象,首先我们要知道面向对象写法涉及哪些内容,要学习哪些概念,具体有以下几种
""" 类的定义 """ 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、创建三个游戏人物,分别是:
2、游戏场景,分别:
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类。
区别:深度优先和广度优先只是查找的顺序变了
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子类时,只要确保新方法编写正确,而不用管原来的代码,这就是著名的“开闭原则”:
原文:https://www.cnblogs.com/cheneyboon/p/11839169.html