目录
一、类和对象
(一)类的概念
(二)对象的概念
(三)类的设计
(四)类和对象的创建
二、方法
(一)实例方法【常用】
(二)类方法
(三)静态方法
(四)小结
三、属性
(一)实例属性
(二)类属性
四、面向对象特征
(一)封装
(二)继承
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 面向对象 | ()
附:这两份资料都是本人在学习过程中认为十分好的参考资料,推荐给大家。