问题场景

小王是某游戏公司的新入职的职员,有一天,组长交给了他一个任务,为一个即将准开发的一款游戏设计一些人物角色,其中包括多种职业,如牧师、战士和法师等等。每种职业都有一些自身独有的属性和技能,但是也会有一些共有的属性和方法。假设这家公司是用 Python 来开发游戏的。

经历过面向对象编程学习的小王很快就理清了思路,这需要用类的思想来进行设计。由于这些职业都会有一些共有的属性和方法,显然应该把这些职业的共有属性和方法拿出来作为一个公共的类,而这个公共的类就叫做基类,或者称为父类;其它职业可以基于这个公共的类来进行增加属性和方法,这些职业的类就叫做子类。这就是面向对象编码中的继承的思想,理清了设计思路之后,小王立马开始动手来实现相应的代码。


父类设计

首先,对于每一个游戏角色,它都会有姓名和性别属性。组长又告诉小王,我们不能让其它人知道我们的角色是怎么设计的,以及都有哪些属性,这又该如何设计呢?聪明的小王立马就想到了封装的思想,通过隐藏对象的属性和实现细节可以防止外部的类直接调用属性或者修改属性。所以小王立马写出了如下的代码:

class Roler(object):
"""
用户角色类,需要隐藏属性
Args:
__username: 用户名,string
__sex:性别, string
"""
def __init__(self, name=None, sex="male"):
self.__username = name
self.__sex = sex
self.__hp = 1000 def get_username(self):
# 获取用户名
return self.__username def get_sex(self):
# 获取用户性别
return self.__sex def add_hp(self, hpr):
# 角色可以回血
self.__hp += hpr def __repr__(self):
# 打印对象信息
return "username : {0}\nsex : {1}\nhp : {2}".format(self.__username, self.__sex, self.__hp)

不同于 JavaC++ ,在 Python 中是没有 private 等关键字的。所以我们如何来定义一个类的属性是私有的呢?方法就是在类属性的名字前加上两个下划线,即表示成 __username 的形式,这就是私有属性的定义方式了。其原因是因为 Python 的类的内部,所有双下划线的开始的名字都会被替换成增加单下划线和类名的方式。实质上,__username 就被替换成了 _Roler__username 的形式了。

role1 = Roler("weisheng", "male") # 建立一个新角色
print(role1) # 打印该角色的信息,调用 __repr__() 方法 print(role1.__username) # AttributeError,该属性是私有的
print(role1._Roler__username) # weisheng,可以打印

子类设计

有了父类还不够,由于每个职业都会有一些自身特有的属性和方法。所以,对于每个职业,我们也需要实现一个类。小王首先针对牧师这个职业来实现,牧师作为一个法系医疗职业,首先肯定需要一个 MP 值。同时,它能给其它用户恢复生命值。因此,可以按照如下方式来实现牧师类:

class Pastor(Roler):
"""
牧师类,继承自用户角色类
Args:
__MP: 魔法值
"""
def __init__(self, name, sex):
# 调用父类的构造函数
super().__init__(name, sex)
self.__mp = 100
def get_mp(self):
return self.__mp
def __repr__(self):
return super().__repr__() + "\nmp : {0}".format(self.__mp) def fullhealth(self, other):
# 技能1:回复其它用户生命值
other.add_hp(200)

在定义的牧师类中,首先调用父类的构造函数来对用户姓名、性别、hp值进行初始化。同时,牧师还有个mp值,这个属性是该职业独有的(请勿追究细节)。由于增加了相应的属性,所以 __repr__() 方法也需要重写,可以通过调用父类的 __repr__() 方法再加上牧师类独有的属性。

子类不能直接调用父类的私有属性,所以针对父类的一些私有属性,需要通过方法来调用。

牧师还有一个技能,他能给其它的用户角色回血,所以需要实习一个 fullhealth() 方法,参数是其它的角色类。测试用例如下:

pastor1 = Pastor("ergouzi", "male") # 建立一个牧师职业
print(pastor1) # 打印该职业角色的信息 pastor1.fullhealth(role1) # 牧师可以给其他角色回血
print(role1) # 可以发现该用户的 hp 值发生变化

其他职业的设计可以参照该职业的特点来做出相应的设计,这里就不在多做说明了。


面向对象总结

通过跟随小王的游戏角色设计,相信你已经对 Python 中的面向对象编程有了一定的了解了。面向对象编程是现在常用的一种编程方式,它是相对于面向过程编程来说的。面向对象编程把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。该思想最主要的三个特点就是封装、继承和多态,其实这些特点在上述的实例中都有体现,你能发现吗?

虽然上述的例子已经阐述了面向对象编程的大部分思想,但是本人也是第一次去进行这些类间关系的设计,所以每个例子都是非常简单的,可能在思想设计上也存在问题,请见谅。

全部代码请访问:面向对象编程

更多精彩内容将发布在公众号 冰咖啡与狗 ,或搜索微信号 icedcoffee7 添加公众号。

Python面向对象知多少?的更多相关文章

  1. Python 面向对象编程——访问限制

    <无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...

  2. Python面向对象之:三大特性:继承,封装,多态以及类的约束

    前言: python面向对象的三大特性:继承,封装,多态. 1. 封装: 把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情 ...

  3. python 面向对象初级篇

    Python 面向对象(初级篇) 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发" ...

  4. Python 面向对象 基础

    编程范式概述:面向过程 和 面向对象 以及函数式编程 面向过程:(Procedure Oriented)是一种以事件为中心的编程思想. 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现 ...

  5. python面向对象进阶(八)

    上一篇<Python 面向对象初级(七)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...

  6. python 面向对象(进阶篇)

    上一篇<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...

  7. python 面向对象编程学习

    1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...

  8. Python面向对象详解

    Python面向对象的"怜人之处" Python的待客之道--谁能进来 Python的封装--只给你想要的 Python的继承--到处认干爹 Python的多态--说是就是

  9. python 面向对象和类成员和异常处理

    python 面向对象 你把自己想象成一个上帝,你要创造一个星球,首先你要把它揉成一个个球,两个直径就能创造一个球 class star: '''名字(name),赤道直径(equatorial di ...

随机推荐

  1. JS实时检测文本框内容长度

    通过js代码实时监测,文本框内容的变化以及长度,下图是一个实际使用场景. HTML部分: <input id="Text1" type="text" on ...

  2. SpringBoot简易搭建

    1.建立maven工程 2.打开pom文件, 将以下配置拷贝过去 <parent> <groupId>org.springframework.boot</groupId& ...

  3. 微信小程序把玩(三十七)location API

    原文:微信小程序把玩(三十七)location API location API也就分这里分两种wx.getLocation(object)获取当前位置和wx.openLocation(object) ...

  4. MinGW 编译 libsndfile-1.0.25(只要有 MSYS,./configure make make install 就行了)

    最近做的一个项目需要读写 wav 文件.在网上找到 libsndfile 刚好满足我的需要.但是编译的时候遇到了点小麻烦,这里记录一下编译的过程,免得下次再编译时忘记了. 因为是在编译完成若干天后写的 ...

  5. 青云QingCloud宣布完成C轮融资,金额1亿美元

    本轮融资由两家人民币基金领投,蓝驰创投跟投. 企业级基础云服务商青云QingCloud正式宣布完成金额为1亿美元的C轮融资,本轮融资由两家人民币基金领投,蓝驰创投跟投. 青云QingCloud公司成立 ...

  6. StarWind Storage Appliance

    https://www.starwindsoftware.com/starwind-storage-appliance?gclid=CLzH8oGyptICFbIW0wodNuYG1Q

  7. Qt for android触摸手势事件QGestureEvent

    在触摸设备上可以使用Qt的手势事件 要激活手势事件,需要执行以下操作: 第一步,为QWidget控件注册手势事件 QList<Qt::GestureType> gestures; gest ...

  8. coci2018 题解

    plahte 给定一些矩形和一些有颜色的点,求每个矩形上有多少种颜色的点,保证矩形只有包含和不相交两种关系,规模 \(10^5\). 把每个矩形看成一个点,用扫描线建出森林,同时也顺便处理点. 然后做 ...

  9. hive表批处理

    对hive中的表进行批量处理,如下是一个简单的脚本 #给定一个hive数据库名,生成它的所有表的create SQL语句,并导出到文件 create_fun(){ hive -e } #显示一个表中所 ...

  10. 前端视频转码flv->swf

    在项目中本来是要用<video>标签插入视频,但此标签不支持flv格式,上网也是搜了很多,试了很久才成功(其他格式不是很清楚你们可以尝试看看) 所用技术 flach (Flvplayer. ...