Python系列之面向对象编程(一文详解)

时间:2025-02-25 09:52:27

目录

一、类和对象

(一)类的概念

(二)对象的概念

(三)类的设计

(四)类和对象的创建

二、方法

(一)实例方法【常用】

(二)类方法

(三)静态方法

(四)小结

三、属性

(一)实例属性

(二)类属性

四、面向对象特征

(一)封装

(二)继承

1、单继承

2、多继承

3、方法重写

五、结语

参考资料


一、类和对象

(一)类的概念

类是具有相同特征和行为的一类事物的统称。在类的创建过程中会将事物的特征映射成为属性,会将事物的行为映射成为方法,即定义了该集合中每个对象所共有的属性和方法。所以可以说类是用来描述具有相同的属性和方法的对象的集合

(二)对象的概念

类是抽象的,它不能直接使用,对象是由类创建出来的实例,用来描述客观事物,是具体的,可以直接使用。

(三)类的设计

类的设计有三要素,分别是类名、类的属性、类的方法。

1、类名:采用大骆驼峰的命名方式,、YourName。

2、类的属性:将某类事物的特征抽象为类的属性,而每一种属性在类中的表现形式就是变量。

3、类的方法:将某类事物的行为抽象为类的方法 ,方法即为定义在类中的函数。

(四)类和对象的创建

class 类名:
    类的属性
    类的方法

实例化类:对象名=类名() 

访问类的属性:对象名.属性名

访问类的方法:对象名.方法名()

【例1】代码实例

class Dog:
    #类的属性
    species='puppy'
    #类的方法
    def run(self):
        print('它想要运动')
    def eat(self):
        print('它想要吃饭')
    def sleep(self):
        print('它想要睡觉')
        
#实例化类:对象名=类名()       
dog1=Dog()

#访问类的属性:对象名.属性名
#访问类的方法:对象名.方法名()
print()
()
()
()

输出为

puppy
它想要运动
它想要吃饭
它想要睡觉

二、方法

(一)实例方法【常用】

附:类有一个名为 __init__() 的构造方法,该方法在类实例化时会自动调用。如果类中的构造方法__init__()有对应的实例属性,则创建对象时还需要给实例属性进行初始化,后面详细讲解。

使用 def 关键字来定义一个方法,与一般函数定义不同,类的实例方法必须包含self,self代表类的实例,且self是第一个参数。

def 方法名(self,方法参数)
    方法体
    return 返回值

语法说明如下:

(1)实例方法必须创建在类中。

(2)方法第一个参数是self,代表对象本身。

(3)“return 返回值”可有可无,需要返回则用。

【例2】代码实例

class Dog:
    def  __init__(self,name,color,weight):
        =name
        =color
        =weight

    def run(self):            
        print('它想要运动')
    def eat(self,food):
        if food == '冻干':
            +=1
            print('它喜欢吃冻干,所以它的体重增加至{}kg'.format())
        else:
            print('它不喜欢吃冻干,所以它的体重依旧是{}kg'.format())
    def sleep(self):
        print('它名字是{},颜色是{},它现在想要睡觉'.format(,))
           
dog1=Dog('小七','黄色',20)

print()
print()
print()
()
('冻干')
()

输出为:

小七
黄色
20
它想要运动
它喜欢吃冻干,所以它的体重增加至21kg
它名字是小七,颜色是黄色,它现在想要睡觉

(二)类方法

在Python中,类方法要使用修饰器 @classmethod来标识,其语法格式如下:

class 类名:
    @classmethod
    def 类方法名(cls):
    方法体

其中类方法的第一个参数为cls,它代表类本身,可以通过cls来访问类的属性。一般如果某个方法体只涉及访问类属性,那么可以将这种方法定义为类方法。

【例3】代码实例

class Dog:
    weight=20
    @classmethod
    
    def wei(cls):
        return() 
        
    def __init__(self):
        +=1     #类属性的值增加
           
dog1=Dog()
print(())   #实例对象调用类方法
print(())    #类对象调用类方法

输出为:

21
21

(三)静态方法

 在Python中,类方法要使用修饰器 @staticmethod来标识,其语法格式如下:

class 类名:
    @staticmethod
    def 静态方法名():
    方法体

其中,静态方法的参数列表没有任何参数;没有self函数,导致其无法访问类的实例属性;没有cls参数,导致无法访问类属性。得出结论,静态方法与定义它的类没有直接关系,只是起到类似于函数的作用。使用静态方法可以通过以下两种方式:一是可以通过对象名调用,二是可以通过类名调用。

【例4】代码实例

class Dog:
    @staticmethod
    def run(time):
        speed=100/time
        print('小七的百米跑步平均速度是{:.3f}m/s'.format(speed))

xiaoqi=Dog()
(12)

输出为:

小七的百米跑步平均速度是8.333m/s

静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,即在静态方法中,不会涉及类中的属性和方法的操作。

(四)小结

1、需要操作实例属性值时,使用实例方法,此种方法也是最常用方法。

2、当方法中只涉及需要操作类属性值时,可以使用类方法。

3、需要提供一些功能但不需要操作类属性和实例属性时,使用静态方法。

三、属性

(一)实例属性

实例属性用来刻画实例对象的特征,用实例变量来表征,在类内部用self进行访问,并且定义在构造方法__init__()中,用来对各个实例对象进行初始化,在创建对象时自动调用。语法格式如下:

def __init__(self,[arg1,arg2,...])
    self.arg1=value1
    self.arg2=value2
    ...

用双下划线作为前缀和后缀的方法,成为类的专有方法,可以用dir()函数查看。

类的专有方法表如下所示。

方法 说明
__init__  构造函数,在生成对象时调用【常用】
__del__  析构函数,释放对象时使用【常用】
__str__ 打印字符串【常用】
__repr__ 打印,转换
__setitem__ 按照索引赋值
__getitem__ 按照索引获取值
__len__ 获得长度
__cmp__ 比较运算
__call__ 函数调用
__add__ 加运算
__sub__ 减运算
__mul__ 乘运算
__truediv__ 除运算
__mod__ 求余运算
__pow__ 乘方

【例5】类的专有方法代码实例

class Dog:
    #构造方法在创建对象时自动调用
    def  __init__(self,name,color,weight):
        =name
        =color
        =weight
        
    #在删除对象或者整个程序结束时自动调用
    def __del__(self):
        print('内存空间被系统收回')
        
    #在打印对象时自动调用
    def __str__(self):            
        print('它的名字叫{},颜色是{},体重是{}'.format(,,))

           
dog1=Dog('小七','黄色',20)
dog1.__str__()

输出为:

内存空间被系统收回
它的名字叫小七,颜色是黄色,体重是20

(二)类属性

Python中,类本身其实也是一种对象,都继承于object类,类属性就是用来刻画类对象的特征的,在类的内部用类名进行访问,直接定义在类的内部即可。在类外部可以用对象名访问,也可以用类名访问。类名访问类属性可以直接修改类属性的值 ,但实例对象访问类属性,修改值的时候无法直接修改,而会在对象内存空间中新建一个与类属性同名的变量。

【例6】代码实例

class Dog:
    #类变量:表征类自身特有属性
    name = "小七"

    def kid(self):
        print("它的名字是{}".format())


dog1 = Dog()
dog2 = Dog()
print("使用实例对象调用类变量:", , )
print("使用类对象调用类变量:", )
()
 = "小六"
print("使用实例对象调用类变量:", , )
print("使用类对象调用类变量:", )
()

输出为:

使用实例对象调用类变量: 小七 小七
使用类对象调用类变量: 小七
它的名字是小七
使用实例对象调用类变量: 小六 小七
使用类对象调用类变量: 小七
它的名字是小七

四、面向对象特征

(一)封装

在面向对象编程中,封装就是将抽象得到的数据和行为相结合,形成一个有机体(即类)。封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只要通过外部接口、特定的访问权限来使用类的成员,类似于黑匣子。

【例7】类的私有属性实例

class Dog:
    __age = 7          # 私有变量
    color = '黄色'    # 公开变量
 
    def info(self):
        self.__age += 1
        print (self.__age)
 
dog1 = Dog()
()
()
print ()
print (dog1.__age)  # 报错,实例不能访问私有变量

输出为:

8
9
黄色
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-119-cfbe743ae96a> in <module>
     11 ()
     12 print ()
---> 13 print (dog1.__age)  # 报错,实例不能访问私有变量

AttributeError: 'Dog' object has no attribute '__age'

【例8】封装代码实例

class Dog:
    def __init__(self, name, age, color,weight):
         = name
        self.__age = age
        self.__color = color
        self.__weight = weight
    def dog_name(self):
        print('它的名字是{}'.format())
    def dog_age(self):
        print('它的年龄是{}岁'.format(self.__age))
    def dog_color(self):
        print('它的颜色是{}'.format(self.__color))
    def dog_color(self):
        print('它的颜色是{}'.format(self.__color))
    def __dogweight(self):          # 私有方法
        print('这是私有方法')
    def dog_weight(self):            # 公共方法
        print('这是公共方法',end=" ")
        print('它的体重是{}'.format(self.__weight))

        
        
dog1 = Dog('小七', 7,'黄色',20)
dog1.dog_name()
dog1.dog_age()
dog1.dog_color()
dog1.dog_weight()
dog1.__dogweight() #会报错

输出为:

它的名字是小七
它的年龄是7岁
它的颜色是黄色
这是公共方法 它的体重是20
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-136-3e8851f447f1> in <module>
     26 dog1.dog_color()
     27 dog1.dog_weight()
---> 28 dog1.__weight() #会报错

AttributeError: 'Dog' object has no attribute '__weight'

访问私有化和方法的格式:

对象名._类名__私有变量名
对象名._类名__私有方法名()

将上例中的dog1.__dogweight()改为dog1._Dog__dogweight(),则不会报错

(二)继承

1、单继承

类的继承是指在一个现有类的基础上构建一个新的类(派生类),枸建出来的新类被称作子类,现有类被称为父类(基类),子类会自动拥有父类的属性和方法。
继承:一个派生类(derived class)继承基类(base class)的属性和方法。
在Python中,单继承的语法格式如下:

class 子类名(父类名):
    pass

单继承指的是当前定义的子类只有一个父类。假设当前有两个类,son是father的子类。

class father(object):
    pass
class son(father):
    pass

注:(1)如果类的定义中没有标注出父类,则这个类默认继承至object类。例如class father和class father(object)是等价的,括号可以省略。

(2)pass是空语句,是为了保持程序完整性。

【例9】代码实例

class Animal:
    def __init__(self, name, color):
         = name
         = color

    def eat(self):
        print("吃")
    def run(self):
        print("{}喜欢和我一起跑步".format())

class Dog(Animal):
    def bark(self):
        print("汪汪汪")

# 父类对象
animal = Animal("小七", "黄色")
()
print("{}的{}".format(, ))
# 子类对象
dog1 = Dog("小六", "黑色")
()
()
print("{}的{}是{}的{}的姐姐".format(, ,,))

输出为:

小七喜欢和我一起跑步
黄色的小七
小六喜欢和我一起跑步
汪汪汪
黑色的小六是黄色的小七的姐姐

2、多继承

在Python中,有时一个子类可能会有多个父类,这就是多继承,并且具有它们各个父类的方法和属性。多继承语法格式如下:

class 子类名(父类名1,父类名2,...):

【例10】代码实例

class Father:
    IQ = 150
    def f_character(self):
        return "有责任,有担当"
class Mother:
    appearance = "漂亮"
    def m_character(self):
        return "善良,体贴"

class Son(Mother, Father):
    def character(self):
        return "有理想、有道德、有文化、有纪律"

son = Son()
print("我继承了父亲的%s的智商,母亲%s的样子" % (, ))
print("我继承了父亲%s的性格,母亲%s的性格,\n我自己要做一个%s的青年" %
       (son.f_character(), son.m_character(),()))

输出为:

我继承了父亲的150的智商,母亲漂亮的样子
我继承了父亲有责任,有担当的性格,母亲善良,体贴的性格,
我自己要做一个有理想、有道德、有文化、有纪律的青年

需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索。即方法在子类中找到时,那就直接访问子类中的,在子类中未找到时,从左到右查找父类中是否包含方法。

3、方法重写

附:此处参考菜鸟系列教程Python 子类继承父类构造函数说明 | ()

(1)情况一:子类需要自动调用父类的方法:子类不重写__init__()方法,实例化子类后,会自动调用父类的__init__()的方法。

class Father(object):
    def __init__(self, name):
        =name
        print ( "name: %s" %( ) )
    def getName(self):
        return 'Father ' + 
 
class Son(Father):
    def getName(self):
        return 'Son '+
 
if __name__=='__main__':
    son=Son('runoob')
    print ( () )

输出为:

name: runoob
Son runoob

(2)情况二:子类不需要自动调用父类的方法:子类重写__init__()方法,实例化子类后,将不会自动调用父类的__init__()的方法。

class Father(object):
    def __init__(self, name):
        =name
        print ( "name: %s" %( ) )
    def getName(self):
        return 'Father ' + 
 
class Son(Father):
    def __init__(self, name):
        print ( "hi" )
         =  name
    def getName(self):
        return 'Son '+
 
if __name__=='__main__':
    son=Son('runoob')
    print ( () )

输出为:

hi
Son runoob

(3)情况三:子类重写__init__()方法又需要调用父类的方法:使用super关键词:

class Father(object):
    def __init__(self, name):
        =name
        print ( "name: %s" %( ))
    def getName(self):
        return 'Father ' + 
 
class Son(Father):
    def __init__(self, name):
        super(Son, self).__init__(name)
        print ("hi")
         =  name
    def getName(self):
        return 'Son '+
 
if __name__=='__main__':
    son=Son('runoob')
    print ( () )

输出为:

name: runoob
hi
Son runoob

五、结语

祝大家学业顺利!!!

小七是我家的一只狗狗,超级喜欢它,可惜它去世了。

参考资料

[1] 周芳, 陈建雄, 朱友康. Python语言程序设计基础教程[M]. 北京: 清华大学出版社, 2023.

[2] Python3 面向对象 | ()

附:这两份资料都是本人在学习过程中认为十分好的参考资料,推荐给大家。