06 面向对象之二


目录

  • 类与对象
  • 构造函数
  • 类变量与实例变量
  • 实例方法与类方法、静态方法
  • 成员的可见性
  • 对象之继承性

四、实例方法与类方法、静态方法

方法的本质意义:
方法对变量做一系列的运算,或逻辑上的操作,最终改变变量的一个状态。

1.实例方法

实例可以调用的方法叫实例方法,与实例相关联
最大的特点:定义时,第一个参数是 self

(1)构造函数与实例方法的区别

构造函数实例方法
调用方式通过类后面的小括号(),即实例化student1=Student('石敢当')通过对象调用,student1.do_homework()
意义初始化类的各种特征描述类的各种行为

注意:构造函数也可以被看作一种特殊的实例方法

(2)实例方法操作的是实例变量,只要加个self即可。那么实例方法可以操作类变量吗?
可以。

写法1:

class Student():
    sum1 = 0           #类变量
    def __init__(self,name,age):
        self.name = name
        self.age = age
        print(Student.sum1)      #实例方法内部可以访问操作类变量

-->
0

写法2:(比较特殊)

class Student():
    sum1 = 0           #类变量
    def __init__(self,name,age):
        self.name = name
        self.age = age
        print(self.__class__.sum1)    #__class__:实例方法内部可以访问操作类变量

-->
0

2.类方法

根据上节,实例方法内部可以访问操作类变量。

class Student():
    sum = 0           #类变量
    def __init__(self,name,age):
        self.name = name
        self.age = age
        self.__class__.sum += 1
        print('当前学生总数:' + str(self.__class__.sum))    #str不能与int相加

student1 = Student('石敢当',18)
student2 = Student('喜小乐',18)
student3 = Student('小诺',18)

-->
当前学生总数:1
当前学生总数:2
当前学生总数:3

以上的构造函数是作为实例方法的特别一种,那其他的实例方法呢?
也可以。

class Student():
    sum = 0           #类变量
    def __init__(self,name,age):
        self.name = name
        self.age = age
       
    def do_homework(self):      #重新定义一个实例方法
        self.__class__.sum += 1      #在实例方法中,操作类变量
        print('当前学生总数:' + str(self.__class__.sum))

student1 = Student('石敢当',18)
student1.do_homework()

student2 = Student('喜小乐',18)
student2.do_homework()

student3 = Student('小诺',18)
student3.do_homework()

-->
当前学生总数:1
当前学生总数:2
当前学生总数:3

(1)定义类方法
最重要的特征:加上一个装饰器:@classmethod
cls不是关键,因为这个只是python默认推荐,它可以是任意其他字母

class Student():
    sum = 0           #类变量
    def __init__(self,name,age):
        self.name = name
        self.age = age
       
    def do_homework(self):     #这里的self代表的是调用该方法的对象
        self.__class__.sum += 1        #在实例方法中,操作类变量
        print('当前学生总数:' + str(self.__class__.sum))

    @classmethod       #定义一个类方法
    def plus_sum(cls):         #这里的cls代表的是类
        cls.sum += 1                   #在类方法中,操作类变量
        print(cls.sum)

student1 = Student('石敢当',18)
student1.do_homework()
Student.plus_sum()                 #通过类来调用类方法

student2 = Student('喜小乐',18)
student2.do_homework()             
Student.plus_sum()                #通过类来调用类方法

student3 = Student('小诺',18)
student3.do_homework()             
Student.plus_sum()                #通过类来调用类方法

-->
当前学生总数:1     #通过实例方法操作类变量的结果
2                  #通过类方法操作类变量的结果
当前学生总数:3
4
当前学生总数:5
6

(2)既然能在实例方法中操作类变量,又为什么要设置能在类方法中操作类变量呢?

在实例方法中操作类变量,虽然功能上对,也不报错,但意义上说不通。
由上述对比可知:
通过类方法操作类变量,既说得通,还更简单。

(3)类可以调用类方法,天经地义。那对象能调用类方法吗?
能。
虽不报错,但逻辑上说不通

class Student():
    sum = 0           #类变量
    def __init__(self,name,age):
        self.name = name
        self.age = age
       
    def do_homework(self):     #这里的self代表的是对象
        self.__class__.sum += 1        #在实例方法中,操作类变量
        print('当前学生总数:' + str(self.__class__.sum))

    @classmethod       #定义一个类方法
    def plus_sum(cls):         #这里的cls代表的是类
        cls.sum += 1                   #在类方法中,操作类变量
        print(cls.sum)

student1 = Student('石敢当',18)
student1.do_homework()
student1.plus_sum()                 #通过对象来调用类方法

student2 = Student('喜小乐',18)
student2.do_homework()             
student2.plus_sum()                #通过对象来调用类方法

student3 = Student('小诺',18)
student3.do_homework()             
student3.plus_sum()               #通过对象来调用类方法

-->
当前学生总数:1       
2
当前学生总数:3
4
当前学生总数:5
6
七月老师:
其他语言中,只能类调用类方法,对象是不能调用类方法,且会报错。
python作为动态语言,很灵活。这是一把双刃剑。这使得它很起来很简单,但如果对机制不深入了解,非常容易掉坑、易bug。

3.静态方法
方法的一种。

  • 使用场景:通常用在当某个方法与类、对象没什么关系时,那就用静态方法定义它
  • 最重要的特征:只要加个@staticmethod即可,不用强制的显式传递参数self/cls
  • 特点:与对象的关联性较弱,几乎与普通函数一样。

基于这个特点,能用静态方法的地方,都能用类方法。因此,不推荐经常使用

class Student():
    sum = 0        
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @staticmethod     #定义一个静态方法    #注意缩进!静态方法与类方法、实例方法、构造函数是平级的!
    def add(x,y):
        print('This is a static method')

student1 = Student('石敢当',18)
student1.add(1,2)     #对象可以调用静态方法
Student.add(1,2)      #类也可以调用静态方法

-->
This is a static method
This is a static method

静态方法内部,可以访问类变量吗?
可以。

class Student():
    sum = 0                      #类变量
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @staticmethod     
    def add(x,y):
        print(Student.sum)     #打印类变量
        print('This is a static method')

student1 = Student('石敢当',18)
student1.add(1,2)    
Student.add(1,2)     

-->
0
This is a static method
0
This is a static method

声明:Jerry's Blog|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 06 面向对象之二


Follow excellence, and success will chase you.