当前位置:   article > 正文

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

python 面向对象编程

目录

一、类和对象

(一)类的概念

(二)对象的概念

(三)类的设计

(四)类和对象的创建

二、方法

(一)实例方法【常用】

(二)类方法

(三)静态方法

(四)小结

三、属性

(一)实例属性

(二)类属性

四、面向对象特征

(一)封装

(二)继承

1、单继承

2、多继承

3、方法重写

五、结语

参考资料


一、类和对象

(一)类的概念

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

(二)对象的概念

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

(三)类的设计

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

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

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

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

(四)类和对象的创建

  1. class 类名
  2. 类的属性
  3. 类的方法

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

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

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

【例1】代码实例

  1. class Dog:
  2. #类的属性
  3. species='puppy'
  4. #类的方法
  5. def run(self):
  6. print('它想要运动')
  7. def eat(self):
  8. print('它想要吃饭')
  9. def sleep(self):
  10. print('它想要睡觉')
  11. #实例化类:对象名=类名()
  12. dog1=Dog()
  13. #访问类的属性:对象名.属性名
  14. #访问类的方法:对象名.方法名()
  15. print(dog1.species)
  16. dog1.run()
  17. dog1.eat()
  18. dog1.sleep()
'
运行

输出为

  1. puppy
  2. 它想要运动
  3. 它想要吃饭
  4. 它想要睡觉

二、方法

(一)实例方法【常用】

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

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

  1. def 方法名(self,方法参数)
  2. 方法体
  3. return 返回值

语法说明如下:

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

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

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

【例2】代码实例

  1. class Dog:
  2. def __init__(self,name,color,weight):
  3. self.name=name
  4. self.color=color
  5. self.weight=weight
  6. def run(self):
  7. print('它想要运动')
  8. def eat(self,food):
  9. if food == '冻干':
  10. self.weight+=1
  11. print('它喜欢吃冻干,所以它的体重增加至{}kg'.format(self.weight))
  12. else:
  13. print('它不喜欢吃冻干,所以它的体重依旧是{}kg'.format(self.weight))
  14. def sleep(self):
  15. print('它名字是{},颜色是{},它现在想要睡觉'.format(self.name,self.color))
  16. dog1=Dog('小七','黄色',20)
  17. print(dog1.name)
  18. print(dog1.color)
  19. print(dog1.weight)
  20. dog1.run()
  21. dog1.eat('冻干')
  22. dog1.sleep()
'
运行

输出为:

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

(二)类方法

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

  1. class 类名:
  2. @classmethod
  3. def 类方法名(cls):
  4. 方法体

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

【例3】代码实例

  1. class Dog:
  2. weight=20
  3. @classmethod
  4. def wei(cls):
  5. return(cls.weight)
  6. def __init__(self):
  7. Dog.weight+=1 #类属性的值增加
  8. dog1=Dog()
  9. print(dog1.wei()) #实例对象调用类方法
  10. print(Dog.wei()) #类对象调用类方法
'
运行

输出为:

  1. 21
  2. 21
'
运行

(三)静态方法

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

  1. class 类名:
  2. @staticmethod
  3. def 静态方法名():
  4. 方法体

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

【例4】代码实例

  1. class Dog:
  2. @staticmethod
  3. def run(time):
  4. speed=100/time
  5. print('小七的百米跑步平均速度是{:.3f}m/s'.format(speed))
  6. xiaoqi=Dog()
  7. xiaoqi.run(12)
'
运行

输出为:

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

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

(四)小结

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

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

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

三、属性

(一)实例属性

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

  1. def __init__(self,[arg1,arg2,...])
  2. self.arg1=value1
  3. self.arg2=value2
  4. ...

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

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

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

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

  1. class Dog:
  2. #构造方法在创建对象时自动调用
  3. def __init__(self,name,color,weight):
  4. self.name=name
  5. self.color=color
  6. self.weight=weight
  7. #在删除对象或者整个程序结束时自动调用
  8. def __del__(self):
  9. print('内存空间被系统收回')
  10. #在打印对象时自动调用
  11. def __str__(self):
  12. print('它的名字叫{},颜色是{},体重是{}'.format(self.name,self.color,self.weight))
  13. dog1=Dog('小七','黄色',20)
  14. dog1.__str__()
'
运行

输出为:

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

(二)类属性

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

【例6】代码实例

  1. class Dog:
  2. #类变量:表征类自身特有属性
  3. name = "小七"
  4. def kid(self):
  5. print("它的名字是{}".format(Dog.name))
  6. dog1 = Dog()
  7. dog2 = Dog()
  8. print("使用实例对象调用类变量:", dog1.name, dog2.name)
  9. print("使用类对象调用类变量:", Dog.name)
  10. dog1.kid()
  11. dog1.name = "小六"
  12. print("使用实例对象调用类变量:", dog1.name, dog2.name)
  13. print("使用类对象调用类变量:", Dog.name)
  14. dog1.kid()
'
运行

输出为:

  1. 使用实例对象调用类变量: 小七 小七
  2. 使用类对象调用类变量: 小七
  3. 它的名字是小七
  4. 使用实例对象调用类变量: 小六 小七
  5. 使用类对象调用类变量: 小七
  6. 它的名字是小七

四、面向对象特征

(一)封装

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

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

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

输出为:

  1. 8
  2. 9
  3. 黄色
  4. ---------------------------------------------------------------------------
  5. AttributeError Traceback (most recent call last)
  6. <ipython-input-119-cfbe743ae96a> in <module>
  7. 11 dog1.info()
  8. 12 print (dog1.color)
  9. ---> 13 print (dog1.__age) # 报错,实例不能访问私有变量
  10. AttributeError: 'Dog' object has no attribute '__age'

【例8】封装代码实例

  1. class Dog:
  2. def __init__(self, name, age, color,weight):
  3. self.name = name
  4. self.__age = age
  5. self.__color = color
  6. self.__weight = weight
  7. def dog_name(self):
  8. print('它的名字是{}'.format(self.name))
  9. def dog_age(self):
  10. print('它的年龄是{}岁'.format(self.__age))
  11. def dog_color(self):
  12. print('它的颜色是{}'.format(self.__color))
  13. def dog_color(self):
  14. print('它的颜色是{}'.format(self.__color))
  15. def __dogweight(self): # 私有方法
  16. print('这是私有方法')
  17. def dog_weight(self): # 公共方法
  18. print('这是公共方法',end=" ")
  19. print('它的体重是{}'.format(self.__weight))
  20. dog1 = Dog('小七', 7,'黄色',20)
  21. dog1.dog_name()
  22. dog1.dog_age()
  23. dog1.dog_color()
  24. dog1.dog_weight()
  25. dog1.__dogweight() #会报错

输出为:

  1. 它的名字是小七
  2. 它的年龄是7
  3. 它的颜色是黄色
  4. 这是公共方法 它的体重是20
  5. ---------------------------------------------------------------------------
  6. AttributeError Traceback (most recent call last)
  7. <ipython-input-136-3e8851f447f1> in <module>
  8. 26 dog1.dog_color()
  9. 27 dog1.dog_weight()
  10. ---> 28 dog1.__weight() #会报错
  11. AttributeError: 'Dog' object has no attribute '__weight'

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

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

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

(二)继承

1、单继承

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

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

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

  1. class father(object):
  2. pass
  3. class son(father):
  4. pass

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

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

【例9】代码实例

  1. class Animal:
  2. def __init__(self, name, color):
  3. self.name = name
  4. self.color = color
  5. def eat(self):
  6. print("吃")
  7. def run(self):
  8. print("{}喜欢和我一起跑步".format(self.name))
  9. class Dog(Animal):
  10. def bark(self):
  11. print("汪汪汪")
  12. # 父类对象
  13. animal = Animal("小七", "黄色")
  14. animal.run()
  15. print("{}的{}".format(animal.color, animal.name))
  16. # 子类对象
  17. dog1 = Dog("小六", "黑色")
  18. dog1.run()
  19. dog1.bark()
  20. print("{}的{}是{}的{}的姐姐".format(dog1.color, dog1.name,animal.color,animal.name))
'
运行

输出为:

  1. 小七喜欢和我一起跑步
  2. 黄色的小七
  3. 小六喜欢和我一起跑步
  4. 汪汪汪
  5. 黑色的小六是黄色的小七的姐姐

2、多继承

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

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

【例10】代码实例

  1. class Father:
  2. IQ = 150
  3. def f_character(self):
  4. return "有责任,有担当"
  5. class Mother:
  6. appearance = "漂亮"
  7. def m_character(self):
  8. return "善良,体贴"
  9. class Son(Mother, Father):
  10. def character(self):
  11. return "有理想、有道德、有文化、有纪律"
  12. son = Son()
  13. print("我继承了父亲的%s的智商,母亲%s的样子" % (son.IQ, son.appearance))
  14. print("我继承了父亲%s的性格,母亲%s的性格,\n我自己要做一个%s的青年" %
  15. (son.f_character(), son.m_character(),son.character()))
'
运行

输出为:

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

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

3、方法重写

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

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

  1. class Father(object):
  2. def __init__(self, name):
  3. self.name=name
  4. print ( "name: %s" %( self.name) )
  5. def getName(self):
  6. return 'Father ' + self.name
  7. class Son(Father):
  8. def getName(self):
  9. return 'Son '+self.name
  10. if __name__=='__main__':
  11. son=Son('runoob')
  12. print ( son.getName() )
'
运行

输出为:

  1. name: runoob
  2. Son runoob

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

  1. class Father(object):
  2. def __init__(self, name):
  3. self.name=name
  4. print ( "name: %s" %( self.name) )
  5. def getName(self):
  6. return 'Father ' + self.name
  7. class Son(Father):
  8. def __init__(self, name):
  9. print ( "hi" )
  10. self.name = name
  11. def getName(self):
  12. return 'Son '+self.name
  13. if __name__=='__main__':
  14. son=Son('runoob')
  15. print ( son.getName() )
'
运行

输出为:

  1. hi
  2. Son runoob

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

  1. class Father(object):
  2. def __init__(self, name):
  3. self.name=name
  4. print ( "name: %s" %( self.name))
  5. def getName(self):
  6. return 'Father ' + self.name
  7. class Son(Father):
  8. def __init__(self, name):
  9. super(Son, self).__init__(name)
  10. print ("hi")
  11. self.name = name
  12. def getName(self):
  13. return 'Son '+self.name
  14. if __name__=='__main__':
  15. son=Son('runoob')
  16. print ( son.getName() )
'
运行

输出为:

  1. name: runoob
  2. hi
  3. Son runoob

五、结语

祝大家学业顺利!!!

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

参考资料

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

[2] Python3 面向对象 | 菜鸟教程 (runoob.com)

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

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/829579
推荐阅读
相关标签
  

闽ICP备14008679号