Python(二十三)类和对象

一、基本概念

Python目的:力求提供简单够用的语法功能,所以你会看到其面向对象比较简单,不像其他面向对象语言(Java等)提供了大量繁杂的面向对象的特征!

了解面向对象的程序设计语言的两个重要概念!

(0)辨析面向对象和面向过程

面向过程 面向对象(oop:object oriented programming)
面向过程:---侧重于怎么做?
1.把完成某一个需求的 所有步骤 从头到尾 逐步实现
2.根据开发要求,将某些功能独立的代码封装成一个又一个函数
3.最后完成的代码,就是顺序的调用不同的函数
特点:
    1.注重步骤和过程,不注重职责分工
    2.如果需求复杂,代码变得非常复杂
    3.开发复杂的项目的时候,没有固定的套路,开发难度很大
面向对象:----侧重于谁来做?
相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法
1.在完成某一个需求前,首先确定职责--要做的事(方法)
2.根据职责确定不同的对象,在对象内部封装不同的方法(多个)
3.最后完成代码,就是顺序的让不同的对象调用不同的方法
特点:
    1.注重对象和职责,不同的对象承担不同的职责
    2.更加适合对复杂的需求变化,是专门应对复杂项目的开发,提供固定的套路
    3.需要在面向过程的基础上,再学习一些面向对象的语法

面向过程--->侧重于怎么做?
面向对象--->测中于谁来做?

小结:

(1)类的概念

把握:严谨的定义和自定义理解!

:大概就是一些具有相同属性的对象的集合的抽象描述,可以理解某种概念

:是一类具有相同特征或行为的事物的一个统称!

(2)对象的概念

对象:按照类的模版创建的一个具体的实例(体)!

明确

         创建出来的对象叫做类的实例

         创建对象的动作(过程)叫做实例化

         类与对象是个性和共性的关系

(3)类的定义

     类名:是合法的标识符即可,满足大驼峰命名规范,类名由有意义的单词连缀组成,单词首字母大写,其余小写,单词之间没有任何的分割符号

说明:懒的画图,随手copy了一张!

备注:python3.x系列的版本会自动的继承超类object,即不需要手动的继承!

# ":"作为类体的开始,统一缩进的内容作为类体!
class LibraySystem(object):
    # pass语句作为占位符号
    pass

#说明:空类没有太大的意义!

类的作用:定义变量、创建对象、派生子类!

(3)类的成员

核心:变量和方法

修饰符扩展:类变量、实例变量、私有方法、类方法、实例方法、静态方法、类变量、私有变量、实例变量

常见的修饰符:@关键字、以双下划线开头、以双下划线结尾、以双下划线开头和结尾(python内置)的

说明:具体的表现形式后面讲解!

(4)对象的创建和方法的调用

class Person:
    '类定义说明文档,放在类声明之后,类体之前'
    # python的内置方法-->构造方法
    # 说明:如果没有自定义构造方法来初始化对象,则默认是只包含一个self参数的__init__函数
    # self参数:被绑定到构造方法的初始化"对象上"!
    def __init__(self, name):
        self.name = name
        print('%s被创建' %(self.name))

    # 没有被特殊修饰的就是实例方法
    def say(self, linux):
        print('hello' + linux)

# 创建对象返回的是一个引用
person=Person('老李')
# 调用方法-->对象.方法(参数)
person.say('linux')
# 访问变量-->对象.变量名
print(person.name)

  注意:Python的没有方法重载,即相同的函数名,不同的函数列表的函数!

  方法中self参数理解:哪一个对象调用的方法,self就是哪一个对象的引用,self就是调用者本身!
        1)在封装的方法内部,self就表示当前调用方法对象自己
        2)在调用方法的时候,程序员不需要传递self参赛(定义的时候,第一个参数默认是self,自动绑定

谁调用(发起),self就是谁(那个对象)!

明确:只是一个形式参数,可以随意命名,只是约定俗成(规范),具有更好的可读性而已!

(4)Python的动态语言特性和内置方法的使用

    4.1)动态特性

            变量:对象动态的增加删除变量

class Person:
    def __init__(self, name):
        self.name = name

p = Person('wzj')
#(1)增加属性
p.height = 175
print(p.height)
# (2)删除属性
del p.height
print(p.height)

# 说明:只是针对这个对象而言的!

            方法动态的添加方法

# (0)定义一个类
class Person:

    def __init__(self, name):
        self.name = name

# (1)自定义一个函数
def define(self):
    print('为对象动态的增加一个方法', self)

# (2)动态增加方法
p = Person('猫腻')
# 说明:foo只是一个变量,存储的是函数的引用!
p.foo = define
# 调用方法
p.foo(p)

# 说明:dir可以看到一个对象或者类的成员
print(dir(p))

说明:这个案例有助于理解类体中方法self参数的含义,这个是类体外针对象的!

注意:动态的增加方法,python不会自动将调用者绑定到第一个参数中,所以需要自己指定!

需求:借助其它模块,后续

    4.2)内置方法

特点:以__开头和结尾的

class Person:

    def __init__(self, name):
        self.name = name

    # 强调:返回必须是一个字符串
    # 说明:重写了object基类的方法,不希望打印对象的地址值!
    def __str__(self):
        return "不用地址数值,而是自定义%s" % (self.name)

    # 对象销毁前做的扫尾工作,把对象从内存中销毁(垃圾回收)
    def __del__(self):
        print('%s 走了' % (self.name))

print(Person('老李'))
print(Person('老吴'))

关于自动绑定self的方法再强调几点

说明:根据第一个参数出现的位置不同,第一个参数绑定的对象略有不同

       构造方法中:表示引用构造方法正在初始化的对象

       实例方法中:引用调用该方法对象

self的作用:引用当前方法的调用者(对象)!

了解:self表示所代表的对象是不确定的,但是类型是确定的,只有在方法被调用的那一刻,它所代表的对象才确定!

self的应用:对象的一个方法依赖于另一个方法-

class Person:

    def __init__(self, name):
        self.name = name
    def run(self):
        print('跑得快')
    def drink(self):
        # 错误的方法调用(省略了self)
        # run()
        # 正确的方法调用,区别于Java!
        self.run()

########说明:上述所讲的都是##########

(5)方法细讲

        5.1)实例方法:类体中定义的一般方法

说明:由于与实例挂钩,所以与对象有直接的联系,又因为对象是由类创建的,所以实例方法有两种调用方式

class Person:
    def __int__(self):
        print('hello')

    def run(self):
        print(self,'正在跑')
# (1)实例调用方法
Person().run()

# (2)类调用实例方法
Person.run(Person())

# 疑惑:二者的内存空间竟然一致,会不会是Python版本的问题

区别类调用实例方法,Python不会自动为第一个参数绑定调用者,而对象调用实例方法会

注意:不管是哪种方式调用实例方法都会进行对象的初始化!

        5.2)类方法和静态方法

class Person:
    @classmethod
    # 说明:cls会自动绑定到类本身!
    def run(cls):
        print('类方法',cls)

    @staticmethod
    # 说明:静态方法如果想绑定参数,需要手动绑定!
    def static(p):
        print('静态方法',p)

# (1)调用类方法-->会自动绑定到第一个参数
# 方式1
Person.run()
# 方式2
Person().run()

# (2)调用静态方法-->不会自动绑定到第一个参数
# 方式1
Person.static(Person())
# 方式2
Person().static(Person())

说明:虽然可以通过类或者对象来调用静态和类方法,但是推荐使用来调用

区别:静态方法不管哪种方式的调用都不会自动绑定都不会调用构造方法

练习

class Toy(object):
    # 类属性
    count = 0

    def __init__(self, name):
        self.nama = name
        # 说明:调用类方法时回创建对象
        # self.count +=1
        Toy.count += 1

    @classmethod
    def show_toy_count(cls):
        # 类方法可以调用类属性
        print('玩具的数量 %d' % (cls.count))

# 测试-->创建玩具对象
toy1 = Toy('乐高')
toy2 = Toy('小米')

# 调用类方法-->注意调用方式!
Toy.show_toy_count()

应用场景工厂模式

由静态方法引出的函数装饰器

        5.3)私有方法

备注:私有方法在讲解Python面向对象的三大特性的风转时讲解!

明确一点:不是绝对私有的(与Java比较)

理解:类的命名空间和全局空间

函数和类的方法区别:看是在类的命名空间还是全局空间中!

(6)变量的细讲

        6.1)类变量和实例变量

需求:类变量和实例变量的读取和修改

class Person:
    # (1)定义一个实例变量
    name = '老李'
    age = 18

    # (2)定义实例方法
    def fun(self, name):
        # 说明1:下面赋值语句(name)不是对类变量的赋值,而是定义新的实例变量
        self.name = name
        # 说明2:由于在对象中找不到此变量,所以会在类变量中寻找age!
        print("%s的年龄也是%d" % (self.name, self.age))


# (1)类变量
# 读取方式:类名调用
print(Person.name)
print(Person.age)
# 修改方式
Person.name = 'kangkang'
print(Person.name)

# (2)实例变量
# 读取:实例变量(第一次调用该方法的时候)
p = Person()
p.fun('wzj')
# 修改:由于对象中已经有此实例变量,此时就是修改
p.name = '老吴'
print(p.name)

# 说明:由于Python是动态语言,赋值语句往往意味着定义新的实例变量!

类变量:在类命名空间中定义的变量就是类变量!

        6.2)私有变量

说明:后续讲到封装的时候再讲解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值