联想说 Python 基础 16 - 认识对象

认识对象

目标:理解类和对象,掌握类和对象以及其成员的创建。

对象这部分(不止这一节),非常重要,关系着你能不能找到合适的对象 ◕‿◕。

类和对象

什么是对象?

生活中能称为对象的东西还是非常多的,最常被称为对象的就是情侣的互称了,比如你的男/女朋友,就称为你的对象。

那这里的对象和 “你的对象” 的这个对象有什么关系?

首先我们需要了解,为什么你的女朋友可以称为你的对象这个问题,最根本的就是了解什么是对象。

对象 是汉语词汇,拼音是duì xiàng,常有两层意思,指行动或思考时作为目标的事物或特指恋爱的对方等含义(来自百度百科)。

按照这个说明,那只要是目标事物都可以是对象,而 “你的对象” 也只是你恋爱的目标事物而已。

问:你现在的对象叫什么?

问这个问题并不是真的要你给我答案,而是对象的特点,它是一个具体的某个事物。就拿这个问题,你应该能明确的告诉我你对象叫什么,比如叫小红。

如果你的女朋友太多,没法没法明确的说出你的女朋友是哪个,那不好意思,这篇文章可能不太适合你看。

什么是类?

对于对象,我们大致有了一个映像,那什么是类呢?

,汉语一级字,读作类(lèi),本义指种类(来自百度百科)。

一般说种,那自然就是一个群体了。比如鸡 类,说的是所有的鸡,不管是公鸡母鸡还是战斗鸡,它们都是鸡类。

所以类,它是一个比较模糊的概念。

为什么模糊?那你想想鸡类是什么样子的。我想此时你脑海里要不是某只鸡或者一大群鸡的样子吧,但它们是整个鸡类吗?明显不是了,只要你能想到的都只是类的一部分。

类和对象有什么关系呢?

前面了解到类是一个模糊的群体,现在我从群体中拿出来一个具体的事务,那不就是具体的了吗?

再看对象,它是一个具体的某个事物,这个事物不刚好可以从类中拿出来吗?

所以类和对象的关系是相对的,对象是类拿出来的具体的事物,类是很多对象的聚合体。

问:你的前女友是类还是对象呢?

答:前女友是类。为什么?因为既然已经是前女友了,那就应该模糊掉了。

好了,正经说一下,前女友确实是类。因为前女友这个名词并不是对某个人来说的,而是一个词,这个词就说明了前女友可以有一个也可以有很多。既然如此,那自然是要包含更多可能的,也就是前女友可能不止一个。

既然前女友不止一个,那自然是一个群体,群体是类还是对象呢?

作者的话:愿大家都没有前任,愿大家择一人而终,愿~ 有情人终成眷属。

Python 中的类和对象

如果你从上面的内容了解了什么是类,什么是对象,那么下面的内容就比较好理解了。

在 Python 中也有类和对象的概念,应该说现在的非常非常多的编程语言都有这个概念。

那在 Python 中该怎么定义类和对象呢?又该怎么使用呢?接着看。

定义类

在 Python 中定义类需要特定的语法格式,如下:

class 类名称():
    pass
  • class 是关键字,不能改变
  • 类名称 可以随自己写,但是建议首字母大写
  • 小括号 可以省略(稍后讲)
  • pass 部分是类的成员所在位置(稍后讲)

根据上面的解释,那我们就可以写一个自己的类了:

class Chicken():
    pass

或者

class Chicken:
    pass

定义类就这么简单了。

拿对象

对象是从类中取出的一个具体的事物,这个从类中取出具体对象的过程就是创建对象的过程,也叫实例化对象

在 Python 中实例化对象,就像函数调用一样,格式如下:

对象名称 = 类名称()

比如:

class Chicken:
    pass


xh = Chicken()

这里就创建了一个名为 xh 的对象,该对象属于 Chicken 类。

由于对象是从类中拿出来的,而类又是一个群体,所以可以从类中拿出来的对象不止一个。创建不同的对象,只需要给对象不同的名字就行。比如:

xh1 = Chicken()
xh2 = Chicken()
xh3 = Chicken()

类成员

一个族群一般都会有自己的特点,比如鸡类从头到脚有鸡冠、耳朵、嘴、喙、肉垂、羽毛、短脚等。除了这些外观属性外,鸡还会打鸣、下蛋等行为。

像这些属性和行为都可以在 Python 中体现出来,而在 Python 中可以把这些称为 类的成员。Python 中类的成员主要有 属性(成员变量)和 方法(成员函数),定义它们的格式分别如下:

class 类名称:
    
    属性名称 = 值

    def 方法名称(self):
        pass

属性的定义和变量的定义方式一样,只是由于它属于该类,所以它只能写在类里面。

方法也类似,它也需要写在类里面。而在写法上面,它相似与函数,不过与函数不同的是它的参数列表中需要存在 self 关键字(后面讲)。

成员调用

成员定义完成后,如果想要调用,需要告诉计算机你要调用哪个里面的成员。比如你是要小红打鸣呢还是要小花打鸣呢?

所以在调用上,它和变量或者函数的调用有一些区别,它需要通过 对象.成员 的方式调用,从而告诉计算机你需要谁来帮你搞事情。比如:

# 定义类 Chicken
class Chicken:
    # 定义属性 name
    name = "小红"

    # 定义方法 test
    def test(self):
        print("hello world")


# 创建对象
xh1 = Chicken()
# 调用 name 属性
print(xh1.name)
# 调用 test 方法
xh1.test()

构造方法

什么是构造方法?

构造方法也是一个方法,它是用来构造某个东西的方法,而这个方法存在于类中,所以它能构造不是类就是对象了。

那构造方法是用来构造类还是构造对象的呢?

答案是用来构造对象的,为什么不是构造类?因为类是我们自己定义的呀,当你定义好的时候,它就已经构造好了。

而对象是从类取出的具体的某一个。既然是具体的,那其具体信息应该是完善的。比如你家的某只鸡,它叫什么,是什么颜色的羽毛,它有什么特长等等,这些你都应都知道了。

但是每只鸡都有自己的特点,不能一概而论,所以创建每个鸡对象都应该有自己的属性。那我们该怎么构造自己所创建对象的属性呢?那就是用构造方法了。

构造方法定义

构造方法是类里面的一个特殊方法,它有自己的特有名称 __init__,定义构造方法的格式如下:

class 类名称:

    def __init__(self):
        pass

注意,构造方法名称必须是 __init__,否则就不是构造方法了。比如:

class Chicken:
    name = "小红"

    def test(self):
        print("hello world")

    def __init__(self):
        print("构造方法")
        pass


# 创建对象
xh1 = Chicken()
xh1.__init__()

定义了构造方法后,通过对象调用,然后运行程序,会发现控制台出现了这样的情况:

构造方法
构造方法

为什么会打印两次?

构造方法作用

按照前面所讲的内容,通过 xh1.__init__() 会调用一次构造方法,控制台会打印一次,而第二次打印,则是构造方法的特殊功能了。

构造方法会在实例化对象的时候,被自动调用。也就是说,你不调用,它也会自动执行,而且执行时间是你创建对象的时候。

基于这个特性,我们可以在创建对象的时候,初始化对象的属性。比如:

class Chicken:

    name = ''
    color = ''

    def __init__(self):
        self.name = '小红'
        self.color = '粉色'


xh1 = Chicken()
print(xh1.name)  # 小红
print(xh1.color) # 粉色

在这段代码中,name 和 color 并没有赋予初始值,当创建对象的时候,自动执行构造方法给 name 和 color 赋值,此时 Chicken 类的属性就有值了。

虽然这样可以给对象初始化属性值,但是每个对象的值都是固定的,那还初始化那么多干嘛呢?所以这样的设计有点不太好。

构造方法的参数

学过函数都知道,函数是可以定义参数的,通过参数可以让函数多样化,方法同样也支持。

class Chicken:

    name = ''
    color = ''

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

但是因为构造方法我们是不会自己调用的,所以没法在调用的时候提供实参。而构造方法又确实需要实参,那我们应该在哪提供呢?

在实例化对象的时候,类名称后面会给一个小括号,这个括号里面没有给任何东西,但又必须存在,可以大胆猜测它就是用来给构造方法传递实参的。测试:

xh1 = Chicken("小红啊", "粉红色")
print(xh1.name)  # 小红啊
print(xh1.color)  # 粉红色

从结果可以看出,它确实能给构造方法传递参数。

按照函数的内容来说,构造方法应该是定义了三个参数:self、name、color,为什么我们不用给 self 传递参数,self 又是什么?

self

self 翻译一下叫 自己,这个 “自己” 是表示类还是对象呢?

首先明确一件事情,我们创建了一个完整的类之后,里面定义的属性、方法是给谁用的?

一般情况下,应该都是给对象用的吧,这个应该不会有疑问吧。因为我们做事情,肯定需要找到某个具体的对象帮我们做,总不能说让鸡类给你下蛋吧。就算你是农场主,那也是很多只鸡对象给你下蛋而不是鸡类。

既然知道了类里面的成员是给对象用的,那方法里面的 self 代表谁也就不言而喻了吧,自然是代表对象了。

如果产生疑问:那么多对象,它代表哪个对象呢?

那说明你还没有理解类和对象的关系。我们从类中拿出来一个对象,这个对象是有这个类里面的所有成员的。当我们再次拿出一个,还会得到一个新的,这两个对象都有自己的成员,相互之间不影响。

我们这里能看到的类,它还只是类的代码,只有当程序运行到它之后,它才能称为类。

问:这个时候你还能修改类吗? 肯定不能(除非停止,之后又得重新执行)。

类有了之后,才会生成对象,它会把类里面的功能复制一份给对象用。

所以,可以把我们现在所写的类当做创建对象的模板,之后根据这个模板创建对象。

为什么方法参数里面的 self 不用传参?

因为 Python 自动帮我们把当前实例作为第一个参数传递给该方法了,因此不需要显示的传递 self 参数,你可以直接使用。

class Chicken:

    name = ''
    color = ''

    def __init__(self, name, color):
        self.name = name
        self.color = color
        print(self)  # <__main__.Chicken object at 0x000001C176C86790>

xh = Chicken("小红啊", "粉红色")

打印 self 的值,可以看到 <__main__.Chicken object at 0x000001C176C86790>,它显示的是对象 xh 的地址。

当创建不同的对象的时候,得到的地址值也不一样。

既然 self 代表的是当前调用的对象本身,那在类里面想要使用类的成员,就都可以使用 self 关键字来实现了,只需要用 self 代替对象名称就行。

关于对象的认识部分暂时就这么多,虽然程序中的对象可以随便造,但是如果你们有对象,还是要好好珍惜。

posted @ 2023-10-12 20:01  笔锋微凉~~  阅读(12)  评论(0)    收藏  举报