zoukankan      html  css  js  c++  java
  • 第十一章 类和对象[DDT书本学习 小甲鱼]【2】

    import random as r
    class Fish:
    def __init__(self):
    self.x=r.randint(0,10)
    self.y=r.randint(0,10)
    def move(self):
    self.x-=1
    print("我的位置是:",self.x,self.y)

    class Goldfish(Fish):
    pass

    class Carp(Fish):
    pass

    class Salmon(Fish):
    pass

    class Shark(Fish):
    def _init_(self):
    self.hungry=True
    def eat(self):
    if self.hungry:
    print("吃货的梦想就是天天有的吃")
    self.hungry=False
    else:
    print("太撑了,吃不下了!")

    f=Fish()
    print(f.move())
    print(f.move())
    s=Shark()
    print(s.eat())
    print(s.eat())
    -------------------------------------------------
    我的位置是: 2 4
    我的位置是: 1 4
    吃货的梦想就是天天有的吃
    太撑了,吃不下了!
    ================================================
    加入 s.move()会报错 因为子类重写__inint__覆盖了父类 s对象没有x属性
    解决办法 1。调用未绑定的父类方法
    2。使用super函数
    1调用未绑定的父类方法,修改代码如下
    class Shark(Fish):
    def __init__(self):
    Fish.__init__(self)#此self是子类对象
    self.hungry=True
    2.使用super函数(不需要指定基类名字,只需要改变继承的父类,方法更优)
    class Shark(Fish):
    def __init__(self):
    super.__init__()
    self.hungry=True
    ====================================================
    以上两种方法都可以实现同一效果,使得s.move()可以正常使用。

    11.5多重继承(同时继承多个父类的属性和方法) 缺点:容易导致代码混乱,出现BUG
    class Base1:
    def foo1(self):
    print("我是foo1,我在Base1中。。。")
    class Base2:
    def foo2(self):
    print("我是foo2,我在Base2中。。。")
    class C(Base1,Base2):
    pass
    c=C()
    print(c.foo1)
    print(c.foo2)
    -----------------------
    我是foo1,我在Base1中。。。
    我是foo2,我在Base2中。。。
    =========================================================
    11.6组合
    先学习了继承,后学习了多重继承,不到必要时候不使用多重继承。
    上回有了乌龟类,鱼类,现在要求一个类,叫水池,水池里要有乌龟和鱼。
    使用多重继承就很奇怪,因为水池和乌龟、鱼是不同物种,如何组合成水池的类?
    在Python里很简单,直接把需要的类放进去实例化就可以了,这就叫【组合】
    代码如下:
    class Wugui:
    def __init__(self,x):
    self.num=x
    class Yu:
    def __init__(self,x):
    self.num=x
    class Chi:
    def __init__(self,x,y):
    self.gui=Wugui(x)
    self.yu=Yu(y)
    def print_num(self):
    print("水池里总共有乌龟%d只,小鱼%d条!"%(self.gui.num,self.yu.num))

    chi=Chi(3,8)
    chi.print_num()
    ---------------------------
    水池里总共有乌龟3只,小鱼8条!
    ===============================================================
    11.7类、类对象、实例对象
    class C: 是一个类,定义完后 也就是一个类对象
    count=0
    a=C()
    b=C()
    c=C()
    print(a.count)
    print(b.count)
    print(c.count)
    ------------------
    0
    0
    0
    ======================修改代码如下
    c.count+=10
    print(c.count)
    ----------------
    10
    =======================但是,此时b.count和c.count呢?
    print(a.count)
    print(b.count)
    print(C.count)
    ----------------
    0
    0
    0
    ========================为何呢?接着看!
    C.count+=100
    print(a.count)
    print(b.count)
    print(c.count)
    ---------------
    100
    100
    10
    =============================思考原因如下
    对实例对象的count属性赋值后,覆盖了类对象C的count属性。
    如果没有赋值覆盖,那么引用的是类对象的count属性。
    图如下
    类C
    类对象C
    实例对象 a b c
    ==================================================
    另外,如果属性的名字与方法名相同,属性会覆盖方法:
    class C:
    def x(self):
    print("X-Man")
    c=C()
    print(c.x())
    --------------
    X-Man
    =====================修改代码如下
    c.x=1
    print(c.x)
    -------------
    1
    =======================加入代码
    print(c.x())
    --------------
    报错,因为方法已经被属性覆盖了。
    为了避免以上冲突,大家应该遵守一些约定俗成的规定
    1,类的定义要“少吃多餐”,要善于利用继承和组合机制来进行扩展
    2,属性命名用名词,方法名用动词且用骆驼命名法等。

    Daodantou:“不积跬步,无以至千里.”
  • 相关阅读:
    C#中的委托和事件的使用
    C#中Attribute/特性的使用
    Eclipase + CDT
    设计模式总结
    Nginx源码编译
    Nginx自定义扩展模块
    电池的寿命
    大盗阿福
    河中跳房子
    An Easy Problem
  • 原文地址:https://www.cnblogs.com/daodantou/p/10468141.html
Copyright © 2011-2022 走看看