天天看点

初学面向对象

一、面向过程和面向对象的比较

1、面向过程

面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,是一种机械式的思维方式。

优点是:复杂度的问题流程化,进而简单化

缺点是:一套流水线或者流程就是用来解决一个问题,程序扩展困难,牵一发而动全身。

应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

2、面向对象

面向对象的程序设计:核心是对象二字,对象是特征与技能的结合体,基于面向对象设计程序就好比在创造一个世界,存在的皆为对象,不存在的也可以创造出来。

优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中。

缺点:

1. 编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题。一些扩展性要求低的场景使用面向对象会徒增编程难度,比如管理linux系统的shell脚本。

2. 无法很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,无法准确地预测最终结果,只有对象之间交互才能准确地知道最终的结果。

应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方

#面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。

二、类与对象

1、类的介绍

类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体

在现实世界中:先有对象,再有类

在程序中:   务必保证先定义类,后产生对象

2、定义类

1

2

3

4

5

6

<code>class</code> <code>Student:</code>

<code>    </code><code>school </code><code>=</code> <code>'Middle school'</code>           <code>#数据属性</code>

<code>    </code><code>def</code> <code>learn(</code><code>self</code><code>):                 </code><code>#函数属性</code>

<code>        </code><code>print</code><code>(</code><code>'is learning'</code><code>)</code>

<code>    </code><code>def</code> <code>sleep(</code><code>self</code><code>):</code>

<code>        </code><code>print</code><code>(</code><code>'is sleeping'</code><code>)</code>

# 注意:

    1.类中可以有任意python代码,这些代码在类定义阶段便会执行

    2.因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过OldboyStudent.__dict__查看

    3.对于经典类来说我们可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供专门的.语法

    4.点是访问属性的语法,类中定义的名字,都是类的属性

3、类的用法

基于上面定义的类来研究用法:

7

8

9

<code>print</code><code>(Student.school)           </code><code>#结果是Middle school</code>

<code>print</code><code>(Student.__dict__)         </code><code>#查看类名称空间的信息</code>

<code>print</code><code>(Student.learn)           </code><code>#结果是&lt;function Student.learn at 0x00000000021C98C8&gt;</code>

<code>Student.age</code><code>=</code><code>18</code>               <code>#添加属性</code>

<code>print</code><code>(Student.age)</code>

<code>Student.school </code><code>=</code> <code>'Primary school'</code>   <code>#修改属性</code>

<code>print</code><code>(Student.school)           </code><code>#结果是Primary school</code>

<code>del</code> <code>Student.age               </code><code>#删除属性</code>

<code>print</code><code>(Student.age)             </code><code>#报错,age属性找不到,说明已经删除了</code>

4、类在程序中的应用

10

11

12

13

<code>    </code><code>school </code><code>=</code> <code>'Middle school'</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,name,age,sex):  </code><code>#实例化得到特有的信息</code>

<code>        </code><code>self</code><code>.name</code><code>=</code><code>name</code>

<code>        </code><code>self</code><code>.age</code><code>=</code><code>age</code>

<code>        </code><code>self</code><code>.sex</code><code>=</code><code>sex</code>

<code>        </code><code>print</code><code>(</code><code>'%s is learning'</code> <code>%</code><code>self</code><code>.name)</code>

<code>stu1</code><code>=</code><code>Student(</code><code>'wang'</code><code>,</code><code>20</code><code>,</code><code>'male'</code><code>)</code>

<code>stu2</code><code>=</code><code>Student(</code><code>'li'</code><code>,</code><code>22</code><code>,</code><code>'male'</code><code>)</code>

<code>print</code><code>(stu1.__dict__)                  </code><code>#{'name': 'wang', 'age': 20, 'sex': 'male'}</code>

<code>print</code><code>(stu2.__dict__)                 </code><code>#{'name': 'li', 'age': 22, 'sex': 'male'}</code>

<code>Student.learn(stu1)                  </code><code>#结果wang is learning</code>

补充:

(1)站的角度不同,定义出的类是截然不同的,详见面向对象实战之需求分析

(2)现实中的类并不完全等于程序中的类,比如现实中的公司类,在程序中有时需要拆分成部门类,业务类......

(3)有时为了编程需求,程序中也可能会定义现实中不存在的类,比如策略类,现实中并不存在,但是在程序中却是一个很常见的类

5、用类实现数据库连接:

14

<code>class</code> <code>MySQLHandler:</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,host,port,db,charset</code><code>=</code><code>'utf8'</code><code>):</code>

<code>        </code><code>self</code><code>.host</code><code>=</code><code>host</code>

<code>        </code><code>self</code><code>.port</code><code>=</code><code>port</code>

<code>        </code><code>self</code><code>.db</code><code>=</code><code>db</code>

<code>        </code><code>self</code><code>.charset</code><code>=</code><code>charset</code>

<code>        </code><code>self</code><code>.conn</code><code>=</code><code>connect(</code><code>self</code><code>.host,</code><code>self</code><code>.port,</code><code>self</code><code>.db,</code><code>self</code><code>.charset)</code>

<code>    </code><code>def</code> <code>exc1(</code><code>self</code><code>,sql):</code>

<code>        </code><code>return</code> <code>self</code><code>.conn.execute(sql)</code>

<code>    </code><code>def</code> <code>exc2(</code><code>self</code><code>,sql):</code>

<code>        </code><code>return</code> <code>self</code><code>.conn.call_proc(sql)</code>

<code>obj</code><code>=</code><code>MySQLHandler(</code><code>'127.0.0.1'</code><code>,</code><code>3306</code><code>,</code><code>'db1'</code><code>)</code>

<code>obj.exc1(</code><code>'select * from tb1;'</code><code>)</code>

<code>obj.exc2(</code><code>'存储过程的名字'</code><code>)</code>

三、属性查找

1、类的属性

类有两种属性:数据属性和函数属性

(1)类的数据属性是所有对象共享的

(2)类的函数属性是绑定给对象用的

2、实例:编写一个学生类,产生一堆学生对象,要求有一个计数器(属性),统计总共实例了多少个对象

15

<code>    </code><code>count</code><code>=</code><code>0</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,name,age,sex):</code>

<code>        </code><code>Student.count</code><code>+</code><code>=</code><code>1</code>

<code>stu3</code><code>=</code><code>Student(</code><code>'jim'</code><code>,</code><code>25</code><code>,</code><code>'male'</code><code>)</code>

<code>print</code><code>(stu1.count)                  </code><code>#结果为3</code>

<code>print</code><code>(stu2.count)                  </code><code>#结果为3</code>

<code>print</code><code>(stu3.count)                  </code><code>#结果为3</code>

3、绑定到对象的方法

类中定义的函数(没有被任何装饰器装饰的)是类的函数属性,类可以使用,但必须遵循函数的参数规则,有几个参数需要传几个参数

类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,而且是绑定到对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法

强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’本身当做第一个参数传给方法,即自动传值(方法__init__也是一样的道理)

注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self可以是任意名字,但是约定俗成地写出self。

四、对象之间的交互

1、简单实现对战

16

17

18

19

20

21

22

<code>class</code> <code>Poilce:</code>

<code>    </code><code>camp </code><code>=</code><code>'justice'</code>            <code>#阵营是正义</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,name,attacking</code><code>=</code><code>55</code><code>,life_value</code><code>=</code><code>300</code><code>):</code>

<code>        </code><code>self</code><code>.attacking</code><code>=</code><code>attacking</code>

<code>        </code><code>self</code><code>.life_value</code><code>=</code><code>life_value</code>

<code>    </code><code>def</code> <code>attack(</code><code>self</code><code>,opponent):    </code><code>#定义攻击,指定对手</code>

<code>        </code><code>opponent.life_value</code><code>-</code><code>=</code><code>self</code><code>.attacking</code>

<code>class</code> <code>Robber:</code>

<code>    </code><code>camp </code><code>=</code><code>'evil'</code>             <code>#阵营是邪恶</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,name,attacking</code><code>=</code><code>60</code><code>,life_value</code><code>=</code><code>270</code><code>):</code>

<code>p1</code><code>=</code><code>Poilce(</code><code>'大兵'</code><code>)</code>

<code>r1</code><code>=</code><code>Robber(</code><code>'海盗'</code><code>)</code>

<code>print</code><code>(</code><code>'p1的名字是%s r1的名字是%s '</code><code>%</code><code>(p1.name,r1.name))              </code><code>#p1的名字是大兵 r1的名字是海盗</code>

<code>print</code><code>(</code><code>'p1的生命值是%s r1的生命值是%s '</code><code>%</code><code>(p1.life_value,r1.life_value))   </code><code>#p1的生命值是300 r1的生命值是270</code>

<code>p1.attack(r1)                                        </code><code>#p1发起攻击</code>

<code>print</code><code>(</code><code>'p1的生命值是%s r1的生命值是%s '</code><code>%</code><code>(p1.life_value,r1.life_value))   </code><code>#p1的生命值是300 r1的生命值是215</code>

2、基于面向对象设计一个对战游戏

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

<code>class</code> <code>Riven:</code>

<code>    </code><code>camp</code><code>=</code><code>'Noxus'</code>                          <code>#Noxus阵营</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,nickname,</code>

<code>                 </code><code>aggressivity</code><code>=</code><code>54</code><code>,          </code><code>#攻击力</code>

<code>                 </code><code>life_value</code><code>=</code><code>414</code><code>,           </code><code>#生命值</code>

<code>                 </code><code>money</code><code>=</code><code>1001</code><code>,</code>

<code>                 </code><code>armor</code><code>=</code><code>3</code><code>):                </code><code>#盔甲</code>

<code>        </code><code>self</code><code>.nickname</code><code>=</code><code>nickname</code>

<code>        </code><code>self</code><code>.aggressivity</code><code>=</code><code>aggressivity</code>

<code>        </code><code>self</code><code>.money</code><code>=</code><code>money</code>

<code>        </code><code>self</code><code>.armor</code><code>=</code><code>armor</code>

<code>    </code><code>def</code> <code>attack(</code><code>self</code><code>,enemy):</code>

<code>        </code><code>damage_value</code><code>=</code><code>self</code><code>.aggressivity</code><code>-</code><code>enemy.armor    </code><code>#给对方造成的伤害值</code>

<code>        </code><code>enemy.life_value</code><code>-</code><code>=</code><code>damage_value            </code><code>#对手每次受到伤害生命值需要减掉伤害值</code>

<code>class</code> <code>Garen:</code>

<code>    </code><code>camp</code><code>=</code><code>'Demacia'</code>

<code>                 </code><code>aggressivity</code><code>=</code><code>58</code><code>,</code>

<code>                 </code><code>life_value</code><code>=</code><code>455</code><code>,</code>

<code>                 </code><code>money</code><code>=</code><code>100</code><code>,</code>

<code>                 </code><code>armor</code><code>=</code><code>10</code><code>):</code>

<code>        </code><code>damage_value</code><code>=</code><code>self</code><code>.aggressivity</code><code>-</code><code>enemy.armor</code>

<code>        </code><code>enemy.life_value</code><code>-</code><code>=</code><code>damage_value</code>

<code>class</code> <code>BlackCleaver:                         </code><code>#定义装备</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,price</code><code>=</code><code>475</code><code>,aggrev</code><code>=</code><code>9</code><code>,life_value</code><code>=</code><code>100</code><code>):</code>

<code>        </code><code>self</code><code>.price</code><code>=</code><code>price</code>

<code>        </code><code>self</code><code>.aggrev</code><code>=</code><code>aggrev</code>

<code>    </code><code>def</code> <code>update(</code><code>self</code><code>,obj):</code>

<code>        </code><code>obj.money</code><code>-</code><code>=</code><code>self</code><code>.price            </code><code>#减钱</code>

<code>        </code><code>obj.aggressivity</code><code>+</code><code>=</code><code>self</code><code>.aggrev       </code><code>#加攻击</code>

<code>        </code><code>obj.life_value</code><code>+</code><code>=</code><code>self</code><code>.life_value     </code><code>#加生命值</code>

<code>    </code><code>def</code> <code>fire(</code><code>self</code><code>,obj):                 </code><code>#这是该装备的主动技能,喷火,烧死对方</code>

<code>        </code><code>obj.life_value</code><code>-</code><code>=</code><code>1000</code>            <code>#假设火烧的攻击力是1000</code>

测试:

<code>r1</code><code>=</code><code>Riven(</code><code>'草丛伦'</code><code>)</code>

<code>g1</code><code>=</code><code>Garen(</code><code>'盖文'</code><code>)</code>

<code>b1</code><code>=</code><code>BlackCleaver()</code>

<code>print</code><code>(r1.aggressivity,r1.life_value,r1.money)   </code><code>#r1的攻击力,生命值,护甲 54 414 1001</code>

<code>if</code> <code>r1.money &gt; b1.price:                  </code><code>#r1的钱足够买装备,就执行装备类的update函数,给r1修改属性</code>

<code>    </code><code>r1.b1</code><code>=</code><code>b1</code>

<code>    </code><code>b1.update(r1)</code>

<code>print</code><code>(r1.aggressivity,r1.life_value,r1.money)    </code><code>#r1的攻击力,生命值,护甲 63 514 526</code>

<code>print</code><code>(g1.life_value)      </code><code>#g1生命值455</code>

<code>r1.attack(g1)           </code><code>#普通攻击(现在r1的攻击是穿上装备后的攻击力)</code>

<code>print</code><code>(g1.life_value)      </code><code>#g1生命值402</code>

<code>r1.b1.fire(g1)          </code><code>#用装备攻击</code>

<code>print</code><code>(g1.life_value)      </code><code>#g1的生命值小于0就死了,值为-598</code>

本文转自 宋鹏超 51CTO博客,原文链接:http://blog.51cto.com/qidian510/2061458,如需转载请自行联系原作者