自学内容网 自学内容网

用人话讲计算机: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)!