• Python3(六) 面向对象


    一.类的定义

    1.


    class
    Student():     name = ' ' #定义变量     age = 0     def print_file(self):     #定义函数         print('name:' + self.name)         print('age:' + str(self.age)) class StudentHomework():     homework_name = ' ' #使用类需要对类进行实例化 student = Student() student.print_file() #调用类下面的方法
    • 类的最基本作用就是在封装代码。
    • 类的内部不能调用类的方法,类只负责去描述和定义,而不负责执行,运行和调用类需要放在类的外部。
    • 不推荐在一个模块中既定义类又使用类。

    2.在一个模块中调用另一个模块的类:

    #c2.py中的代码
    from c1 import Student#Student类属于c1模块
     
    student = Student()#实例化
    student.print_file()#调用Student类中的print_file()方法

    二.函数与方法的区别

    方法是设计层面上的称谓,更多的是面向对象中的概念;

    函数是程序运行的,面向过程的一种称谓。

    没有必要特别的去区分方法和函数。

    变量出现在类中更多称为数据成员。

    三.构造函数 

    1.实例化创造不同的对象。

    student1 = Student()
    student2 = Student()
    student3 = Student()
     
    print(id(student1))
    print(id(student2))
    print(id(student3))
     
    结果
    #3269808
    #3410256
    #3410320

    2.

    def __init__(self):声明构造函数

    • 构造函数的调用是自动进行的
    • 我们可以去主动调用构造函数
    • 对构造函数来说只能 return None

    3.构造函数的作用

    class Student():
        name = '' #定义变量(类变量)
        age = 0
        def __init__(self,name,age):
            #初始化对象的属性
            name = name
            age = age
     
    student1 = Student('朱可爱',18)
    print(student1.name,student1.age)    #返回了空字符串

    返回空字符串的原因:类变量和实例变量的原因,实质上返回的是类变量

    尝试访问实例变量时:在实例变量列表里查找,如果没有会到类变量里面寻找。如果类中没有会到父类寻找。

    模块中的类似情况:局部变量不会覆盖全局变量

    c = 50
    def add(x,y)
        c = x + y    #这个c不会覆盖全局变量的c
        print(c)
    结果:
    3
    50

    四.类变量与实例变量 

    1.定义:

    类变量:和类相关的变量(类变量不会受实例变量的影响)

    实例变量:和对象相关联的变量

    2.代码

    class Student():
        name = 'cute' 
        age = 0
        def __init__(self,name,age):
            self.name = name 
            self.age = age
     
    student1 = Student('朱可爱',18)    #实例变量
    student2 = Student('朱cute',19)
     
    print(student1.name)
    print(student2.name)
    print(Student.name)#类变量不会受实例变量的影响
    结果:
    #朱可爱
    #朱cute
    #cute#类变量不会受实例变量的影响

    五.self与实例方法

    1.如果在类中定义实例方法的话,要固定在类中放上self

     

    2.self代表实例而不是类,注意:self不能称作关键字,self可以改为任意值,但是python建议使用self

    3.实例方法是实例可以调用的方法,和对象实例相关联。 

    六.在实例方法中访问实例变量与类变量

    1.在构造函数内部访问实例变量:

    class Student():
        name = '123'
        age = 0
        sum = 0
        def __init__(self,name,age):
           self.name = name
           self.age = age
           print(self.name)    #读取的是self.name,访问实例变量要加self
           print(name)        #读取的是形参的name,如果形参列表变成(self,name1,age),则会报错
     
    student1 = Student('cute',18)
     
    结果:
    cute
    cute

    2.在实例方法中访问类变量:

       print(Student.sum1)               #第一种访问类变量的方式(类名.变量名)
       print(self.__class__.sum1)        #第二种访问类变量的方式

    class Student():
        name = '123'
        age = 0
        sum1 = 0
        def __init__(self,name,age):
            self.name = name
            self.age = age              
            print(Student.sum1)               #第一种访问类变量的方式(类名.变量名)
            print(self.__class__.sum1)        #第二种访问类变量的方式
     
    结果:
    0
    0

    七.类方法

    类变量的使用场景:

    class Student():
        name = '123'
        age = 0
        sum1 = 0
        def __init__(self,name,age):
            self.name = name
            self.age = age
            self.__class__.sum1 += 1
            print("当前班级人数为" + str(self.__class__.sum1))
     
    student1 = Student('cute',18)
    student2 = Student('朱cute',18)
    student3 = Student('朱可爱',18)
     
    结果:
    #当前班级人数为1
    #当前班级人数为2
    #当前班级人数为3

    1.定义类方法:

    @classmethod     #装饰器
    def 方法名(cls):     #class简写,cls代表调用类方法的类。cls可以换成别的名字,但是不建议更换
       pass

    2.类方法里操作类变量:(更改类变量的使用场景的代码)

    class Student():
        name = '123'
        age = 0
        sum1 = 0
        def __init__(self,name,age):
            self.name = name
            self.age = age
            #self.__class__.sum1 += 1
            #print("当前班级人数为" + str(self.__class__.sum1))
        
        @classmethod
        def plus_sum(cls):
            cls.sum1 += 1
            print(cls.sum1)
     
     
    student1 = Student('cute',18)
    Student.plus_sum()              #调用类方法
    student2 = Student('朱cute',18)
    Student.plus_sum()
    student3 = Student('朱可爱',18)
    Student.plus_sum()

    3.区别:实例方法关联对象,类方法关联类本身。

    4.可以用对象调用类方法:

    student1 = Student('cute',18)
    student1.plus_sum()    #可以,但是最好不要,在逻辑上说不通

    八.静态方法

    1.定义静态方法:

    @staticmethod    #装饰器
    def 方法名(x,y):    #没有指代
               pass

    2.静态方法能够被类和对象调用:

    @staticmethod    #装饰器
    def add(x,y):    #没有指代
        print('This is a static method')
     
    student1 = Student('cute',18)
    student1.add(1,2)    #被对象调用
    Student.add(1,2)     #被类调用
     
    结果:
    This is a static method
    This is a static method

    3.静态方法内部可以访问类变量

    @staticmethod    #装饰器
    def add(x,y):    #没有指代
        print(Student.sum1)    #可以访问类变量
        print('This is a static method')

    4.静态方法和类方法都无法访问实例变量。

     

    5.能用静态方法的时候都可用类方法替代,最好不要经常使用,与类和对象的关联性非常弱,和普通的函数几乎没有区别。

     

    九. 成员可见性:公开和私有

    1.成员需要有一定的调用层级,以打分为例:

    class Student():
        name = '123'
        age = 0
        sum1 = 0
        score = 0
     
        def __init__(self,name,age):
            self.name = name
            self.age = age
            self.score = 0
        def marking(self,score):
            if score < 0:    #可以对数据进行判断
                score = 0
            self.score = score
            print(self.name + '本次考试分数为' + str(self.score))
     
    student1 = Student('cute',18)
    student1.marking(100)    #利用marking方法打分

    2.

    不加双下划线:公开

    加双下划线:私有   eg:__add

    前后都有双下划线:公开,是python内置函数的命名风格。eg:__init__():

    3.尝试从外部访问私有变量:

    class Student():
        def __init__(self,name,age):
            self.name = name
            self.age = age
            self.__score = 0
        def marking(self,__score):
            if __score < 0:
            __score = 0
            self.__score = __score
            print(self.name + '本次考试分数为' + str(self.__score))
     
    student1 = Student('cute',18)
    student1.marking(100)
    student1.__score = -1    #没有报错
    print(student1.__score)
     
    结果:
    100
    -1

    __score不是私有变量吗?为什么在外部赋值又可以访问呢?因为,student1.__score = -1  实际上是给sutdent1新添加了一个实例变量。

    举例:如果没有新添加,是不能在外部访问私有变量

    class Student():
     
        def __init__(self,name,age):
            self.name = name
            self.age = age
            self.__score = 0
        def marking(self,__score):
            if __score < 0:
            __score = 0
            self.__score = __score
            print(self.name + '本次考试分数为' + str(self.__score))
     
    student1 = Student('cute',18)
    student2 = Student('朱cute',19)
     
    student1.marking(100)
    student1.__score = -1    #实际上是利用python动态特性,给student1添加了一个新的属性叫__score,
                              并不是实例变量中的__score
    print(student1.__score)    #结果:-1
     
    print(student2.__score)    #报错了

    通过这种方式可以间接的读取私有变量:单下划线 + 类名 + 双下划线 + 实例变量名

    举例:

    print(student2._Student__score)    #读取到了私有变量,不会报错
     
    结果:本次考试分数为59

    10.继承

    #Filename:cls.py
    
    class People():
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def sayHello(self):
            print('Hello!')
    import cls
    
    class Student(cls.People):
        pass
    
    stu=Student('Tom',18)
    stu.sayHello()

    输出结果:

     Hello!
     

    Student类继承了People类的方法

    import cls
    
    class Student(cls.People):
        def __init__(self,name,age,score):
            self.score=score
            cls.People.__init__(self,name,age)
    
        def sayHello(self):
            print('Hi!')
    
    stu=Student('Tom',18,90)
    stu.sayHello()

    输出结果:

     Hi

    子类扩展了父类的init()方法,但是调用父类的init方法时,必须要传入self

    然后子类又重写了父类的sayHello()方法

    调用父类的方法时也可以使用super()

     
    import cls
    
    class Student(cls.People):
        def __init__(self,name,age,score):
            self.score=score
            super(Student,self).__init__(name,age)
    
        def sayHello(self):
            print('Hi!')
    
    stu=Student('Tom',18,90)
    stu.sayHello()
    print(stu.name)
    print(stu.age)

    输出结果:

     Hi
     Tom
      18
     

    使用super()可以不用指定父类名称

    11.多继承

    python可以多继承

    class A():
        def __init__(self):
            print('a')
    
    class B():
        def __init__(self):
            print('b')
    
    class C(A,B):
        pass
    
    c=C()

    输出结果:

     a

    如果父类有相同的方法,子类会优先调用先被继承的类的方法

    12.多态

    class C():
        def say(self):
            pass
    
    class B(C):
        def say(self):
            print('B')
    
    class A(C):
        def say(self):
            print('A')
    
    b=B()
    a=A()
    b.say()
    a.say()

    输出结果:

     B
     A
     
     
  • 相关阅读:
    Linux C 面试题总结
    linux下的缓存机制及清理buffer/cache/swap的方法梳理
    接入WebSocket记录 + 一些个人经验
    Linux基础系列—Linux体系结构和Linux内核结构
    typedef和define具体的详细区别
    RANSAC与 最小二乘(LS, Least Squares)拟合直线的效果比较
    深入理解C/C++混合编程优秀博文赏析与学习
    “error LNK2019: 无法解析的外部符号”之分析
    CUDA和OpenGL互操作经典博文赏析和学习
    [原创]C/C++语言中,如何在main.c或main.cpp中调用另一个.c文件
  • 原文地址:https://www.cnblogs.com/wlgaojin/p/12284809.html
Copyright © 2020-2023  润新知