巨蟒python全栈开发-第16天 核能来袭-初识面向对象
一.今日内容总览(上帝视角,大象自己进冰箱,控制时机)
#转换思想(从面向过程到面向对象)
1.初识面向对象
面向过程:
一切以事物的发展流程为中心.
面向对象:
一切以对象为中心,一切皆为对象,具体的某一个事务就是对象
作用:两者(面向过程&面向对象)是相辅相成的作用
打比方:(开车去新疆)
大象进冰箱
步骤:1.开门,2.装大象,3.关门
面向对象:大象,你进冰箱
此时主语是大象,我操纵的就是大象,此时的大象就是对象
2.类,对象
(1)类:就是图纸,创建对象的第一步,先画图纸,先写类
对象:对象就是车,通过图纸造出来的具体的东西,通过类来创建对象
(2)类与对象的关系:
A.类是对xxx事物的抽象归类.
写:
__init__(self,参数) 参数一般作为属性设置给对象,对象就是self,对属性的封装
def 方法(self,参数):#方法:第一个参数默认是self,当前类的对象,一般也不起其他的
pass
B.对象是xxx类型的一个具体.
创建对象: 类名()
(3)创建类:(最实际的东西)
class 类名:
def __init__(self): #初始化方法,又被称为构造方法(这里暂时这样记忆)
self.属性=值
self.属性=值
self.属性=值
def fangfa(self):
方法体(函数体,return)
(4)创建对象:
变量=类名() #实例化<=>创建对象
变量.属性 #访问对象的属性信息
变量.方法() #访问类中的方法
3.面向对象和面向过程的对比
如果写一些比较小的程序用面向过程.
程序很复杂,很庞大建议用面向对象.
(前面的东西都是基础,基础就是铺垫,但是那才是核心,现在是进一步升华)
4.面向对象的三大特征
(1)封装
1.对属性的封装(__init__())
self.xxx=xxx
2.对方法和功能的封装
(2)继承
子类自动拥有父类中出了私有内容外的其他所有内容
class Bar(Foo): #Bar对Foo进行了扩展
pass
当出现x是一种y的时候,推荐使用继承关系
python支持多继承,查找顺序:先找离他近的.(就近原则)
(3)多态(python原生直接就是多态)
鸭子模型:python(其他很多语言也是)更多的支持的是鸭子模型,只要会嘎嘎叫的就是鸭子
二.今日内容大纲
1.类与对象
2.面向对象和面向过程
3.封装
4.继承
5.多态
三.今日内容详解
1.类与对象
(1)
class Car: #好习惯类名首字母大写,严格遵守驼峰命名规范 pass #造车 c=Car() #类名() #创建对象 #出厂之后进行改装 c.color='红颜色' #对象.属性 点:的 c.pai='京A888' #对象.属性 c.pailiang='666L' #排量 print(c.color) #红颜色 print(c.pai) #京A888 print(c.pailiang) #666L c.color='绿颜色' #当属性存在的时候是修改属性信息 #对象.属性=xxxx 设置属性信息 print(c.color) #绿颜色 # 对比: dic={} dic['jay']='周杰伦' print(dic) dic['jay']='alex' print(dic) #对象其实内部机制就是字典
(2)
class Car: #好习惯类名首字母大写,严格遵守驼峰命名规范 pass #造车 c=Car() #类名() #创建对象 #出厂之后进行改装 c.color='红颜色' #对象.属性 点:的 当属性不存在的时候,添加一个属性 c.pai='京A888' #对象.属性 c.pailiang='666L' #排量 c2=Car() c2.color='蓝色' c2.pai='京B66666' c2.pailiang='1.6T' c3=Car() c3.color='蓝色' c3.pai='上A99999' c3.pailiang='3.0L'
(3)
class Car: #好习惯 类名首字母大写,严格遵守驼峰命名规范 #__init__方法是一个特殊的方法,初始化方法(暂时这么记忆,构造方法) #在创建对象的时候回自动的调用__init__() #self就是你创建出来的那个对象 def __init__(self,color,pai,pailiang): #init初始化方法,在创建对象的时候,默认执行这个函数 # print('我是init') #结果:我是init # print('self=',self) #结果:self= <__main__.Car object at 0x000001B82F177550> # self.color='红色' #在出厂的时候都是红色 self.color=color self.pai=pai self.pailiang=pailiang # c.color = "红色" # c=Car('红','鲁A111','3.0L') #创建Car类型对象,此时self参数不需要我们管 # print('C=',c) #结果:C= <__main__.Car object at 0x000001B82F177550> #总结:c和self是同一个对象 c=Car('红色','京A88888','555L') #创建Car类型对象,此时self参数不需要我们管 c2=Car('蓝色','京B66666','1.6T') print(c.color) print(c2.color) #self对应一块内存地址
(4)
#车需要跑:动作,功能=>函数 #在类中写的函数=>方法 class Car: #好习惯 类名首字母大写,严格遵守驼峰命名规范 def __init__(self,color,pai,pailiang): #init初始化方法,在创建对象的时候,默认执行这个函数 self.color=color self.pai=pai self.pailiang=pailiang # 跑: 动作, 功能 -> 函数 # 在类中写的函数 -> 方法 # self 当前类的对象. def pao(self): #self是自动传递的,不用管它 print('%s,我的车能跑'%self.color) def jump(self): print('%s,you jump,I jump'%self.color) c=Car('红色','京A88888','555L') #创建Car类型对象,此时self参数不需要我们管 c2=Car('蓝色','京B66666','1.6T') print(c.color) print(c2.color) c.pao() #车c跑 c2.pao() c.jump()
(5)
class Phone: def __init__(self,color,dianchi,num,price): self.color=color self.dianchi=dianchi self.num=num self.price=price def call(self,ren): print('使用我的%s颜色价格%s的电话打个%s'%(self.color,self.price,ren)) def play(self): print('电话可以打游戏') sj=Phone('黑色','5WmA','110','9w欧元') sj.call('嫂子') sj.play()
(6)练习1版本
(1) #创建一个武松,武松可以打老虎,杀嫂子,替天行道 class haohan(): def __init__(self,name,nickname): self.name=name self.nickname=nickname print('好汉%s,绰号%s'%(self.name,self.nickname)) def play(self,ren): print('%s 可以打老虎,杀嫂子,替天行道'%ren) hh=haohan('武松','行者') hh.play('武松') (2) #⽤⾯向对象的思维来模拟LOL⾥的盖伦上阵杀敌. class hero(): def __init__(self,name): self.name=name print('英雄是:%s'%(self.name)) def skill(self,Q,W,E,R): print("Q技能是%s,W技能是%s,E技能是%s,R技能是%s"%(Q,W,E,R)) # print("名字%s,Q技能是%s,W技能是%s,E技能是%s,R技能是%s"%(self,Q,W,E,R)) h=hero('盖伦') h.skill('快溜','转子','双倍打击','大保健') # hero.skill('盖伦','快溜','转子','双倍打击','大保健') # hero.skill('艾希','快溜','转子','双倍打击','大保健') (3)#编写和尚类. ⾃⼰⾃由发挥和尚有哪些属性和⽅法. class monk(): def __init__(self,name,home,fahao): self.name=name self.home=home self.fahao=fahao def action(self,ren): print('%s,吃狗肉,敲木鱼,念经,吃斋'%(ren)) m=monk('济公','灵隐寺','道济') m.action('济公') (4) #用面向对象的思维来完成用户登录 class user_login(): def __init__(self,name,pwd): self.name=name self.pwd=pwd def login(self): if self.name=='alex'and self.pwd=='ab': print('登录成功') else: print('登录失败') ul=user_login('alex','ab') ul.login()
2版本
#类就是对属性和动作的封装 ''' 1. 创建⼀个武松. 武松可以打老虎, 杀嫂⼦, 替天⾏道 2. ⽤⾯向对象的思维来模拟LOL⾥的盖伦上阵杀敌. 3. 编写和尚类. ⾃⼰⾃由发挥和尚有哪些属性和⽅法 4. ⽤⾯向对象的思维来完成⽤户登录. ''' #属性和方法 (1) class Person: #属性 def __init__(self,waihao,name,address): self.waihao=waihao self.name=name self.address=address #动作 def dalaohu(self): print("%s%s%s打老虎"%(self.waihao,self.name,self.address)) def shasaozi(self): print('这个人,喜欢杀嫂子') def titianxingdao(self): print('替天行道') ws=Person('行者','武松','景阳县') ws.dalaohu() ws.shasaozi() ws.shasaozi() ws.titianxingdao() (2) class Hero: def __init__(self,waihao,name,story): self.waihao=waihao self.name=name self.story=story def q(self): print('拎着宝剑嗷嗷跑') def w(self): print('护盾') def e(self): print('电风扇') def r(self): print('大保健') gw=Hero('德玛西亚之力','盖伦','500年前盖伦拿一个破棍子捅破玉皇大帝...') gw.w() gw.e() gw.q() gw.r() (3) class HeShang: def __init__(self, fh, name, miao): self.fahao = fh self.name = name self.miao = miao def nianjing(self): print("和尚会念经") def huayuan(self): print("和尚会化缘") lzs = HeShang("花和尚", "鲁智深", "梁山水庙") lzs.nianjing() lzs.huayuan() (4) #用户登录的问题,逻辑是活的 #我的版本:把所有的逻辑都写在类中 class User: def __init__(self,username,password): self.username=username self.password=password def login(self): uname=input('请输入你的用户名') upwd=input('请输入你的密码') if uname==self.username and upwd==self.password: print("登录成功") else: print("登录失败") u = User("alex", "123") u.login()
2.面向对象和面向过程
(1)
#大象装冰箱
# print('开门')
# print('装大象')
# print('关门')
(2)
#脚本,此时代码是最简单的,不需要构思整个程序的概况
(3)
函数式编程,比脚本麻烦,对功能有了'概况'
(4)
def kai(): print('开门') def zhuang(): print('装大象') def guan(): print('关门') kai() zhuang() guan()
第一回合
脚本胜
函数侧重的是功能
面向对象侧重的是:归类
(5)
PK2
# PK2!!!!!!!! #小猪佩奇,使用嘴巴嘟嘟技能攻击 超人 #小猪佩奇,使用嘴巴嘟嘟技能攻击 蝙蝠侠 #小猪佩奇,使用嘴巴嘟嘟技能攻击 蜘蛛侠 #面向过程:代码非常的冗余,尤其是参数 def fight_superman(name,jineng): print('%s使用%s攻击超人'%(name,jineng)) def fight_spiderman(name,jineng): print('%s使用%s攻击蜘蛛侠'%(name,jineng)) def fight_batman(name, jineng): print('%s使用%s攻击蝙蝠侠' % (name, jineng)) fight_superman('小猪佩奇','嘴巴嘟嘟') fight_spiderman('小猪佩奇','嘴巴嘟嘟') fight_batman('小猪佩奇','嘴巴嘟嘟') class Pig: def __init__(self,name,jineng): self.name=name self.jineng=jineng def fight_superman(self): print('%s使用%s攻击超人' % (self.name, self.jineng)) def fight_spiderman(self): print('%s使用%s攻击蜘蛛侠' % (self.name, self.jineng)) def fight_batman(self): print('%s使用%s攻击蝙蝠侠' % (self.name, self.jineng)) #不需要像原来一样传递一样的参数了 #面向对象的程序:结果相对清晰.缺点:代码量比原来大,上手太难 pg=Pig('小猪佩奇','嘴巴嘟嘟') pg.fight_batman() pg.fight_superman() pg.fight_spiderman() #学完之后,再学java才真正明白
(6)
#如果写一个定时任务,半夜12点,给老板发送财务报表(一张图) # def send_email(address,name,title,content): # print('发送邮件') # def send_chat(address,name,title,content): # print('发送短信') # def send_wechat(address,name,title,content): # print('发送微信') # def send_dd(address,name,title,content): # print('发送钉钉') # def send_oa(address,name,title,content): # print('发送OA') # send_dd() # send_email() # send_oa() # send_wechat() # send_chat() # # # class Messager: # def __init__(self,name,title,content): # self.name=name # self.title=title # self.content=content # # def send_email(address, name, title, content): # print('发送邮件') # # def send_wechat(address, name, title, content): # print('发送微信') # # def send_chat(address, name, title, content): # print('发送短信') # # def send_dd(address, name, title, content): # print('发送钉钉') # # def send_oa(address, name, title, content): # print('发送OA') #用面向对象就比面向过程稍微好一些 #可维护性比原来好 #python同时支持面向对象和面向过程: #面向过程:应用程序相对比较小,不需要大规模的设计 #面向对象:程序非常大,项目管理,维护成本很高,此时更适合用面向对象(结构) #tornado #java:纯面向对象 =>可以把一个微小项目,做成巨大项目
3.封装
1.对属性的封装
2.对功能的封装
3.模块 (在一个模块中封装了很多类)
4.包
(1)
class Student: #封装需要的就可以了 def __init__(self,num,name,clazz): self.num=num self.name=name self.clazz=clazz # print() stu=Student('10010','曹宝宝','三年级二班') #把多个信息(值),保存在一个对象里面 stu2=Student('10086','王迪','三年级一班') def kill_stu(s): #这是就是对属性进行封装 print('杀%s'%(s.name)) kill_stu(stu2)
(2)
class Game: def login(self): print('登录') def recharge(self): print('充钱') def uninstall(self): print('卸载')#冲多了就卸了 def zhaoduixiang(self): print('找对象') g=Game() #强行安装一个主语 g.recharge()
(3)
class Game1: def recharge(self): print("充钱") def uninstall(self): print("卸载") class Game2: def recharge(self): print("充钱") def uninstall(self): print("卸载") g = Game2() g.uninstall()
4.继承
子类自动拥有父类中除了私有内容外的其他所有内容
老婆不能继承,年龄不能继承(这些都属于'私有内容')
王思聪(熊猫tv)=>王健林(年龄)
getmoney 拿钱
继承的目的:对父类进行扩展
(1)
class Foo: def getMoney(self): print('拿钱') class Bar(Foo): pass b=Bar() b.getMoney() #此时调用的是父类中的方法 #当出现xxx是一种yyy类型的东西,可以使用继承关系 #猫是一种动物
(2)
class Animal: def dong(self): print('动物会动,雇佣') class Cat(Animal): #子类其实是对父类的一种扩展 def catchMouse(self): print('猫很皮,抓老鼠') c=Cat() c.dong() c.catchMouse() a=Animal() #父类的对象不能执行子类中的功能 a.dong() a.catchMouse() #父类不能对子类的方法操作,这句话会报错 #创建的是动物,动物不能执行抓老鼠
(3)
class Animal: def dong(self): print('动物会动,雇佣') class Cat(Animal): #子类其实是对父类的一种扩展 def dong(self): #子类中写了和父类一模一样的方法,这个叫方法的覆盖,重写 print('猫上蹿下跳') def catchMouse(self): print('猫很皮,抓老鼠') c=Cat() #创建的是猫 c.dong() #类中的方法的查询顺序,先找自己,然后再找父类
(4)
#python支持多继承 class Foo1: def getMoney(self): print('给钱,给你个大嘴巴子') class Foo2: def getMoney(self): print('给多点儿') def play(self): print('玩儿') class Bar(Foo1,Foo2): #离当前类最近的是亲爹,后面的是干爹 pass a=Bar() #就近原则,MRO的C3算法 a.getMoney() #Foo2里的
5.多态
多态性:同一个对象,多种形态
python支持的是鸭子类型,只要会嘎嘎叫的东西就是鸭子
(哪怕不是鸭子//哪怕是鸭子,不会叫,也不行,也不能叫鸭子)
为了程序能够正常执行,本来需要传递进来一只鸭子,但是我只需要传递一个会嘎嘎叫的东西就可以了
(1)归一化设计
class Animal(object): def chi(self): print('会吃') class GlodenMonkey(Animal): def chi(self): print('用手拿着吃,五花八门') class Tiger(Animal): def chi(self): print('老虎吃肉') class Elephant(Animal): def chi(self): print('大象吃香蕉') class qie(Animal): def chi(self): print('企鹅吃人民币') #以下代码是饲养员 #优点:超强的可扩展性.面向对象的核心就是多态 def wei_animal(ani): #传进来的东西要会吃就行 ani.chi() #动物园 t=Tiger() m=GlodenMonkey() e=Elephant() wei_animal(t) wei_animal(m) wei_animal(e)
a=188 def cul(n): print(n) #python中万事万物都是对象,object(对象) cul(a) cul('666')
作业:???(记得补充)