每日分享
Whenever you are confronted with an opponent, conquer them with love.
无论何时面对你的对手,都要用爱征服他。
小闫语录:
孙子曰『凡用兵之法,全国为上,破国次之;全军为上,破军次之;全旅为上,破旅次之;全卒为上,破卒次之;全伍为上,破伍次之。是故百战百胜,非善之善者也;不战而屈人之兵,善之善者也。』
晓之以理,动之以情,智取以让敌方臣服者,大智慧也。武力破之,身降而心不降,是祸也。
浅谈面向对象
1.面向对象
面向对象编程OOP,很多人都是丈二的和尚,摸不着头脑。现在并没有一个统一的概念,导致面向对象也变成了只可意会不可言传,让很多人望尘莫及。
其实面向对象很简单,它就是为了提高代码的复用性而设计。我们在刚进入游戏的时候,肯定会有选择人物形象这一步,你喜欢女生,你会给它穿个裙子,她喜欢男生,她给他设置八块腹肌.....最初始的模型就是一个类,我们通过穿衣服,选择发型之类的操作,创建出来的人物就是对象。
总结一下,类是抽象出来的一些笼统的框架,对象通过类创建出来,并且可以为其设置属性。
面向过程编程时,我们会按照逻辑将所有的步骤都实现出来,而面向对象不需要关注过程怎么实现,我们直接通过类创建对象就好。
举个小栗子,假如你喜欢吃肯德基的奥尔良鸡腿堡。
面向过程就是你去后厨问师傅奥尔良鸡腿堡怎么做(当然人家不会告诉你,如果你家里有矿的话就开一家肯德基,然后你就有配方了,哈哈哈哈.....假装你有配方了),然后你买原材料自己动手做,好不容易做好了,两天过去了,饿死了。卒,享年24岁。
面向对象就是你去肯德基花26块钱买了一个奥尔良鸡腿堡,吃完了,很开心。
2.类
类有新式类和旧式类的区分,现在我们统一采用新式类。从名字你也晓得旧式类out了。
旧式类:
class Kfc: pass 或者 class Kfc(): pass
新式类:
class Kfc(object): def orlean: print("奥尔良鸡腿堡制作完成")
你也许会想:小编,KFC你写错了,别欺负我没读过书......这正是我要说的,只是为了让大家明白类名我们采用大驼峰的命名方法。
大驼峰式命名法(upper camel case): 每一个单词的首字母都采用大写字母,例如:FirstName、LastName
还要知道一点,Python的命令规则遵循PEP8标准。
3.一些魔法方法
__str__
:这个方法代表的是当你print一个通过类创建出来的对象时,打印出的是这个魔法方法的返回值。(所以 __str__
需要return一个数据)
__del__
:这个方法类比 __init__
,当创建对象后,python解释器默认调用 __init__
方法,当删除对象时,python解释器也会默认调用 __del__
方法。
__new__
:其实 __init__
方法不是第一个调用的方法, __new__
才是,类就是通过这个方法创建的对象。正因为它要创建对象,所以它必须有返回值。
1.
__new__
至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供。2.
__new__
必须要有返回值,返回实例化出来的实例,这点在自己实现__new__
时要特别注意,可以return父类__new__
出来的实例,或者直接是object的__new__
出来的实例。3.
__init__
有一个参数self,就是这个__new__
返回的实例,__init__
在__new__
的基础上可以完成一些其它初始化的动作,__init__
不需要返回值。4.我们可以将 ‘类’ 比作制造商,
__new__
方法就是前期的原材料购买环节,__init__
方法就是在有原材料的基础上,加工,初始化商品环节。
__doc__
:文档字符串,是文件中的特殊注释。
__module__
:查看当前成员属于哪个模块。
__class__
:查看对象属于哪个类。
__bases__
:查看本类的父类有哪些。
__mro__
:查看类中方法的查找顺序。
__dict__
:保存了类或对象中的成员信息。
类中的
__dict__
属性保存了类的所属模块,类中全局变量,方法,DocString 等内容。对象中的
__dict__
属性 用来保存对象的属性。
__call__
:通过实现了此方法的类创建出来的对象就可以被调用。
3.1单例模式
单例模式是一种常用的设计模式,它能保证某一个类只有一个实例对象。为什么要这样做呢?因为可以节省空间啊。同样的一个东西,内存里保存好几份,浪费不浪费~~~
那么下面实现一个单例模式:
class Kfc(object): __instance = None def __new__(cls,age,name): # 如果类属性__instance的值为None, # 那么就创建一个对象,并且赋值为这个对象的引用,保证下次调用这个方法时 # 能够知道之前已经创建过对象了,这样就保证了只有1个对象 if not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instnce
4.面向对象的三个基本特征
4.1封装
封装就是将重复的逻辑抽象成一个类。
意义:
1.将属性和方法放到一起做为一个整体,然后通过实例化对象来处理;
2.隐藏内部实现细节,只需要和对象及其属性和方法交互就可以了;
3.对类的属性和方法增加 访问权限控制。
4.2继承
继承超重要,就是子类可以继承父类的一些方法。(就好像儿子继承父亲的五毛钱财产一样。)
4.2.1子类调用父类的同名方法
-
1.子类继承了多个父类,如果父类类名修改了,那么子类也要涉及多次修改。而且需要重复写多次调用,显得代码臃肿。
2.使用super() 可以逐一调用所有的父类方法,并且只执行一次。调用顺序遵循
__mro__
类属性的顺序。注意:如果继承了多个父类,且父类都有同名方法,则默认只执行第一个父类的(同名方法只执行一次,目前super()不支持执行多个父类的同名方法)
3.super() 在Python2.3之后才有的机制,用于通常单继承的多层继承。
1. # 方式1. 指定执行父类的方法(代码臃肿) 2. School.__init__(self) 3. School.make_cake(self) 4. # 方法2. super() 带参数版本,只支持新式类 5. super(Prentice, self).__init__() # 执行父类的 __init__方法 6. super(Prentice, self).make_cake() 7. # 方法3. super()的简化版,只支持新式类 8. super().__init__() # 执行父类的 __init__方法 9. super().make_cake() # 执行父类的 实例方法 1. 父类是 School 2. 子类是 Prentice 3. 父类方法是 make_cake()
4.3多态
多态:定义时的类型和运行时的类型不一样,此时就称为多态,多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。
鸭子类型:虽然我想要一只"鸭子",但是你给了我一只鸟。只要这只鸟走路像鸭子,叫起来像鸭子,游泳也像鸭子,我就认为这是鸭子。
Python的多态,就是弱化类型,重点在于对象参数是否有指定的属性和方法,如果有就认定合适,而不关心对象的类型是否正确。
下面使用代码说一下什么是多态:
class F1(object): def show(self): print('F1.show') class S1(F1): def show(self): print('S1.show') class S2(F1): def show(self): print('S2.show') def Func(obj): # python是弱类型,即无论传递过来的是什么,obj变量都能够指向它,这也就没有所谓的多态了(弱化了这个概念) print(obj.show()) s1_obj = S1() Func(s1_obj) s2_obj = S2() Func(s2_obj)