用人话讲计算机:python篇!(十六)面向对象:类、对象、属性、方法、实例化(上)
首先写代码有两个方法,面向对象和面向过程,我们主讲面向对象:
一、面向对象与面向过程
关于面向对象与面向过程,我们可以将其理解为两种编程方法。
比如,我们要设计一个程序:把大象关进冰箱。
面向过程:先设计打开冰箱的代码,再设计大象进去的代码,最后设计把门关上的代码。
面向对象:设计一个大象的代码,并且大象遇到门会走进去,设计一个人的代码,并且人遇到门会打开。最后我们把冰箱放到人和大象前面就行。
其区别在于:
面向过程是线性的,做完一步,再做一步。很固定。
面向对象是非线性的,先设计很多函数,每个函数都是,遇到什么就会怎样的,然后我们就跟拼图一样拼它就完事了。
所以我们知道了面向对象这种方法,首先你要有一个可供编写的对象,然后这个对象有很多特征属性,并且这个对象遇到什么,就会怎样做等等。
所以用官方的话说,它要有:类、对象、属性、方法等。
二、面向对象
开始之前,请把自己想象成上帝,现在你要创造一个物种,叫狗。
(1)类和对象
类,就是你要创造的对象,比如我们现在要创造一条狗。
格式:用class告诉计算机你要创建的东西
class dog: pass
说明:
- 当对象是空,写pass。
- 当对象有属性,不写pass,直接写它的属性就行(如下图,不懂属性可看后文)
如果我们想要调用它,须将其赋值给某变量 ,比如:
class Dog:
species="柯基"
a_dog = Dog() #将该类,赋值给变量a_dog,以后调用可以直接写a_dog
详细使用可看后面
(2)属性
属性,就是这个对象有什么属性,比如狗,狗有大有小,有各种颜色、品种等,这些都是属性。
属性又分为类属性和实例属性。
- 类属性,可以理解为全局性的。
- 实例属性,可以理解为此实例的属性。
即,实例属性是特定于某个对象的,而类属性是共享的。
a.类属性
编写一个对象的类属性,直接另起一行后,编写即可,如下图所示:
如果我们想访问或者修改它,可以如下图格式访问或修改:
b.实例属性
格式:(self那不一定非写成self,你一样可以都写成其他的,只不过大家都习惯写成self)
class dog: def __init__(self, 属性1, 属性2,……): self.属性1名字 = 属性1 self.属性2名字 = 属性2
(关于__init__它其实是英文状态下左右各两个下划线,另外关于__init__属于一种方法,后续会详细讲述的,这里不用搞太懂,知道这里要用__init__就行。)
解释:
这样,相当于,self这个对象,具备了属性1和属性2
如果想要赋值、访问、修改,可以按下格式:
class dog:
def __init__(self, name, breed):
self.a = name
self.b = breed
# 为实例属性赋值
A_dog = dog("小黄","斗牛犬")
# 访问实例属性
print(A_dog.a)
# 修改实例属性
A_dog.name = "旺财"
print(A_dog.name)
输出:
小黄
旺财
那么问题来了,上面我们说 类属性是全局的,实例属性是特定对象的。
这体现在哪里?
我们来看一个例子,区别一下他们:
class dog:
speices="犬科"
def __init__(self, name, color):
self.name = name
self.color = color
#赋值
adog=dog("A","黄")
bdog=dog("B","黑")
#访问
print(adog.speices) #输出:犬科
print(adog.name) #输出:A
print(bdog.name) #输出:B
在这个例子中
- species是类属性,是全局性的。
- name,color是实例属性,是对实例self来说的。
所以当我们对其进行赋值操作后
- 对adog来说,name:A color:黄 成了adog的专有属性。实例bdog和这两个属性没有关系。
- 对bdog来说,name:B color:黑 成了bdog的专有属性。实例adog和这两个属性没有关系。
- 而类属性species是全局性的,换言之,adog和bdog都具有这个类属性
综述,类属性是让所有的狗都具有这个属性,如犬科。
实例属性是让每个实例都具有各自的属性,如adog和bdog。
c.交叉访问
一句话,实例对象可以访问类属性,而类不能访问实例对象属性。
比如:
class dog:
speices="犬科"
def __init__(self, name, color):
self.name = name
self.color = color
#赋值
adog=dog("A","黄")
#访问
print(adog.speices) #输出:犬科
print(dog.name) #输出错误乱码
用最明白的话来说,这个交叉访问,就是告诉你:
- 类属性是全局的,所以每个实例属性都会具备这个类属性
故而print(adog.speices) 可以成功
- 实例属性是特定的,在这个例子中self具有两个实例属性。你不能通过dog这个大类,直接访问这个两个实例属性,而必须通过self去访问。
- 因为self虽然在这个例子中是adog,但是有时,self会是adog又会是bdog(如上一个例子中)。所以为了避免这种情况,干脆就不能直接在大类中去直接访问。
故而print(dog.a) 会失败
(3)实例化
实例化,其实我们已经经历过了,比如:
class dog:
speices="犬科"
def __init__(self, name, color):
self.name = name
self.color = color
#赋值
adog=dog("A","黄")
#访问
print(adog.speices) #输出:犬科
在这个例子中:
adog=dog("A","黄")就是实例化
除此之外,实例化还可以补充某一个实例的属性,比如:
class dog:
speices="犬科"
def __init__(self, name, color):
self.name = name
self.color = color
#赋值
adog=dog("A","黄")
#补充
adog.age=2
#访问
print(adog.age) #输出:2
a.传参
(此处权当知识点补充)
位置参数
adog=dog("A","黄")
就是我们的常规写法,这样写必须要和init后面的参数一一对应。
关键字参数
adog=dog(name="A",color="黄")
这样写有一个好处,不用一一对应,即我们这样写也是可以的:
adog=dog(color="黄",name="A")
默认参数
class dog:
speices="犬科"
def __init__(self, name=“小白”, color=“白”):
self.name = name
self.color = color
#赋值:默认参数
adog=dog()
#访问
print(adog.name) #输出:小白
即,提前在init后面写好参数。
可变参数
class Person:
def __init__(self, name, *hobbies):
self.name = name # 姓名
self.hobbies = hobbies # 爱好,通过 *hobbies 接收任意数量的爱好
# 创建两个实例
person1 = Person("Alice", "Reading", "Cooking")
person2 = Person("Bob", "Football", "Gaming", "Music")
# 显示信息
print(person1.hobbies) #输出:('Reading', 'Cooking')
print(person2.hobbies) #输出:('Football', 'Gaming', 'Music')
如上,在变量前加一个 * 是接受任意数量的位置参数。
同样的,如果前面加** 是接受任意数量的关键字参数。
(4)方法
方法,就是你要让你创造的物种,干些什么
方法也分为几种:类方法、实例方法、静态方法。
我们先来说说实例方法
a.实例方法
格式:
def 方法名(self,参数1,……): 干点啥的代码
比如,我们想让狗,汪汪叫 。
我们可以用如上格式方法,命名一个bark板块,然后在bark板块编写狗叫的代码。
这样我们创造的这个物种:狗。它就有汪汪叫的功能了。
实例:
class Dog:
def __init__(self,name):
self.name = name # 实例属性
def bark(self): # 实例方法
print("汪汪")
#赋值
dog1=Dog("1")
#使用方法
dog1.bark() #输出:汪汪
我们再来看类方法,之后再说说他们的区别
b.类方法
格式:
@classmethod def 方法名(cls): 干点啥的代码
比如,我们还是用类方法,让狗汪汪叫
实例:
class Dog:
def __init__(self, name):
self.name = name
@classmethod
def bark(cls):
print("汪汪叫!")
Dog.bark() # 输出:汪汪叫!
比较与区分
我们来看一下区别在哪:
首先,最显而易见的是格式不同。
除此之外,似乎就是调用时,类方法可以用类调用,实例方法只用实例对象调用,其他的似乎没有什么不同。
的确,在这个例子上他们确实没有什么不同。
但我们要注意的是,其不同在于
- 类方法,是将方法绑定到类上。
- 实例方法,是将方法绑定的实例上。
所以我们
- 需要操作类属性,用类方法
- 需要操作实例属性(针对某一对象的行为进行操作),用实例方法
举个例子:
比如操作一下类属性,我们用类方法:
(虽然说实例方法下用Dog.age一样能print输出,但这个例子的确是类方法的一个用处)
类方法不用去写init和self那一堆,当你封装函数时可能会更方便。
c.静态方法
格式:
@staticmethod def 方法名(): 干点啥的代码
特点:
- 没有
self
或cls
参数 - 可以通过类或实例调用
示例:
原文地址:https://blog.csdn.net/2301_81711570/article/details/144910328
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!