• Python——面向对象


    💦初识面向对象

    什么是面向对象?为什么要引入面向对象?

    首先,早期计算机编程语言都是面向过程的,程序即由数据和算法构成,数据可以构成复杂的数据结构,算法也是由上到下的复杂逻辑控制,这是一种将数据与操作算法分离开的编程思想。😲总是就是很麻烦的意思。

    而面向对象中的对象,将数据和方法包装起来,它内部的数据和算法由开发者设计,我们只需调用接口就行了,不需关心实际对象内部的复杂逻辑😄。

    ☁️对象

    现实生活中我们能见到的、能触碰到的人和事物都是对象,如你、我、猫、汽车、树等等。“万物皆是对象”,但咱就没有对象😭。对象可以是有形的,也可以是无形的。我们可以将对象简单地处理为两个部分——属性行为

    属性
    对象具有属性,可以称为状态,也可以称为变量。例如👉每个人都有名字、性别、身高、体重等。再直白一点就是,在游戏里有时候会给角色的属性加点😆,像力量、体力、速度、敏捷、魔法等等。

    而同一类中有许多不同的对象,进而这些的对象的属性值也并不相同。正如这个世界上70亿人就是一个大类,我们都是其中一个对象罢了。

    行为
    对象具有行为,也可以称为方法。例如,我们身为人这一类中的对象,我们要吃饭、睡觉、打豆豆。这些就是属于对象的行为。

    面向对象编程将完成某个功能的代码块定义为方法,方法可以被其它程序调用,也可以自己调用,例如,我可以自己吃饭,你也可以喂我吃饭😋。

    同时,每个对象的行为也是不一样的,例如一般常人都12点之前就睡觉了,而我不知不觉就熬到了一两点。。。。

    ☁️类

    类是相同类似对象的统称。例如👉狗是一个类,属于它的对象有:二哈、金毛、中华田园犬等等。手机也可以是一个类,属于它的对象有:华为、三星、苹果、小米等等。

    类是对象的属性和行为被进一步封装的模板,不同的类之间的属性和行为都是不同的。就好比人的行为能跟狗的行为一样吗?答案…当然是否定的。

    💦Python与面向对象

    ☁️基本术语

    1. 类(class):用来描述具有相同的属性和方法的对象的集合。对象是类的实例(具体例子)。
    2. 实例化:创建一个类的实例,一个类的具体对象。
    3. 实例变量:定义在方法中的变量,只作用于当前实例的类。
    4. . 类变量:类变量定义在类中且在函数体之外,常不作为实例变量使用。
    5. 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
    6. 数据成员:类变量或实例变量,用于处理类及其实例对象的相关数据。
    7. 方法:类中定义的函数。
    8. 继承:指一个派生类继承基类的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
    9. 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程较方法的覆盖,也称为方法的重写。

    ☁️类的定义

    类必须在被定义后才能使用,定义一个类也就是定义这一类对象的模板。Python中用 c l a s s class class关键字来声明一个类, c l a s s class class中有成员属性和成员方法。例如👇:

    class Empty:
        pass
    
    empty = Empty()
    print(type(empty))
    #
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其中, e m p t y empty empty就是一个对象,类的实例化,同时在内存中为这个对象分配了内存空间。

    在创建实例的时候,很多类可能都需要有特定的初始状态。所以,一个类可以定义一个特殊的方法,叫做构造函数。在Python中,构造函数就是类的__init__方法(init前后都有两个连续的短下划线)。例如👇:

    class Dog:
        def __init__(self):
            print("汪汪汪!")
    dog = Dog()
    #汪汪汪
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意❗️:当一个类定义了__init__方法,类在实例化时会自动调用__init__方法,用于创建新的类实例。在上面的例子中,新的实例dog被创建,同时又执行了构造方法,也就是运行了__init__函数。还有一点需要注意的是,构造方法的返回值必须是None。在定义构造方法的时候解释器不会报错,但是在实例化的时候Python会输出错误提示“TypeError: init() should return None”。

    在构造方法中,我们可以初始化一些属性,例如👇:

    class Dog:
        def __init__(self,name):
            self.name = name;
            self.age = 3
    dog = Dog("旺财")
    print(dog.name)
    #旺财
    print(dog.age)
    #3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    属性(或者叫成员变量、类变量)必须要使用self加上点的方式赋值,不能直接定义变量。直接定义的变量的声明周期只会在函数内,函数执行完变量就会被销毁。

    其实函数__init__的第一个参数self指的就是实例本身,可以理解为对实例的属性赋值,相当于实例的初始化。Python在调用__init__函数时会自动地添加实例作为函数的第一个参数。(这部分非常重要)

    在类中定义的函数我们称为方法。自己定义成员方法也很简单,例如👇:

    class Dog:
        def __init__(self,name):
            self.name = name
    
        def play(self):
            print("汪汪汪!我是", self.name)
    dog = Dog("旺财")
    dog.play()
    #汪汪汪!我是 旺财
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    方法除了一定要定义在类里面并且第一个参数必须是“self”(也可以叫做其它的名字)外,其它和函数的定义没有任何区别。

    类中还有私有属性,用来限制外部对属性的修改。例如👇:

    class Dog:
        def __init__(self,name):
            self.__name = name
    
        def play(self):
            print("汪汪汪!我是", self.__name)
    dog = Dog("旺财")
    dog.play()
    #汪汪汪!我是 旺财
    print(dog.__name)
    #AttributeError: 'Dog' object has no attribute '__name'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    那么我们如何能修改到私有属性呢?首先,明确私有属性是为了限制外部的访问(也就是类的外面),所以我们在类里面修改就行了,也就是在类里面再定义一个方法,用来修改私有属性。例如👇:

    class Dog:
        def __init__(self,name):
            self.__name = name
    
        def play(self):
            print("汪汪汪!我是", self.__name)
    
        def set_name(self,name):
            self.__name = name
    dog = Dog("旺财")
    dog.play()
    #汪汪汪!我是 旺财
    dog.set_name("二哈")
    dog.play()
    #汪汪汪!我是 二哈
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    那么,既然有私有属性,那么就一定有私有方法。同样地,和私有属性一样,私有方法只能在类的内部被调用,实例不能直接调用。例如👇:

    class Dog:
        def __init__(self):
            pass
        def __say(self,name):
            print(name)
        def play(self):
            self.__say("汪汪汪!")
    
    dog = Dog()
    dog.play()
    #汪汪汪
    dog._say("旺财")
    #AttributeError: 'Dog' object has no attribute '__say'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    也就是说,__say函数只能被类中的其它函数调用,不能从外部调入。

    💦继承

    继承是一种对类进行分层级划分的概念。它的基本思想是在一个类的基础上制定出一个新的类,这个新的类不仅可以继承原来类的属性和方法,还可以增加新的属性和方法。原来的类被称为父类,新的类被称为子类。Python中一个子类可以继承多个父类。其语法如下👇:

    class SubClass(BaseClass1,BaseClass2):
    	语法块
    
    • 1
    • 2

    定义要继承哪个父类,只需在定义子类名字后面的括号中填入父类的名字,如果有多个父类,则用逗号隔开。例如👇:

    class Animal:
        def __init__(self, name):
            self.name = name
        def play(self):
            print("我是", self.name)
    
    class Dog(Animal):
        pass
    
    dog = Dog("旺财")
    dog.play()
    #我是 旺财
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    有两点需要注意❗️:

    1. 在继承中,若子类定义了构造方法,则父类的构造方法__init__不会被自动调用,需要在子类的构造方法中用 s u p e r 函数 super函数 super函数专门调用。例如👇:
    class Animal:
        def __init__(self, name):
            self.name = name
        def play(self):
            print("我是", self.name)
    
    class Dog(Animal):
        def __init__(self):
            super(Dog , self).__init__("旺财")
    
    dog = Dog()
    dog.play()
    #我是 旺财
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 子类不能继承父类中的私有方法,也不能调用父类的私有方法。

    💦多态

    继承可以帮助我们重复使用代码,但是有时候子类的行为不一定完全和父类一样。例如👇:

    class Animal:
        def say(self):
            print('Animal')
    
    class Dog(Animal):
        pass
    class Cat(Animal):
        pass
    dog = Dog()
    dog.say()
    #Animal
    cat = Cat()
    cat.say()
    #Animal
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    我们想让dog和cat在调用say方法时能输出不同的内容,那么该如何做呢?看下面👇:

    class Animal:
        def say(self):
            print('Animal')
    
    class Dog(Animal):
        def say(self):
            print('dog')
    
    class Cat(Animal):
        def say(self):
            print('cat')
    dog = Dog()
    dog.say()
    #dog
    cat = Cat()
    cat.say()
    #cat
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在上面的代码中,Dog和Cat分别调用了各自的say方法。

    那么,当子类和父类存在相同的方法时,子类的方法会覆盖父类的方法,这样代码在运行时总是会调用子类的方法,这就是多态

    判断一个实例是不是某个对象可以使用isinstance函数,例如👇:

    class Animal:
        def say(self):
            print('Animal')
    
    class Dog(Animal):
        def say(self):
            print('dog')
    
    class Cat(Animal):
        def say(self):
            print('cat')
    dog = Dog()
    cat = Cat()
    print(isinstance(dog,Dog))
    #True
    print(isinstance(dog,Animal))
    #True
    print(isinstance(cat,Cat))
    #True
    print(isinstance(cat,Animal))
    #True
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    💦知识拓展

    ☁️类变量和实例变量

    类变量和实例变量有什么区别?👉:类变量不需要实例化就能直接使用。例如👇:

    class Animal:
        name = '动物'
    print(Animal.name)
    #动物
    
    • 1
    • 2
    • 3
    • 4

    类变量在实例中也是可以被调用的,例如👇:

    class Animal:
        name = '动物'
    
    dog = Animal()
    cat = Animal()
    
    print(dog.name)
    #动物
    print(cat.name)
    #动物
    Animal.name = '哺乳动物'
    
    print(dog.name)
    #哺乳动物
    print(cat.name)
    #哺乳动物
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    但是实例不能修改类变量,如果实例对类变量进行修改,Python解释器就会新建一个同名的成员变量来代理实例中的类变量。

  • 相关阅读:
    微信小程序关注公众号
    SpringBoot项目的创建
    面试题c/c++--语言基础
    剑指offer56 数组中只出现一次的两个数字
    Linux之Socket函数(详细篇)
    AI芯片软件定义硬件架构
    服务器不稳定会造成什么影响
    【Java并发编程十】同步控制二
    写作一笔记
    【python基础】类-模块
  • 原文地址:https://blog.csdn.net/weixin_62917800/article/details/126395461