• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
KK筑梦人
博客园    首页    新随笔    联系   管理    订阅  订阅

面向对象的三大特性:封装、继承、多态---->单继承、多继承 第十九天 2018.11.4

上节复习:

面向对象编程:

思想:角色的抽象,创建类,创建角色(实例化),操作这些实例

面向对象的关键字:

class 类名:

  静态属性='  '

       def __init__(self):

类名.静态属性 ——> 存储在类的命名空间里

对象 = 类名()        实例化:创造了一个self对象,执行init方法,返回self对象给外部

对象.属性

对象.方法    类名.方法(对象)

对象可以使用静态变量  类不可以使用对象里的属性

组合:一个类的对象是另外一个类对象的属性

面向对象的三大特性:封装、继承、多态

继承:直接在类名后加括号,括号里面便是该类的父类,父类可以有多个(Python支持多继承);

父类又可以称为基类、超类;Python中所有最高级父类的默认继承为object(新式类),最高级父类可以不带括号。

class A(object):pass   # 父类,基类,超类   默认继承object(新式类)
class B:pass   # 父类,基类,超类
class A_son(A,B):pass # 子类,派生类
class AB_son(A):pass # 子类,派生类

单继承:一个父类 可以被多个子类继承

多继承:一个子类 可以继承多个父类 

.__bases__查看该类所有父类,没有的话默认object

print(A_son.__bases__)            #.__bases__查看该类的所有父类
print(AB_son.__bases__)
print(A.__bases__)  # python3 -新式类# 没有继承父类默认继承object

抽象:抽取类似或者说比较像的部分

class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp
        self.func()          #作为一个对象调用方法,此处self为dog的,相当于Dog.func()
    def func(self):
        print(123)

class Dog(Animal):
    def func(self):      #在此创建Dog的self对象,因为Dog中无__init__()方法,因此向父类中找init方法
        print(456)       #456
    def bite(self,person):
        person.hp -= self.aggr
d = Dog()          #执行Dog类


class Person(Animal):
    def __init__(self,name,aggr,hp,sex):
        Animal.__init__(self,name,aggr,hp)
        self.sex = sex       # 派生属性
        self.money = 0       # 派生属性

    def attack(self,dog):
        dog.hp -= self.aggr

    def get_weapon(self,weapon):
        if self.money >= weapon.price:
            self.money -= weapon.price
            self.weapon = weapon
            self.aggr += weapon.aggr
        else:
            print("余额不足,请先充值")
alex = Person('alex',1,2,None)
alex.eat()
print(alex.hp)

jin.bite(alex)
print(alex.hp)

派生:父类中没有的子类中出现了的

父类中没有的属性 在子类中出现 叫做派生属性

父类中没有的方法 在子类中出现 叫做派生方法

只要是子类的对象调用,子类中有的名字 一定用子类的,子类中没有才找父类的,如果父类也没有报错

如果父类 子类都有 用子类的

  如果还想用父类的,单独调用父类的:

  父类名.方法名 需要自己传self参数

  super().方法名 不需要自己传self

正常的代码中 单继承 === 减少了代码的重

继承表达的是一种 子类是父类的关系

class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp

    def eat(self):
        print('吃药回血')
        self.hp+=100

class Dog(Animal):
    def __init__(self,name,aggr,hp,kind):
        Animal.__init__(self,name,aggr,hp)  #
        self.kind = kind       # 派生属性
    def eat(self):
        Animal.eat(self)   # 如果既想实现新的功能也想使用父类原本的功能,还需要在子类中再调用父类
        self.teeth = 2
    def bite(self,person):   # 派生方法
        pass

jin = Dog('金老板',100,500,'吉娃娃')
jin.eat()
print(jin.hp)
class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp
    def eat(self):
        print('吃药回血')
        self.hp+=100

class Dog(Animal):
    def __init__(self,name,aggr,hp,kind):
        super().__init__(name,aggr,hp)  # 只在新式类中有,python3中所有类都是新式类
        self.kind = kind       # 派生属性
    def eat(self):print('dog eating')

jin = Dog('金老板',200,500,'teddy')
print(jin.name)
jin.eat()
super(Dog,jin).eat()

多继承:(.mro()查看调用方法时经过父类的顺序)

新式类 继承object类的才是新式类 广度优先

经典类 如果你直接创建一个类在2.7中就是经典类 深度优先

单继承 : 子类有的用子类 子类没有用父类

多继承中,我们子类的对象调用一个方法,默认是就近原则,找的顺序是:经典类中 深度优先;新式类中 广度优先

python2.7 新式类和经典类共存,新式类要继承object(即出现父类后括号里object)

python3 只有新式类,默认继承object

经典类和新式类还有一个区别 mro方法只在新式类中存在

super 只在python3中存在

super的本质 :不是单纯找父类 而是根据调用者的节点位置的广度优先顺序来的

钻石继承、漏斗继承:

 

六边形继承:

class F:
    def func(self): print('F')
class A(F):pass
    # def func(self): print('A')
class B(A):
    pass
    # def func(self): print('B')
class E(F):pass
    # def func(self): print('E')
class C(E):
    pass
    # def func(self): print('C')

class D(B,C):
    pass
    # def func(self):print('D')

d = D()
# d.func()
print(D.mro())

新式类中的继承顺序:广度优先(加super().):

class A(object):
    def func(self): print('A')  #所以第一个输出A

class B(A):
    def func(self):     #不是单纯找父类 而是根据调用者的节点位置的广度优先顺序来的
        super().func()  #此时调用者节点位置为B按广度优先顺序再到C
        print('B')      #第三个输出B

class C(A):             #此时调用者节点位置为C按广度优先顺序该到最后节点A
    def func(self):
        super().func()
        print('C')      #第二个输出C

class D(B,C):           #此时调用者节点位置为D按广度优先顺序先到B
    def func(self):
        super().func()
        print('D')      #最后输出D

b = D()
b.func()
print(B.mro())

  

  

  

 

 

  

posted @ 2018-11-04 19:47  KK筑梦人  阅读(163)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3