【人生苦短,我学 Python】进阶篇——类与继承(Day14)
写在前面:大家好!我是【AI 菌】,一枚爱弹吉他的程序员。我
热爱AI、热爱分享、热爱开源
! 这博客是我对学习的一点总结与记录。如果您也对深度学习、机器视觉、算法、Python、C++
感兴趣,可以关注我的动态,我们一起学习,一起进步~
我的博客地址为:【AI 菌】的博客
我的Github项目地址是:【AI 菌】的Github
一、类
(1) 什么是类
Python是一种面向对象的编程语言。在面向对象编程中,我们会编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。
编写类时,你需要定义一大类对象都有的通用行为。基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。
根据类来创建对象被称为实例化 ,这让你能够使用类的实例。通过本文,你将学习到一下一些内容:
- 编写一些类并创建其实例
- 指定可在实例中存储什么信息,定义可对这些实例执行哪些操作
- 编写一些类来扩展既有类的功能,让相似的类能够高效地共享代码
- 编写的类存储在模块中,并在自己的程序文件中导入其他程序员编写的类
(2) 创建类
使用类几乎可以模拟任何东西。下面来编写一个表示人类的简单类 Human —— 它表示的不是特定的人,而是任何人。
任何人都有名字name和年龄age,我们就可以用name和age来简单地描述Human的属性;任何人都会吃东西eating和运动exercise,所以这些行为可以描述Human的通用方法。
我们在类中封装好这些属性和方法,就能简单地构建一个Human类了。如下所示:
class Human(): """模拟创建人""" def __init__(self, name, age): """初始化属性name和age""" self.name = name self.age = age def eat(self): """模拟吃东西""" print(self.name + "is eating") def exercise(self): """模拟运动""" print(self.name + "is doing some sports")
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
下面来着重解释一下,创建类过程中的一些重要步骤:
def __init__(self, name, age):
,这是构造函数。每当你使用 Human 类创建新实例时,Python 都会自动运行它。在构造函数的定义中,形参 self 必不可少,还必须位于其他形参的前面。这是因为 Python 调用这个__init__()
方法来创建 Human 实例时,将自动传入实参 self 。每个与类相关联的方法调用都自动传递实参 self ,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。- 5、6行分别定义的两个变量都有前缀 self 。以 self 为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。 self.name = name 获取存储在形参 name 中的值,并将其存储到变量 name 中,然后该变量被关联到当前创建的实例。 self.age = age 的作用与此类似。像这样可通过实例访问的变量称为属性 。
- Human 类还定义了另外两个方法: eat() 和 exercise() 。由于这些方法不需要额外的信息,如名字或年龄,因此它们只有一个形参 self 。我们后面将创建的实例能够访问这些方法。
(3) 创建实例
创建好了一个类,并不代表你在程序中就执行了该类。类真正起作用的时候,是其实例化的过程。下面来创建一个表示特定人的实例对象:
# 创建实例
man = Human("AI Jun", 18)
- 1
- 2
创建实例对象后,我们可以访问其属性和方法了:
1、访问属性。要访问实例的属性,可使用句点表示法,使用方法如下:
# 创建实例
man = Human("AI Jun", 18)
# 访问类属性:name和age
print(man.name + " is " + str(man.age) + " years old.")
- 1
- 2
- 3
- 4
程序输出结果:
AI Jun is 18 years old.
- 1
2、调用方法。根据 Human 类创建实例后,就可以使用句点表示法来调用 Human 类中定义的任何方法。下面来让AI Jun 吃东西(eat)和运动(exercise):
# 创建实例
man = Human("AI Jun", 18)
# 调用方法
man.eat()
man.exercise()
- 1
- 2
- 3
- 4
- 5
程序输出结果:
AI Jun is eating
AI Jun is doing some sports
- 1
- 2
二、继承
(1) 什么是继承
编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用 继承 。一个类 继承 另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为 父类 ,而新类称为 子类 。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
(2) 创建继承
创建子类的实例时, Python 首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法 __init__()
需要父类施以援手。
下面我们来创建Human类的一个子类——超人类SuperMan。超人是一类特殊的人,拥有着和Human类一样的属性和方法,但是SuperMan类会一些特异功能,比如会飞fly()。
因此我们可以在前面创建的 Human 类的基础上创建新的SuperMan类,这样我们就只需为电动汽车特有的属性和行为编写代码。
下面来创建一个简单的 SuperMan类,它继承了 Human 类的所有功能:
# 声明父类
class Human(): """模拟创建人""" def __init__(self, name, age): """初始化属性name和age""" self.name = name self.age = age def eat(self): """模拟吃东西""" print(self.name + "is eating") def exercise(self): """模拟运动""" print(self.name + "is doing some sports")
# 创建子类
class SuperMan(Human): """模拟创建超人""" def __init__(self, name, age): """ 初始化父类的属性""" super().__init__(name, age) # 新增属性 self.weight = 60 # 新增方法 def fly(self): """模拟飞行""" print(self.name + " is flying")
# 子类实例化
super_man = SuperMan('SteelMan', 20)
# 访问子类属性
print(super_man.name + " is " + str(super_man.weight) + " kg")
# 调用子类方法
super_man.fly()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
程序输出:
SteelMan is 60 kg
SteelMan is flying
- 1
- 2
定义子类时,必须在括号内指定父类的名称。super()
是一个特殊函数,它帮助 Python 将父类和子类关联起来。这行代码让 Python 调用 SuperMan 的父类的方法 __init__()
,让 SuperMan 实例包含父类的所有属性。父类也称为超类(superclass),名称 super 因此而得名。
(3) 重写父类方法
有的情况下,子类并不需要严格继承父类的方法,这个时候可以在子类中,对部分方法进行重写,给方法与父类方法同名。这样, Python 将不会考虑这个父类方法,而只关注你在子类中定义的相应的方法。
比如在上面的例子中,父类Human有着一个方法eat(),但是超人并不需要吃饭,因此在定义子类时,我们可以对其方法进行重写。下面演示了一下这种重写方式:
# 创建子类
class SuperMan(Human): """模拟创建超人""" def __init__(self, name, age): """ 初始化父类的属性""" super().__init__(name, age) # 新增属性 self.weight = 60 # 重写方法 def eat(self): print("Superman doesn't need to eat !")
# 实例化
super_man = SuperMan('SteelMan', 20)
# 调用子类重写方法
super_man.eat()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
重写eat()后,如果再调用方法 eat() , Python 将忽略父类中的方法,转而运行上述代码。程序输出如下:
Superman doesn't need to eat !
- 1
三、导入类
为了使代码尽可能地整洁, Python 允许你将类存储在模块中,然后在主程序中导入所需的模块。
(1) 导入单个类
我们先将上述类存放在一个名为human.py的文件中,也可以将此文件称之为模块。文件中内容如下:
"""一个用来模拟人的类"""
# 声明父类
class Human(): """模拟创建人""" def __init__(self, name, age): """初始化属性name和age""" self.name = name self.age = age def eat(self): """模拟吃东西""" print(self.name + "is eating") def exercise(self): """模拟运动""" print(self.name + "is doing some sports")
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
接下来,我们想在主程序文件main.py中导入这个类,并实例化对象:
# 从模块中导入类
from human import Human
# 实例化对象
man = Human("AI Jun", 18)
# 调用方法
man.eat()
- 1
- 2
- 3
- 4
- 5
- 6
(2) 从一个模块中导入多个类
通常,在一个模块中,会包含一些功能相关联的几个类。在下面的human.py模块中,存在两个类:一个父类Human和一个子类SuperMan。
# 声明父类
class Human(): """模拟创建人""" def __init__(self, name, age): """初始化属性name和age""" self.name = name self.age = age def eat(self): """模拟吃东西""" print(self.name + " is eating") def exercise(self): """模拟运动""" print(self.name + " is doing some sports")
# 创建子类
class SuperMan(Human): """模拟创建超人""" def __init__(self, name, age): """ 初始化父类的属性""" super().__init__(name, age) # 新增属性 self.weight = 60 # 新增方法 def fly(self): """模拟飞行""" print(self.name + " is flying") # 重写方法 def eat(self): print("Superman doesn't need to eat !")
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
接下来,我们在主程序文件main.py中来导入这两个类,并实例化对象:
from human import Human, SuperMan
man = Human("AI Jun", 18)
superman = SuperMan("SteelMan", 200)
man.eat()
superman.eat()
- 1
- 2
- 3
- 4
- 5
程序输出:
AI Jun is eating
Superman doesn't need to eat !
- 1
- 2
当需要导入一个模块中的所有类时,可以直接用*
号代替所有的类名:
from 模块名 import *
- 1
但是,在实际开发过程中,不太建议使用这种方法。因为如果你不小心导入了一个与程序文件中其他东西同名的类,将引发难以诊断的错误。
注:同时导入多个类时,要用逗号分隔了各个类。
由于水平有限,博客中难免会有一些错误,有纰漏之处恳请各位大佬不吝赐教!
文章来源: ai-wx.blog.csdn.net,作者:AI 菌,版权归原作者所有,如需转载,请联系作者。
原文链接:ai-wx.blog.csdn.net/article/details/113785655
- 点赞
- 收藏
- 关注作者
评论(0)