python_day6_面向对象的介绍/构造函数/类变量和实例变量/析构函数/私有属性和私有方法/继承、多继承和继承实例/多态

python_面向对象的介绍/构造函数/类变量和实例变量/析构函数/私有属性和私有方法/继承、多继承和继承实例/多态

在这里得感谢,老师Alex金角大王(路飞学城IT)
Python(给兄弟们挂个🔗)

Alex,面向对象

python边写边更…

一、面向对象的介绍:

<1>背景:(什么是“编程范式”)

1)编程范式:
1.程序员用(特定语法)+(数据结构)+(算法),组成代码,告诉计算机如何工作;
2.一百万个人,有一百万个不同形式;久之,就都会形成了一种“套路”,即"编程范式"

2)优劣:
1.面向过程:top-dowm language,从上到下的编程,上下具有依赖性,维护性太差(一步改,上下都得改)
2.面向对象:有的一些步骤呢,具有相同的 “相同方法” ,可以用 “函数” 实现;维护性好了一点,比较面向过程,代码减少了
3.面向对象:用 “类” 和 “对象” 来创建各种模型,来实现对真实世界的描述1.维护和扩展性高,大大提高开发效率…可以使人更加理解你的代码逻辑

<2>class(类):
是具有 “相同属性”的对象的抽象;在类中定义了这些了这些对象“都具备的属性”和“共同方法”

<3>object(对象):
类实例化后的一种实例,实例化也叫“类的初始化化”,类在实例化之后,才可以被调用;一个类可以“实例化”多个对象,每个对象亦可以有不同属性

<4>封装:
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
(…这个很抽象,enenen…这么理解,上帝造了“人”,外部访问的就只能是“你这个人”,你的内脏、器官都看知道)

<5>继承:
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承

<6>多态:“一个接口,多种实现”
比如,你的老板让 “所有员工” 在九点钟开始工作, 他只要在九点钟的时候说:“开始工作”即可,而不需要对销售人员说:“开始销售工作”,对技术人员说:“开始技术工作”, 因为“员工”是一个抽象的事物, 只要是员工就可以开始工作,他知道这一点就行了。至于每个员工,当然会各司其职,做各自的工作

①、构造函数:

先来一个“cs”的面向对象实例:

#Author:Jony c
#!/usr/bin/env  python 
# -*- coding:utf-8 -*-
class Role():
    def __init__(self,name,role,weapon,life_value=100,money=15000):
        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')
r1.buy_gun("AWM")

1.什么是“构造函数”???…

  def __init__(self,name,role,weapon,life_value=100,money=15000):
        self.name = name #实例变量(“静态”属性),作用域就是 “实例”本身...
        self.role = role
        self.weapon = weapon
        self.life_value = life_value
        self.money = money

conclude:

“构造函数”(定义在类里),是在“实例化”一个对象时,相当于接收参数的函数;

!!!但是!!!,他与自变量赋值或者函数传参又不一样:
(如果按照函数/自变量,那样传参数,是这样…)
1.调用这个Role(“name”,“work”,“weapon”);
2.Role去开辟一个"内存空间",把这些值存起来,然后return给r1进行调用;

但是,并不是这样的…

构造函数的接收参数是这样的:
1.r1 = Role(“name”,‘role’,‘weapon’)
2.将 r1 / “name” / “role” / “weapon” ;都传给Role…其中的 r1 被self 接收
3.这样就在,def __init __(self,name,role,weapon)里面,直接操作
(把值都付给r1这个变量,放在内存空间存起来…)

self.name = name
self.role = role
self.weapon = weapon
self.life_value = life_value
self.money = money

2.功能实现:

(“恐怖份子,实现开枪功能”)

r1.got_shot()#Role.got_shot(self)

这些功能定义在“类”里,而实例化之后的那些"属性"定义在r1里

 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)

②、实例变量和“类”变量:

(1)实例变量、“静态属性” 和 “属性”:

  def __init__(self,name,role,weapon,life_value=100,money=15000):

enen…在实例化的时候,name,role,weapon,life_value…这些人物“属性”,被叫作"实例变量"、“静态属性”,这些也都是人物的基本属性…

(2)类方法、“动态属性”:

 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)

这些人物用来实现的“功能”,被叫作“动态属性”,也叫作“类方法”,其定义在类里面…

(3)类变量:

class Role():
    n = 100
    def __init__(self,name,role,weapon,life_value=100,money=15000):
        self.name = name
        self.role = role

其中这个n,就代表是类变量…下面有情况用来讨论:

1)对实例变量进行修改:

class Role(object):
    def __init__(self,name,work,money):
        self.name = name;
        self.work = work;
        self.money = money;

    def eat(self):
        print("% is eating...."%self.name)

man1 = Role("caixukun","rap and dancing",'2毛')
#有一天,kunkun发达了...
man1.money = "10块"
print(man1.money)

1.实例化的时候,(类的初始化)的时候,kunkun才挣2毛钱…
2.经过长时间的rap & dance之后,enen…被发掘了,能挣10块了…
3.输出结果呢,result:
10块(实例变量在外部进了修改)

2)实例变量 和 类变量:(那个优先???)
(下面kunkun给大家举个栗子…)

class Role(object):
    money = "100块"
    def __init__(self,name,work,money):
        self.name = name;
        self.work = work;
        self.money = money;

    def eat(self):
        print("% is eating...."%self.name)

man1 = Role("caiukun","rap and dancing",'2毛')
print(man1.money)

result:2毛
(kunkun一出生就有100块,kunkun说我不,我要自己打拼;然后自己打拼,挣了2毛…100块钱还没了)
1.也就是说,实力变量和类变量,都进行赋值,优先输出实例变量的赋的值…

3)对类变量进行修改:

#Author:Jony c
#!/usr/bin/env  python 
# -*- coding:utf-8 -*-
class Role(object):
    company = "lehua"
    def __init__(self,name,work,money):
        self.name = name;
        self.work = work;
        self.money = money;

    def eat(self):
        print("% is eating...."%self.name)

man1 = Role("caiukun","rap and dancing",'2毛')

#kunkun膨胀了,开始换公司里了...
man1.company = "Tencent"
#kunkun runing IT 去了...

print(man1.company)

result:Tencent
(kunkun刚开始在lehua深造,后面膨胀了,去Tencent敲代码了…)
1.输出结果为Tencent;
2.你可以理解为“修改”了类变量,(我的理解是又变了个法的搞了一个“实例变量”,实例变量优先)

enen…到底是哪种理解更好呢???…我们再实例化一个man2就行了

3.在实例化man2,“那个男人”(enen…乔治一代)

man2 = Role("qiaozhiyidai",'rap','3毛')

不修改man2的company…

#Author:Jony c
#!/usr/bin/env  python 
# -*- coding:utf-8 -*-
class Role(object):
    company = "lehua"
    def __init__(self,name,work,money):
        self.name = name;
        self.work = work;
        self.money = money;

    def eat(self):
        print("% is eating...."%self.name)

man1 = Role("caiukun","rap and dancing",'2毛')
man2 = Role("qiaozhiyidai",'rap','3毛')
#kunkun膨胀了,开始换公司里了...
man1.company = "Tencent"
#kunkun runing IT 去了...

print(man1.company)
#那个男人,嗯...懂的都懂...
print(man2.company)

result:Tencent
lehua

(也就是说,类变量没被改…上面的那种我的理解起来稍微能更通顺一点…)

4)来看一种,可以改“类变量”的方法
(没有忘记局部变量的兄弟们,应该记得,局部变量也是可以在外部访问的时候改)
1.类变量,我把它定义为空列表

class Role(object):
    member = []
#Author:Jony c
#!/usr/bin/env  python
# -*- coding:utf-8 -*-
class Role(object):
    member = []
    def __init__(self,name,work,money):
        self.name = name;
        self.work = work;
        self.money = money;

    def eat(self):
        print("% is eating...."%self.name)

man1 = Role("caiukun","rap and dancing",'2毛')
man2 = Role("caiukun的亲戚","rap and dancing",'没钱')
man1.member.append(man1)
man2.member.append(man2)
print(man1.member[0].name)
print(man1.member[1].name)

result:caiukun
caiukun的亲戚

conclude:
实例变量 可以改 / 优先实例变量 / 字符串改不了 / 列表可以改

③、析构函数:(收尾工作,“接盘侠”/狗头)

1.class里面,我加一个析构函数:
(60年以后,kunkun和他家亲戚双双退休了…)

 def __del__(self):
        print("60years have gone...%s退休了"%self.name)

result:60years have gone…caiukun退休了
60years have gone…caiukun的亲戚退休了
可以看到,析构函数是当"所有程序"(man1,man2)的都跑完了,才执行的“收尾工作”;enen…在这提一嘴“内存回收机制”
“内存回收机制”:
1.当程序运行完,Python把不用的变量,都会回收(上面属于这一种)
2.你自己把“门牌号”去删了,python就把内存回收了…(下面跑一下这种…)

#Author:Jony c
#!/usr/bin/env  python
# -*- coding:utf-8 -*-
class Role(object):
    member = []
    def __init__(self,name,work,money):
        self.name = name;
        self.work = work;
        self.money = money;

    def eat(self):
        print("%s is eating...."%self.name)

    def __del__(self):
       print("60years have gone...%s退休了"%self.name)

man1 = Role("caiukun","rap and dancing",'2毛')
man2 = Role("caiukun的亲戚","rap and dancing",'没钱')
man1.eat()#Role.eat(man1)
del man1
man2.eat()#Role.eat(man2)

result:caiukun is eating…
60years have gone…caiukun退休了
caiukun的亲戚 is eating…
60years have gone…caiukun的亲戚退休了

④、私有属性 & 私有方法:

(外部访问不了你的“属性” / “方法”)

1.私有属性:(_ _money…kunkun这挣个2毛的,不好意思告诉人家)

def __init__(self,name,work,money):
        self.name = name;
        self.work = work;
        self.__money = money;#一个月挣多少钱,我不想告诉你
print(man1.__money)

result:报错,甚至都没有 “.” 调用这个方法…

那到底要怎么去调用???..解决:外边调用不了就在内部调用…

在class内部,写一个函数:(专门调用这个__money)

   def diaoyong(self):
        print(self.__money)
man1.diaoyong()

result:2毛

私用方法同上…
(附上自己写的简单代码,可以试一下…)

#Author:Jony c
#!/usr/bin/env  python
# -*- coding:utf-8 -*-
class Role(object):
    member = []
    def __init__(self,name,work,money):
        self.name = name;
        self.work = work;
        self.__money = money;#一个月挣多少钱,我不想告诉你

    def diaoyong(self):
        print(self.__money)

    def eat(self):
        print("%s is eating...."%self.name)



man1 = Role("caiukun","rap and dancing",'2毛')
man2 = Role("caiukun的亲戚","rap and dancing",'没钱')

man1.diaoyong()

二、面向对象的“特性”:

(封装、继承 和 多态 )

①、封装:

上面在介绍的时候已经实现了…就是外部访问的永远是man1、man2这个整体…数据都在里面(类里放的是“功能”、man放的“属性”)

②、继承:

[ “子类”继承“父类”的…“属性” & “功能”(类方法) ]

1)普通继承:

#Author:Jony c
#!/usr/bin/env  python
# -*- coding:utf-8 -*-
class people(object):
    def __init__(self,name,age,sex):
        self.name =name;
        self.age =age;
        self.sex =sex;

    def play(self):
        print("%s is playing...."%self.name)

class Man(people):#Man这个子类,继承了people这个父类的“属性”、“方法”
    def eat(self):#除了继承“父类”的play,自己又写了一个自己方法:“eat”
        print("%s is eating....."%self.name)


man1 =Man("chizi","25",'male')
man1.eat()#实现一下自己的
man1.play()#实现一下父类的

2)“重构”方法:(父类 + 新功能)

#Author:Jony c
#!/usr/bin/env  python
# -*- coding:utf-8 -*-
class people(object):
    def __init__(self,name,age,sex):
        self.name =name;
        self.age =age;
        self.sex =sex;

    def play(self):
        print("%s is playing...."%self.name)

class Man(people):
    def play(self):
        people.play(self)#重构了“父类” 的方法
        print("%s 想再玩1个小时"%self.name)#加上一个新功能


man1 =Man("chizi","25",'male')
man1.play()

result:
chizi is playing…
chizi 再玩1个小时

3)“重构”属性:(子类的“特殊”属性)(父类属性+自己独有的属性)

#Author:Jony c
#!/usr/bin/env  python
# -*- coding:utf-8 -*-
class people(object):
    def __init__(self,name,age,sex):
        self.name =name;
        self.age =age;
        self.sex =sex;

    def play(self):
        print("%s is playing...."%self.name)

class Man(people):
    def __init__(self,name,age,sex,money,weight):
        people.__init__(self,name,age,sex)#重构“属性”
        self.money = money ;
        self.weight =weight;


man1 =Man("chizi","25",'male',100,130)
print(man1.money)
print(man1.weight)

result:100
130

!!!但是我们一般不用这种…用下面这种

  #People.__init__(self,name,age)
  super(Man,self).__init__(name,age,sex)

4)“多继承”:(一次继承,2个“类”)

旧式继承:

class people()

新式继承:(object是一种“基类”)

class people(object)

1)"多继承"的一些“优先”:
[python 2.x 里面是“深度优先”(旧式类),“广度优先”(新式类);python 3.x 里面都是 “广度优先” ]

下图,如果是这样的一个“继承”:
在这里插入图片描述
这样一个优先顺序:1.先找自己的 2.再找B 3.再找C 4.再找“同排” 的
5.“同排” 的没有的话 6.再找 A …这样的“优先顺序”,被定义为“广度”优先

在这里插入图片描述
这样一个优先顺序:1.先找自己的 2.再找B 3.再找A 4.再找“C”…这样的“优先顺序”,被定义为“深度”优先
在这里插入图片描述
2)"多继承"的实例:

先定义两个“父类”:

class people(object):
    def __init__(self,name,age,sex):
        self.name =name;
        self.age =age;
        self.sex =sex;

    def play(self):
        print("%s is playing...."%self.name)
class relation(object):
   def fight(self,obj):
       print("%s is fighting with %s..."%(self.name,obj.name))

子类的Man,继承了people / relation,这两个父类

class Man(people,relation):
    def __init__(self,name,age,sex,money,weight):
        #people.__init__(self,name,age,sex)#重构“属性”
        super(Man,self).__init__(name,age,sex)
        self.money = money ;
        self.weight =weight;

man1 =Man("chizi","25",'male',100,130)#实例化
man2 =Man("lidan","35",'male',100000,150)#实例化
man1.fight(man2)#调用“父类”函数

result:
chizi is fighting with lidan…

3)"多继承"的实例之“学校”:

__author__ = "Alex Li"

class School(object):
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr
        self.students =[]
        self.staffs =[]
    def enroll(self,stu_obj):
        print("为学员%s 办理注册手续"%stu_obj.name )
        self.students.append(stu_obj)
    def hire(self,staff_obj):
        self.staffs.append(staff_obj)
        print("雇佣新员工%s" % staff_obj.name)

class SchoolMember(object):
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def tell(self):
        pass

class Teacher(SchoolMember):
    def __init__(self,name,age,sex,salary,course):
        super(Teacher,self).__init__(name,age,sex)
        self.salary = salary
        self.course = course
    def tell(self):
        print('''
        ---- info of Teacher:%s ----
        Name:%s
        Age:%s
        Sex:%s
        Salary:%s
        Course:%s
        '''%(self.name,self.name,self.age,self.sex,self.salary,self.course))

    def teach(self):
        print("%s is teaching course [%s]" %(self.name,self.course))

class Student(SchoolMember):
    def __init__(self,name,age,sex,stu_id,grade):
        super(Student,self).__init__(name,age,sex)
        self.stu_id = stu_id
        self.grade = grade
    def tell(self):
        print('''
        ---- info of Student:%s ----
        Name:%s
        Age:%s
        Sex:%s
        Stu_id:%s
        Grade:%s
        ''' % (self.name, self.name, self.age, self.sex, self.stu_id, self.grade))
    def pay_tuition(self,amount):
        print("%s has paid tution for $%s"% (self.name,amount) )


school = School("老男孩IT","沙河")

t1 = Teacher("Oldboy",56,"MF",200000,"Linux")
t2 = Teacher("Alex",22,"M",3000,"PythonDevOps")

s1 = Student("ChenRonghua",36,"MF",1001,"PythonDevOps")
s2 = Student("徐良伟",19,"M",1002,"Linux")


t1.tell()
s1.tell()
school.hire(t1)# school >>> 调的函数 >>> 都存在 "school.students[]"里面
school.enroll(s1)
school.enroll(s2)

print(school.students)#school = School("老男孩IT","沙河")
print(school.staffs)#school = School("老男孩IT","沙河")
school.staffs[0].teach()

for stu in school.students:
    stu.pay_tuition(5000)#调的 student 的 函数功能

③、多态:(“一个接口,多种实现”)

1.先来一个“父类”:

class people(object):
    def __init__(self,name,age,sex):
        self.name= name;
        self.age= age;
        self.sex= sex;

2.定义2个“子类”:

class teacher(people):
    def work(self):
        print("%s is teaching..."%self.name)

class student(people):
    def work(self):
        print("%s is studing..."%self.name)

3.实例化2个“对象”:

man1 = teacher("daxiong",'25','man')
man2 = student("panghu",'22','man')
man1.work()
man2.work()

result:daxiong is teaching…
panghu is studing…

你会发现这样实际是一个“功能”(work),调用了2次

就这样加一个“函数”,实现“一个接口,多种实现”

def working(obj):
    obj.work()
man1 = teacher("daxiong",'25','man')
man2 = student("panghu",'22','man')
working(man1)
working(man2)

4.多态的实现:

(加个装饰器的语法糖…把定义好的函数加进去)

class people(object):
    def __init__(self,name,age,sex):
        self.name= name;
        self.age= age;
        self.sex= sex;

    @staticmethod
    def working(obj):
        obj.work()

调用方式改变为:

man1 = teacher("daxiong",'25','man')
man2 = student("panghu",'22','man')
people.working(man1)
people.working(man2)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值