联想说 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 代替对象名称就行。
关于对象的认识部分暂时就这么多,虽然程序中的对象可以随便造,但是如果你们有对象,还是要好好珍惜。

浙公网安备 33010602011771号