赞
踩
目录
类是具有相同特征和行为的一类事物的统称。在类的创建过程中会将事物的特征映射成为属性,会将事物的行为映射成为方法,即定义了该集合中每个对象所共有的属性和方法。所以可以说类是用来描述具有相同的属性和方法的对象的集合
类是抽象的,它不能直接使用,对象是由类创建出来的实例,用来描述客观事物,是具体的,可以直接使用。
类的设计有三要素,分别是类名、类的属性、类的方法。
1、类名:采用大骆驼峰的命名方式,eg.MyFamily、YourName。
2、类的属性:将某类事物的特征抽象为类的属性,而每一种属性在类中的表现形式就是变量。
3、类的方法:将某类事物的行为抽象为类的方法 ,方法即为定义在类中的函数。
- class 类名:
- 类的属性
- 类的方法
实例化类:对象名=类名()
访问类的属性:对象名.属性名
访问类的方法:对象名.方法名()
【例1】代码实例
- class Dog:
- #类的属性
- species='puppy'
- #类的方法
- def run(self):
- print('它想要运动')
- def eat(self):
- print('它想要吃饭')
- def sleep(self):
- print('它想要睡觉')
-
- #实例化类:对象名=类名()
- dog1=Dog()
-
- #访问类的属性:对象名.属性名
- #访问类的方法:对象名.方法名()
- print(dog1.species)
- dog1.run()
- dog1.eat()
- dog1.sleep()
'运行
输出为
- puppy
- 它想要运动
- 它想要吃饭
- 它想要睡觉
附:类有一个名为 __init__() 的构造方法,该方法在类实例化时会自动调用。如果类中的构造方法__init__()有对应的实例属性,则创建对象时还需要给实例属性进行初始化,后面详细讲解。
使用 def 关键字来定义一个方法,与一般函数定义不同,类的实例方法必须包含self,self代表类的实例,且self是第一个参数。
- def 方法名(self,方法参数)
- 方法体
- return 返回值
语法说明如下:
(1)实例方法必须创建在类中。
(2)方法第一个参数是self,代表对象本身。
(3)“return 返回值”可有可无,需要返回则用。
【例2】代码实例
- class Dog:
- def __init__(self,name,color,weight):
- self.name=name
- self.color=color
- self.weight=weight
-
- def run(self):
- print('它想要运动')
- def eat(self,food):
- if food == '冻干':
- self.weight+=1
- print('它喜欢吃冻干,所以它的体重增加至{}kg'.format(self.weight))
- else:
- print('它不喜欢吃冻干,所以它的体重依旧是{}kg'.format(self.weight))
- def sleep(self):
- print('它名字是{},颜色是{},它现在想要睡觉'.format(self.name,self.color))
-
- dog1=Dog('小七','黄色',20)
-
- print(dog1.name)
- print(dog1.color)
- print(dog1.weight)
- dog1.run()
- dog1.eat('冻干')
- dog1.sleep()
'运行
输出为:
- 小七
- 黄色
- 20
- 它想要运动
- 它喜欢吃冻干,所以它的体重增加至21kg
- 它名字是小七,颜色是黄色,它现在想要睡觉
在Python中,类方法要使用修饰器 @classmethod来标识,其语法格式如下:
- class 类名:
- @classmethod
- def 类方法名(cls):
- 方法体
其中类方法的第一个参数为cls,它代表类本身,可以通过cls来访问类的属性。一般如果某个方法体只涉及访问类属性,那么可以将这种方法定义为类方法。
【例3】代码实例
- class Dog:
- weight=20
- @classmethod
-
- def wei(cls):
- return(cls.weight)
-
- def __init__(self):
- Dog.weight+=1 #类属性的值增加
-
- dog1=Dog()
- print(dog1.wei()) #实例对象调用类方法
- print(Dog.wei()) #类对象调用类方法
'运行
输出为:
- 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()
- xiaoqi.run(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):
- self.name=name
- self.color=color
- self.weight=weight
-
- #在删除对象或者整个程序结束时自动调用
- def __del__(self):
- print('内存空间被系统收回')
-
- #在打印对象时自动调用
- def __str__(self):
- print('它的名字叫{},颜色是{},体重是{}'.format(self.name,self.color,self.weight))
-
-
- dog1=Dog('小七','黄色',20)
- dog1.__str__()
'运行
输出为:
- 内存空间被系统收回
- 它的名字叫小七,颜色是黄色,体重是20
Python中,类本身其实也是一种对象,都继承于object类,类属性就是用来刻画类对象的特征的,在类的内部用类名进行访问,直接定义在类的内部即可。在类外部可以用对象名访问,也可以用类名访问。类名访问类属性可以直接修改类属性的值 ,但实例对象访问类属性,修改值的时候无法直接修改,而会在对象内存空间中新建一个与类属性同名的变量。
【例6】代码实例
- class Dog:
- #类变量:表征类自身特有属性
- name = "小七"
-
- def kid(self):
- print("它的名字是{}".format(Dog.name))
-
-
- dog1 = Dog()
- dog2 = Dog()
- print("使用实例对象调用类变量:", dog1.name, dog2.name)
- print("使用类对象调用类变量:", Dog.name)
- dog1.kid()
- dog1.name = "小六"
- print("使用实例对象调用类变量:", dog1.name, dog2.name)
- print("使用类对象调用类变量:", Dog.name)
- dog1.kid()
'运行
输出为:
- 使用实例对象调用类变量: 小七 小七
- 使用类对象调用类变量: 小七
- 它的名字是小七
- 使用实例对象调用类变量: 小六 小七
- 使用类对象调用类变量: 小七
- 它的名字是小七
在面向对象编程中,封装就是将抽象得到的数据和行为相结合,形成一个有机体(即类)。封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只要通过外部接口、特定的访问权限来使用类的成员,类似于黑匣子。
【例7】类的私有属性实例
- class Dog:
- __age = 7 # 私有变量
- color = '黄色' # 公开变量
-
- def info(self):
- self.__age += 1
- print (self.__age)
-
- dog1 = Dog()
- dog1.info()
- dog1.info()
- print (dog1.color)
- print (dog1.__age) # 报错,实例不能访问私有变量
输出为:
- 8
- 9
- 黄色
- ---------------------------------------------------------------------------
- AttributeError Traceback (most recent call last)
- <ipython-input-119-cfbe743ae96a> in <module>
- 11 dog1.info()
- 12 print (dog1.color)
- ---> 13 print (dog1.__age) # 报错,实例不能访问私有变量
-
- AttributeError: 'Dog' object has no attribute '__age'
【例8】封装代码实例
- class Dog:
- def __init__(self, name, age, color,weight):
- self.name = name
- self.__age = age
- self.__color = color
- self.__weight = weight
- def dog_name(self):
- print('它的名字是{}'.format(self.name))
- 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(),则不会报错
类的继承是指在一个现有类的基础上构建一个新的类(派生类),枸建出来的新类被称作子类,现有类被称为父类(基类),子类会自动拥有父类的属性和方法。
继承:一个派生类(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):
- self.name = name
- self.color = color
-
- def eat(self):
- print("吃")
- def run(self):
- print("{}喜欢和我一起跑步".format(self.name))
-
- class Dog(Animal):
- def bark(self):
- print("汪汪汪")
-
- # 父类对象
- animal = Animal("小七", "黄色")
- animal.run()
- print("{}的{}".format(animal.color, animal.name))
- # 子类对象
- dog1 = Dog("小六", "黑色")
- dog1.run()
- dog1.bark()
- print("{}的{}是{}的{}的姐姐".format(dog1.color, dog1.name,animal.color,animal.name))
'运行
输出为:
- 小七喜欢和我一起跑步
- 黄色的小七
- 小六喜欢和我一起跑步
- 汪汪汪
- 黑色的小六是黄色的小七的姐姐
在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的样子" % (son.IQ, son.appearance))
- print("我继承了父亲%s的性格,母亲%s的性格,\n我自己要做一个%s的青年" %
- (son.f_character(), son.m_character(),son.character()))
'运行
输出为:
- 我继承了父亲的150的智商,母亲漂亮的样子
- 我继承了父亲有责任,有担当的性格,母亲善良,体贴的性格,
- 我自己要做一个有理想、有道德、有文化、有纪律的青年
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索。即方法在子类中找到时,那就直接访问子类中的,在子类中未找到时,从左到右查找父类中是否包含方法。
附:此处参考菜鸟系列教程Python 子类继承父类构造函数说明 | 菜鸟教程 (runoob.com)
(1)情况一:子类需要自动调用父类的方法:子类不重写__init__()方法,实例化子类后,会自动调用父类的__init__()的方法。
- class Father(object):
- def __init__(self, name):
- self.name=name
- print ( "name: %s" %( self.name) )
- def getName(self):
- return 'Father ' + self.name
-
- class Son(Father):
- def getName(self):
- return 'Son '+self.name
-
- if __name__=='__main__':
- son=Son('runoob')
- print ( son.getName() )
'运行
输出为:
- name: runoob
- Son runoob
(2)情况二:子类不需要自动调用父类的方法:子类重写__init__()方法,实例化子类后,将不会自动调用父类的__init__()的方法。
- class Father(object):
- def __init__(self, name):
- self.name=name
- print ( "name: %s" %( self.name) )
- def getName(self):
- return 'Father ' + self.name
-
- class Son(Father):
- def __init__(self, name):
- print ( "hi" )
- self.name = name
- def getName(self):
- return 'Son '+self.name
-
- if __name__=='__main__':
- son=Son('runoob')
- print ( son.getName() )
'运行
输出为:
- hi
- Son runoob
(3)情况三:子类重写__init__()方法又需要调用父类的方法:使用super关键词:
- class Father(object):
- def __init__(self, name):
- self.name=name
- print ( "name: %s" %( self.name))
- def getName(self):
- return 'Father ' + self.name
-
- class Son(Father):
- def __init__(self, name):
- super(Son, self).__init__(name)
- print ("hi")
- self.name = name
- def getName(self):
- return 'Son '+self.name
-
- if __name__=='__main__':
- son=Son('runoob')
- print ( son.getName() )
'运行
输出为:
- name: runoob
- hi
- Son runoob
祝大家学业顺利!!!
小七是我家的一只狗狗,超级喜欢它,可惜它去世了。
[1] 周芳, 陈建雄, 朱友康. Python语言程序设计基础教程[M]. 北京: 清华大学出版社, 2023.
[2] Python3 面向对象 | 菜鸟教程 (runoob.com)
附:这两份资料都是本人在学习过程中认为十分好的参考资料,推荐给大家。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。