In [6]:
# 我们建立一个有趣的简单的模仿游戏的类来说明面向对象编程的概念
# v1.0.0
# NPC 类
class NPC(object):
# 初始化 NPC 的属性
def __init__(self, name):
self.name = name
self.weapon = 'gun'
self.blood = 1000
# 定义方法 - 显示 NPC 属性
def show_properties(self):
print('name:', self.name)
print('weapon:', self.weapon)
print('blood:', self.blood)
# 定义方法 - 通用攻击
def fight_common(self):
print('Fight Common')
n1 = NPC('AA1')
n1.show_properties()
n1.fight_common()
这个 NPC 的类,在初始化这里定义了 NPC 拥有的三个属性,name、weapon、blood,其中 name 需要创建实例的时候设置。
NPC 类有两个方法,一个是 show_properties(),显示 NPC 的属性;另外一个是 fight_common(),我们称之为普通攻击。
通过 class B(A)
,即表示从 A 开始创建一个子类,我们称之为继承。
面向对象的编程方式的有点已经可以体现,我们可以通过继承来构造一个对象体系,比如这里现在 NPC 这个类中,定义了游戏中人物的最基本的一些属性和方法,可以理解不光 NPC 是战士,还是巫师,对会有这些属性和方法;然后我们把各自独特的属性和方法定义在从 NPC 中继承的各个子类中。我们先来定义一个战士 Soldier 类。
In [20]:
# 战士 Soldier 类,继承自 NPC class
class Soldier(NPC):
# 暂时什么也不干
pass
# 创建一个 Soldier 类, 作为 NPC 的子类
n1 = Soldier('AA2')
# 调用方法,因为 Soldier 中此刻并没有任何实际的方法等,所以实际上自动调用了父类的方法
n1.show_properties()
n1.fight_common()
在子类中,可以覆盖父类的方法。
比如 __init__()
,我们需要在 Soldier 类的初始化中加入一个只有 soldier 才有的级别 level 属性。
所以,我们先调用父类的__init__()
方法,再写 Soldier 类需要的代码。
而 show_properties()
方法,我们先用简单的办法,完全覆盖,也就是使用这个新的show_properties()
方法,来显示 NPC 标准的三个属性以及 Soldier 的一个独立属性。
In [7]:
# 战士 Soldier 类
class Soldier(NPC):
# 建立 soldier 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.soldier_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
print('name:', self.name)
print('weapon:', self.weapon)
print('blood:', self.blood)
print('soldier_level:', self.soldier_level)
# 创建一个 Soldier 类, 作为 NPC 的子类
n1 = Soldier('AA2')
n1.show_properties()
n1.fight_common()
再来看看 show_properties()
这个方法,总感觉这样有点笨重,因为不管是否是面向对象的编程方式,都不应该有太多重复的代码,现在 NPC 类中也有 show_properties()
方法,用来显示标准的三个属性,而 Soldier 类中同样名字的方法显示四个属性,如果 NPC 类中增加了属性,那么两边类中的这个方法都要修改。
我们来看看有没有更好的办法,可以用 super(需要知道父类的类,self) 的方法来访问父类的方法,这样代码就简洁优雅了。
In [28]:
# 战士 Soldier 类
class Soldier(NPC):
# 建立 soldier 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.soldier_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Soldier, self).show_properties()
print('soldier_level', self.soldier_level)
# 创建一个 Soldier 类, 作为 NPC 的子类
n1 = Soldier('AA2')
n1.show_properties()
n1.fight_common()
In [1]:
# 先整理一下上面的代码
# v1.0.1
# NPC 类
class NPC(object):
# 初始化 NPC 的属性
def __init__(self, name):
self.name = name
self.weapon = 'gun'
self.blood = 1000
# 定义方法 - 显示 NPC 属性
def show_properties(self):
print('name:', self.name)
print('weapon:', self.weapon)
print('blood:', self.blood)
# 定义方法 - 通用攻击
def fight_common(self):
print('Fight Common')
# 战士 Soldier 类
class Soldier(NPC):
# 建立 soldier 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.soldier_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Soldier, self).show_properties()
print('soldier_level', self.soldier_level)
In [6]:
# 创建两个 soldier
n1 = Soldier('AA1')
n1.show_properties()
n1.fight_common()
print()
n2 = Soldier('AA2')
n2.show_properties()
n2.fight_common()
In [9]:
# 连续创建多个 soldier 的实例
# 并存储在 list 中
s = []
for i in range(3):
n = Soldier('AA' + str(i))
n.show_properties()
n.fight_common()
s.append(n)
In [12]:
# 看一下存储了对象的列表
print(s)
In [7]:
# 可以和一般访问列表一样访问列表中的对象
for i in s:
print(i.name)
print(len(s))
In [8]:
# 可以删除一个实例
s.pop(1)
# 显示列表中的实例
for i in s:
print(i.name)
print(len(s))
In [10]:
# 再增加一个巫师 Wizard 的类
# 巫师 Wizard 类
class Wizard(NPC):
# 建立 Wizard 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.wizard_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Wizard, self).show_properties()
print('wizard_level', self.wizard_level)
# 定义一个巫师专用的战斗方法
def wizard_fight_magic(self):
print('Wizard Magic!')
# 创建一个 wizard
c1 = Wizard('CC1')
c1.show_properties()
c1.fight_common()
c1.wizard_fight_magic()
In [14]:
# 创建复杂的 NPC,3个 wizards,3个 soldiers
# 创建多个 soldier 的实例
s = []
for i in range(3):
n = Soldier('AA' + str(i))
n.show_properties()
s.append(n)
for i in range(3):
n = Wizard('CC' + str(i))
n.show_properties()
s.append(n)
for i in s:
print(i.name)
print('--')
In [12]:
# 显示类的方法
print(dir(Soldier))
In [13]:
# 显示类的方法
print(dir(Wizard))
In [10]:
# 当前版本的代码
# v1.0.2
# NPC 类
class NPC(object):
# 初始化 NPC 的属性
def __init__(self, name):
self.name = name
self.weapon = 'gun'
self.blood = 1000
# 定义方法 - 显示 NPC 属性
def show_properties(self):
print('name:', self.name)
print('weapon:', self.weapon)
print('blood:', self.blood)
# 定义方法 - 通用攻击
def fight_common(self):
print('Fight Common')
# 战士 Soldier 类
class Soldier(NPC):
# 建立 soldier 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.soldier_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Soldier, self).show_properties()
print('soldier_level', self.soldier_level)
# 巫师 Wizard 类
class Wizard(NPC):
# 建立 Wizard 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.wizard_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Wizard, self).show_properties()
print('wizard_level', self.wizard_level)
# 定义一个巫师专用的战斗方法
def fight_magic(self):
print('Wizard Magic!')
In [18]:
# 在 NPC 的 __init__() 加入显示创建的是什么角色
# v1.0.3
# NPC 类
class NPC(object):
# 初始化 NPC 的属性
def __init__(self, name):
self.name = name
self.weapon = 'gun'
self.blood = 1000
# 先简单的显示
print('')
print('NPC created!')
# 定义方法 - 显示 NPC 属性
def show_properties(self):
print('name:', self.name)
print('weapon:', self.weapon)
print('blood:', self.blood)
# 定义方法 - 通用攻击
def fight_common(self):
print('Fight Common')
# 战士 Soldier 类
class Soldier(NPC):
# 建立 soldier 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.soldier_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Soldier, self).show_properties()
print('soldier_level', self.soldier_level)
# 巫师 Wizard 类
class Wizard(NPC):
# 建立 Wizard 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.wizard_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Wizard, self).show_properties()
print('wizard_level', self.wizard_level)
# 定义一个巫师专用的战斗方法
def fight_magic(self):
print('Wizard Magic!')
s = []
for i in range(2):
n = Soldier('AA' + str(i))
n.show_properties()
s.append(n)
for i in range(2):
n = Wizard('CC' + str(i))
n.show_properties()
s.append(n)
In [27]:
# 但是在 NPC 这个父类中没有显示出具体的子类名称
# 所以我们用下面的方法来显示子类的名称
# type(self).__name__ 来访问类的名称
# v1.0.4
# NPC 类
class NPC(object):
# 初始化 NPC 的属性
def __init__(self, name):
self.name = name
self.weapon = 'gun'
self.blood = 1000
print('')
print(type(self).__name__, 'NPC created!')
# 定义方法 - 显示 NPC 属性
def show_properties(self):
print('name:', self.name)
print('weapon:', self.weapon)
print('blood:', self.blood)
# 定义方法 - 通用攻击
def fight_common(self):
print('Fight Common')
# 战士 Soldier 类
class Soldier(NPC):
# 建立 soldier 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.soldier_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Soldier, self).show_properties()
print('soldier_level', self.soldier_level)
# 巫师 Wizard 类
class Wizard(NPC):
# 建立 Wizard 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.wizard_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Wizard, self).show_properties()
print('wizard_level', self.wizard_level)
# 定义一个巫师专用的战斗方法
def fight_magic(self):
print('Wizard Magic!')
s = []
for i in range(2):
n = Soldier('AA' + str(i))
n.show_properties()
s.append(n)
for i in range(2):
n = Wizard('CC' + str(i))
n.show_properties()
s.append(n)
面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程范型,同时也是一种程序开发的方法。它可能包含数据、属性、代码与方法。对象则指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象。
面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反:传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。目前已经被证实的是,面向对象程序设计推广了程序的灵活性和可维护性,并且在大型项目设计中广为应用。此外,支持者声称面向对象程序设计要比以往的做法更加便于学习,因为它能够让人们更简单地设计并维护程序,使得程序更加便于分析、设计、理解。反对者在某些领域对此予以否认。
In [4]:
# 继续优化,根据 NPC 类型来设定 blood 和 weapon
# 将代码尽量集中,是有好处的
# v1.0.5
# NPC 类
class NPC(object):
# 初始化 NPC 的属性
def __init__(self, name):
self.name = name
self.npc_type = type(self).__name__
print('')
print(self.npc_type, 'NPC created!')
if self.npc_type == 'Soldier':
self.weapon = 'sword'
self.blood = 1000
if self.npc_type == 'Wizard':
self.weapon = 'staff'
self.blood = 2000
# 定义方法 - 显示 NPC 属性
def show_properties(self):
print('name:', self.name)
print('weapon:', self.weapon)
print('blood:', self.blood)
# 定义方法 - 通用攻击
def fight_common(self):
print('Fight Common')
# 战士 Soldier 类
class Soldier(NPC):
# 建立 soldier 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.soldier_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Soldier, self).show_properties()
print('soldier_level', self.soldier_level)
# 巫师 Wizard 类
class Wizard(NPC):
# 建立 Wizard 的初始化
def __init__(self, name):
# 调用 父类 NPC 的初始化方法
NPC.__init__(self, name)
# soldier 自己的初始化
self.wizard_level = 1
# 定义方法 - 显示 NPC 属性
def show_properties(self):
# 通过 super 来调用父类方法
super(Wizard, self).show_properties()
print('wizard_level', self.wizard_level)
# 定义一个巫师专用的战斗方法
def fight_magic(self):
print('Wizard Magic!')
s = []
for i in range(2):
n = Soldier('AA' + str(i))
n.show_properties()
s.append(n)
for i in range(2):
n = Wizard('CC' + str(i))
n.show_properties()
s.append(n)