Python小甲鱼学习笔记36-40

36类和对象:介绍

一、介绍对象
0、对象中的属性和方法,在编程中实际是什么?
  变量和函数。

1、类和对象是什么关系呢?
  类是对象的抽象表达,对象是类的实际表现。

2、如果我们定义了一个猫类,那你能想象出由“猫”类实例化的对象有哪些?
  黑猫,白猫,黑猫警长。

3、类的定义有些时候或许不那么“拟物”,有时候会抽象一些,例如我们定义一个矩阵类,那你会为此添加哪些属性和方法呢?
  添加长度,宽度,坐标,颜色等属性,计算面积和周长等方法。

4、类的属性定义应该尽可能抽象还是尽可能具体?
  抽象,这样才叫面向对象啊。

5、请用一句话概括面向对象的几个特征?
  封装:对外部隐藏对象的工作细节
  继承:子类自动共享父类之间数据和方法的机制
  >>> class MyList(list):
    pass 占位符 无意义
  >>> list1 = MyList()
  >>> list1.append(0)
  >>> list1
  [0]
  多态:可以对不同类的对象调用相同的方法,产生不同的结果,就是不同类的同一个方法名调用和后的结果不一样。

6、函数和方法有什么区别?
  方法多了一个self参数。

二、课后题
0、按照以下提示尝试定义一个Person类并生成类实例对象。

# 属性:姓名(默认姓名为“小甲鱼”)
# 方法:打印姓名
# 提示:放法中对属性的引用形式加上self,如self.name
class Person :
    name = '小甲鱼'
    def print_name(self) :
        print('名字是%s' % self.name)

1、按照以下提示尝试定义一个矩阵类并生成类实例对象。
属性:长和宽
方法:设置长和宽->setRect(self),获得长和宽->getRect(self),获得面积->getArea(self)
提示:方法中对属性的引用形式加上self,如self.width

#属性:长和宽
#方法:设置长和宽->setRect(self),获得长和宽->getRect(self),
#获得面积->getArea(self)
#提示:方法中对属性的引用形式加上self,如self.width
class Matrix:
    length = 5
    width = 4
    
    def setRect(self) :
        print('请输入矩形的长和宽')
        self.length = float(input('长:'))
        self.width = float(input('宽:'))

    def getRect(self) :
        print('这个矩形的长是:%d,宽是:%d' % (self.length,self.width))

    def getArea(self) :
        area = self.length * self.width
        print(area)

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

一、self
0、self参数的作用是什么?
  绑定方法。self参数类似于人的身份证,每个实例对象都有唯一的self参数。

二、类的方法
0、如果我们不希望对象的属性或方法被外部直接引用,我们可以怎么做?(私有变量)
  我们可以在属性或方法名字前边加上双下划线,这样子从外部是无法直接访问到,会显示AttributeError错误。

>>> class Person:  
              __name = '小甲鱼'  
           def getName(self):  
               return self.__name  
         
             
>>> p = Person()  
>>> p.__name  
Traceback (most recent call last):  
       File "<pyshell#7>", line 1, in <module>  
              p.__name  
AttributeError: 'Person' object has no attribute '__name'  
>>> p.getName()  
	'小甲鱼' 

因为加了“__”就变成私有元素,类外部不能直接访问,但可以通过类的方法间接访问。但其实Python只是把元素名改变了而已,可以通过“_类名__变量名”访问,即_Person__name。

1、类在实例化后哪个方法会被自动调用?
  __init__方法会在类实例化时被自动调用,称为魔法方法,又称为构造方法。

三、课后题
0、按照以下要求定义一个游乐园门票的类,并尝试计算2个成人+1个小孩平日票价。
a.平日票价100元
b.周末票价为平日的120%
c.儿童半价

#0、按照以下要求定义一个游乐园门票的类,并尝试计算2个成人+1个小孩平日票价。
#a.平日票价100元
#b.周末票价为平日的120%
#c.儿童半价
class Ticket:
    def __init__(self,people = 1,date = 1) :
        '成人1,平日1'
        if people == 1:
            if date == 1 :
                self.price = 100
            else :
                self.price = 120
        else :
            if date == 1 :
                self.price = 50
            else :
                self.price = 60

    def allprice(self,number = 1) :
        return self.price * number

adults = Ticket()
child = Ticket(2,1)
print(adults.allprice(2) + child.allprice(1))

1、游戏编程:按以下要求定义一个乌龟类和鱼类并尝试编写游戏。(初学者不一定可以完整实现,但请务必先自己动手,你会从中学习到很多知识的)

#1、游戏编程:按以下要求定义一个乌龟类和鱼类并尝试编写游戏。
#(初学者不一定可以完整实现,但请务必先自己动手,你会从中学习到很多知识的)
#a.假设游戏场景为范围(x,y)为0<=x<=10,0<=y<=10
#b.游戏生成1只乌龟和10条鱼
#c.它们的移动方向均随机
#d.乌龟的最大移动能力是2(Ta可以随机选择1还是2移动),鱼儿的最大移动能力是1
##e.当移动到场景边缘,自动向反方向移动
#f.乌龟初始化体力为100(上限)
#g.乌龟每移动一次,体力消耗1
#h.当乌龟和鱼坐标重叠,乌龟吃掉鱼,乌龟体力增加20
#i.鱼暂不计算体力
#j.当乌龟体力值为0(挂掉)或者鱼儿的数量为0游戏结束
'''      结构
1.设置游戏范围(x,y)为0<=x<=10,0<=y<=10
让位置为(x,y),一直在范围内

2.生成1只乌龟和10条鱼,乌龟体力值为100,且最大为100,鱼无体力

3.乌龟和鱼都移动,移动方向随机,乌龟走1或2步,体力消耗1,鱼走1步
如果移动到边界的自动反方向

4.如果乌龟和鱼坐标重叠,乌龟吃掉鱼,乌龟体力增加20

5.当乌龟体力值为0(挂掉)或者鱼儿的数量为0游戏结束
'''

import random

class Turtle :
    def __init__(self) :
        self.HP = 100  #乌龟体力值为100
        (self.x,self.y) = (random.randint(0,10),random.randint(0,10))  #位置随机
        self.GPS = (self.x,self.y)
    
    def crawl(self) : #乌龟移动
        stepcount = random.randint(1,2)
        if stepcount == 1 :  #一次移动一步
            direction = random.randint(1,4)
            if direction == 1 :  #上
                self.y += 1
                self.GPS = (self.x,self.y)
            elif direction == 2 :  #下
                self.y -= 1
                self.GPS = (self.x,self.y)
            elif direction ==3 :  #左
                self.x -= 1
                self.GPS = (self.x,self.y)
            else :                #右
                self.x += 1
                self.GPS = (self.x,self.y)
        else :            #一次移动两步
            direction = random.randint(1,4)
            if direction == 1 :   #上
                self.y += 2
                self.GPS = (self.x,self.y)
            elif direction == 2 :  #下
                self.y -= 2
                self.GPS = (self.x,self.y)
            elif direction ==3 :  #左
                self.x -= 2
                self.GPS = (self.x,self.y)
            else :                #右
                self.x += 2
                self.GPS = (self.x,self.y)
        #超出边界,当移动到场景边缘,自动向反方向移动
        if self.x < 0 :
            self.x = self.x * (-1)
            self.GPS = (self.x,self.y)
        elif self.x > 10 :
            self.x = 10 - (self.x - 10)
            self.GPS = (self.x,self.y)
        elif self.y < 0 :
            self.y = self.y * (-1)
            self.GPS = (self.x,self.y)
        elif self.y > 10 :
            self.y = 10 - (self.y - 10)
            self.GPS = (self.x,self.y)
            
    def reduceHP(self) :  #乌龟每移动一次,体力消耗1
        self.HP -= 1
            
    def eat(self) :  #如果乌龟和鱼坐标重叠,乌龟吃掉鱼,乌龟体力增加20
        self.HP += 20
        if self.HP > 100 :
            self.HP =100

class Fish :
    def __init__(self) :
        (self.x,self.y) = (random.randint(0,10),random.randint(0,10))  #位置随机
        self.GPS = (self.x,self.y)
    
    def tour(self) :  #鱼移动
        direction = random.randint(1,4)
        if direction == 1 :  #上
            self.y += 1
            self.GPS = (self.x,self.y)
        elif direction == 2 :  #下
            self.y -= 1
            self.GPS = (self.x,self.y)
        elif direction ==3 :  #左
            self.x -= 1
            self.GPS = (self.x,self.y)
        else :                #右
            self.x += 1
            self.GPS = (self.x,self.y)
        #超出边界,当移动到场景边缘,自动向反方向移动
        if self.x < 0 :
            self.x = self.x * (-1)
            self.GPS = (self.x,self.y)
        elif self.x > 10 :
            self.x = 10 - (self.x - 10)
            self.GPS = (self.x,self.y)
        elif self.y < 0 :
            self.y = self.y * (-1)
            self.GPS = (self.x,self.y)
        elif self.y > 10 :
            self.y = 10 - (self.y - 10)
            self.GPS = (self.x,self.y)
        
    def beeated(self) :  #如果乌龟和鱼坐标重叠,乌龟吃掉鱼
        del self.GPS
        
turtle1 = Turtle()
fish1 = Fish()
fish2 = Fish()
fish3 = Fish()
fish4 = Fish()
fish5 = Fish()
fish6 = Fish()
fish7 = Fish()
fish8 = Fish()
fish9 = Fish()
fish10 =Fish()
list1 = [fish1,fish2,fish3,fish4,fish5,fish6,fish7,fish8,fish9,fish10]
count = 0

print('=========================初始的游戏状况:====================')
print('乌龟的位置为:'+ str(turtle1.GPS))
print('乌龟的体力为:%d' % turtle1.HP)
for i in list1 :
    if i.GPS == turtle1.GPS :
        turtle1.eat()
        i.beeated()
        del i
    print('鱼的位置是:'+ str(i.GPS))
    
while turtle1.HP > 0 and len(list1) > 0 :
    turtle1.crawl()
    turtle1.reduceHP()
    for i in list1 :
        i.tour()
        if i.GPS == turtle1.GPS :
            turtle1.eat()
            i.beeated()
            list1.remove(i)
    count += 1
    print('=======================移动%d次之后的游戏状况:=================' % count)
    print('乌龟的位置为:'+ str(turtle1.GPS))
    print('乌龟的体力为:%d' % turtle1.HP)
    for i in list1 :
        print('鱼的位置是:'+ str(i.GPS))    

38类和对象:继承

一、格式
class 类名(父类类名):

二、测试题
0. 继承机制给程序猿带来最明显的好处是?
答:
  如果一个类 A 继承自另一个类 B,就把这个 A 称为 B 的子类,把 B 称为 A 的父类、基类或超类。继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码(偷懒)。
  在子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。另外,为子类追加新的属性和方法也是常见的做法。
  但是,这里覆盖的是子类实例化对象里面的方法而已,对父类的方法没有影响。

  1. 如果按以下方式重写魔法方法 init,结果会怎样?
class MyClass:
    def __init__(self):
        return "I love FishC.com!"

答:会报错,因为 init 特殊方法不应当返回除了 None 以外的任何对象。

  1. 当子类定义了与相同名字的属性或方法时,Python 是否会自动删除父类的相关属性或方法?

答:不会删除!Python 的做法跟其他大部分面向对象编程语言一样,都是将父类属性或方法覆盖,子类对象调用的时候会调用到覆盖后的新属性或方法,但父类的仍然还在,只是子类对象“看不到”。

  1. 假设已经有鸟类的定义,现在我要定义企鹅类继承于鸟类,但我们都知道企鹅是不会飞的,我们应该如何屏蔽父类(鸟类)中飞的方法?

答:覆盖父类方法,例如将函数体内容写 pass,这样调用 fly 方法就没有任何反应了。

  1. super 函数有什么“超级”的地方?

答:super 函数超级之处在于你不需要明确给出任何基类的名字,它会自动帮您找出所有基类以及对应的方法。由于你不用给出基类的名字,这就意味着你如果需要改变了类继承关系,你只要改变 class 语句里的父类即可,而不必在大量代码中去修改所有被继承的方法。

  1. 多重继承使用不当会导致重复调用(也叫钻石继承、菱形继承)的问题,请分析以下代码在实际编程中有可能导致什么问题?
class A():
    def __init__(self):
        print("进入A…")
        print("离开A…")
 
class B(A):
    def __init__(self):
        print("进入B…")
        A.__init__(self)
        print("离开B…")
        
class C(A):
    def __init__(self):
        print("进入C…")
        A.__init__(self)
        print("离开C…")
 
class D(B, C):
    def __init__(self):
        print("进入D…")
        B.__init__(self)
        C.__init__(self)
        print("离开D…")

答:多重继承容易导致重复调用问题,下边实例化 D 类后我们发现 A 被前后进入了两次(有童鞋说两次就两次憋,我女朋友还不止呢……)。
这有什么危害?我举个例子,假设 A 的初始化方法里有一个计数器,那这样 D 一实例化,A 的计数器就跑两次(如果遭遇多个钻石结构重叠还要更多),很明显是不符合程序设计的初衷的(程序应该可控,而不能受到继承关系影响)。

>>> d = D()
进入D…
进入B…
进入A…
离开A…
离开B…
进入C…
进入A…
离开A…
离开C…
离开D…
  1. 如何解决上一题中出现的问题?
class A():
    def __init__(self):
        print("进入A…")
        print("离开A…")
 
class B(A):
    def __init__(self):
        print("进入B…")
        super().__init__()
        print("离开B…")
        
class C(A):
    def __init__(self):
        print("进入C…")
        super().__init__()
        
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值