037类和对象:面向对象编程

面向对象编程(OOP)
   OOA:面向对象分析
   OOD:面向对象设计
   OOP:面向对象编程

1.self 是什么呢?
  python中的self相当于C++的this指针
  就像类是图纸,而对象是可以住人的房子,每个房子长得一样,但它们有不同的主人,self就相当于每个房子的门牌号。
  self参数的作用:绑定方法,有了self参数python就可以分清哪个对象再调用方法;
                  可以认为self其实就是实例对象的唯一标识。
  例:
    >>> class Ball:
    ...  :   def setName(self,name):
    ...         self.name = name
    ...     def kick(self):
    ...         print('I am %s' % self.name)
    ...
    >>> a = Ball()   # 第一个参数self告诉Python是a对象在调用方法,因为是隐藏的并且由Python自己传入,所以我们这里不需要写进来。
    >>> b = Ball()
    >>> a.setName('A')
    >>> b.setName('B')
    >>> a.kick()
    I am A
    >>> b.kick()
    I am B

2.python的魔法方法
   据说,python的对象天生拥有一些神奇的方法,它们是面向对象的python的一切……
   它们是可以给你的类增加魔力的特殊方法。
   如果你的对象实现了这些方法中的某一个,那这个方法就会在特殊的情况下被python所调用,这一切都是自动发生
 
  __init__(self):构造方法,最基础的魔法方法。实例化一个对象的时候,在方法创建的时候自动调用
  __init__(self,param1,param2...):在实例化的时候可以传入参数。
               __init__方法:不可以返回除了None以外的任何对象               
 
   如:>>> class Ball:
       ...     def __init__(self,name):
       ...         self.name = name
       ...     def kick(self):
       ...         print('I am %s' % self.name)
       ...
       >>> b = Ball('B')
       >>> b.kick()
       I am B

3.共有的和私有的
  python中属性和方法默认都是共有的,可以用'.'来访问
  如:>>> class Person:
      ...     name = 'HaHa'
      ...
      >>> p = Person()
      >>> p.name
      'HaHa'

  name mangling:名字改变,名字重整,可以实现类似私有的功能  
                名字改变就是把"__"开头的变量改为"_类名__变量名"

  定义私有的函数或变量:在变量或函数名前加“__”两个下划线
  如:>>> class Person:
      ...     __name = 'HaHa'
      ...
      >>> p = Person()
      >>> p.__name           
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      AttributeError: Person instance has no attribute '__name'
  现在__name就是私有的变量,外部不可以访问
  如果现在要访问__name这个私有变量,理论上需要在内部访问
  如:>>> class Person:
      ...     __name = 'HaHa'
      ...     def getName(self):
      ...         return self.__name
      ...
      >>> p = Person()
      >>> p.getName()
      'HaHa'
   但是现在可以用另一种方法访问,因为名字改变就是把"__"开头的变量改为"_类名__变量名",所以
   如:>>> p._Person__name
       'HaHa'
   所以说,python的私有是伪私有,python的类是不受限制的。


练习:
1.写一个游乐场门票的类,计算两个成人一个小孩平日票价
     平日票价100元
     周末为平日的120%
     小孩半价S
  1 #!/usr/bin/python
  2 #coding:utf8
  3
  4 class Ticket:
  5     def __init__(self,week = False,child = False):
  6         self.exp = 100
  7         if week:
  8             self.inc = 1.2
  9         else:
 10             self.inc = 1
 11         if child:
 12             self.discount = 0.5
 13         else:
 14             self.discount = 1
 15     def calcPrice(self,num):
 16         return (self.exp * self.inc * self.discount * num)
 17
 18 adult = Ticket()
 19 child = Ticket(child=True)
 20 print("2个成人 + 1个小孩平日的票价为:%.2f" % (adult.calcPrice(2) + child.calcPrice(1)))


2.游戏编程:按以下要求定义一个乌龟类和鱼类并编写游戏
   游戏场景为范围(x,y)为 0<=x<=10,0<=y<=10
   游戏生成1只乌龟和10条鱼
   它们的移动方向均随机
   乌龟的最大移动能力为2(可以随机选择1还是2),鱼儿的最大移动能力为1
   当移动到场景边缘,自动向反方向移动
   乌龟初始化体力为100(上限)
   乌龟每移动一次,体力消耗1
   当乌龟和鱼坐标重叠,乌龟吃掉鱼,乌龟体力增加20
   鱼暂不计算体力
   当乌龟体力值为0(挂掉)或鱼儿的数量为0游戏结束

  1 #!/usr/bin/python                                                                                        
  2 # coding:utf8
  3
  4 import random as r
  5
  6 legal_x = [0,10]
  7 legal_y = [0,10]
  8
  9 class Turtle:
 10     def __init__(self):
 11          self.power = 100                             #初始化体力
 12          self.x = r.randint(legal_x[0],legal_x[1])    #初始化位置随机
 13          self.y = r.randint(legal_y[0],legal_y[1])
 14     
 15     def move(self):
 16         new_x = self.x + r.choice([1,2,-1,-2])        #随机计算方向 并移动到新的位置(x,y)
 17         new_y = self.y + r.choice([1,2,-1,-2])
 18
 19         if new_x < legal_x[0]:                        #检查移动后是否超出了场景x轴边界
 20             self.x = legal_x[0] - (new_x - legal_x[0])
 21         elif new_x > legal_x[1]:
 22             self.x = legal_x[1] - (new_x - legal_x[1])
 23         else:
 24             self.x = new_x
 25
 26         if new_y < legal_y[0]:                        #检查移动后是否超出了场景y轴边界
 27             self.y = legal_y[0] - (new_y - legal_y[0])
 28         elif new_y > legal_y[1]:
 29             self.y = legal_y[1] - (new_y - legal_y[1])
 30         else:
 31             self.y = new_y
 32
 33         self.power -= 1                               #体力消耗
 34         return (self.x,self.y)                        #返回移动后新的位置
 35  
 36     def eat(self):
 37         self.power += 20
 38         if self.power > 100:
 39             self.power = 100
 40
 41 class Fish:
 42     def __init__(self):
 43         self.x = r.randint(legal_x[0],legal_x[1])    #初始化位置随机
 44         self.y = r.randint(legal_y[0],legal_y[1])
 45
 46     def move(self):
 47         new_x = self.x + r.choice([1,-1])            #随机计算方向 并移动到新的位置(x,y)
 48         new_y = self.y + r.choice([1,-1])
 49
 50         if new_x < legal_x[0]:                        #检查移动后是否超出了场景x轴边界
 51             self.x = legal_x[0] - (new_x - legal_x[0])
 52         elif new_x > legal_x[1]:
 53             self.x = legal_x[1] - (new_x - legal_x[1])
 54         else:
 55             self.x = new_x
 56
 57         if new_y < legal_y[0]:                        #检查移动后是否超出了场景y轴边界
 58             self.y = legal_y[0] - (new_y - legal_y[0])
 59         elif new_y > legal_y[1]:
 60             self.y = legal_y[1] - (new_y - legal_y[1])
 61         else:
 62             self.y = new_y
 63
 64         return (self.x,self.y)                        #返回移动后新的位置
 65
 66 turtle = Turtle()
 67
 68 fish = []
 69 for i in range(10):
 70     new_fish = Fish()
 71     fish.append(new_fish)
 72
 73 while True:
 74     if not len(fish):
 75         print("鱼吃完了,游戏结束")
 76         break
 77     if not turtle.power:
 78         print("乌龟体力耗尽")
 79         break
 80
 81     pos = turtle.move()
 82     for each_fish in fish[:]:
 83         if each_fish.move() == pos:
 84             turtle.eat()                              #鱼儿被吃掉了
 85             fish.remove(each_fish)
 86             print("有一条鱼被吃了")                                     

posted @ 2015-10-16 23:29  淡蓝色的天空很美  阅读(708)  评论(0编辑  收藏  举报