• day25 面向对象继承,多态,


    这两天所学的都是面向对象,后面还有几天也是它,面向对象主要有三个大的模块,封装,继承,多态,(组合),昨天主要讲了面向对象的命名空间,还有组合的用法,今天是讲的继承还有继承里面所包括的钻石继承,以及多态的知识点。

    创建一个类,关键字是class,然后后面加上类的名字,首字母大写即可,创建完了之后就得到了一个类的命名空间,

    然后下面就是类的属性,分为静态属性(定义在类中的变量)和动态属性(定义在类中的方法),

    然后就是属性,属性是类实例化得出的结果,创建一个属性就是创建了一个属性的命名空间,对象可以通过类对象指针找到类,然后调用类中的方法,而类找不到对象,无法调用对象中的方法。

     再就是组合,在一个类中以另外一个类的对象作为属性,称为类的组合。

    然后就是今天学的继承(子类对象调用父类方法指名道姓,super),以及继承里面的钻石继承,

    继承就是有几个类,这几个类里面有一些相同的属性,那么就把这些个属性提取出来,作为一个基类(父类,超类),然后其余的各自不尽相同的属性就各自保留,那么其余的类就是子类也叫做派生类。这时我们得到的结果就叫做继承。

    有一句话“  高桌子低板凳都是木头 ”,这句话高度概括了继承的关系,木头是父类(超类,基类),高桌子和低板凳则都为子类(派生类)

    那么之前学过的组合跟继承最大的区别就是一个字,“是”,“有”。组合中:A有B,那么A与B就为组合。继承中:A是B,那么A与B就为继承,且‘是’后面的名词叫做父类(超类,基类),即B是父类;‘是‘前面的名词叫做子类(派生类)。

    还有一个概念,object,带有object关键字作为默认参数的类就是经典类,经典类在python2.7中有。不带有object关键字作为默认参数的类是新式类,在python3中,所有类都是新式类。这里补充一个super方法,当子类里面有一个派生类方法和父类里面的一个方法同名时,如果要调用派生类的就直接使用方法名调用,如果要调用父类里面的,就需要使用指名道姓方法调用,格式为:父类名.方法名(对象名)

    这个格式可以放在类外面,也可以放在类里面,写法不变,放在类里面的时候,就放在子类的与父类方法同名的方法下面。

    钻石继承(查找父类):在python2中分为经典类和新式类,经典类的写法是class F:经典类中是深度优先原则;而新式类的写法是class F(object):,新式类中是广度优先原则。

              :在python3中经典类和新式类统一并称为新式类,而且还提供了一种简单的查询方法,就是使用mro直接可以得到父类的查询踪迹。

    还有就是多态。python本身自带多态。

    对于昨天所学的面向对象的命名空间的回顾:

    # 命名空间 :
        # 静态属性 : 属于类内部的命名空间
        # 动态属性 : 属于类内部的命名空间
        # 对象属性 : 属于对象的,在类内和self发生联系,在类外和对象名发生联系
        # 可以查看静态属性的都有哪些:类名 对象名
        # 可以调用类中的方法的有哪些:类名.方法名(对象),对象.方法名()
        # 类到对象之间没有联系,而对象到类之间有联系。
        # 对象在查找名的时候,会现在我自己的空间里找,再到类的空间里找
    # 组合 :
        #将一个对象作为另一个类的对象的属性
        # 老师有生日
        # 圆环
        # 人有武器
    View Code

    面向对象的继承:

    #继承 : 模糊到具体
    #抽象 : 具体到模糊
    #先抽象后继承
    #继承有几种: 单继承,多继承
    # 猫类 抓老鼠
    # 狗类 看门
    # 动物 吃 喝 睡
    # class Animal:
    #     def eat(self):
    #         print('eating')
    #
    #     def drink(self):
    #         print('drinking')
    #
    #     def sleep(self):
    #         print('sleeping')
    #
    # class Cat(Animal):
    #     def catch_mouse(self):
    #         print('yeah')
    #
    # class Dog(Animal):
    #     def watch_door(self):
    #         print('wangwangwang')
    
    # kitty = Cat()
    # kitty.eat()
    # snoopy = Dog()
    # snoopy.eat()
    
    # 人类 狗类 相同的属性 提取了一个__init__方法,在这个方法里放一些共有的属性
    # 猫类和狗类 相同的方法 直接把相同的方法提取出来,放在基类里
    
    # 他大舅他二舅都是他舅 —— 实例化
    # 高桌子低板凳都是木头 —— 继承
    
    # 人 狗 相同属性的同时 还有一些不同的属性
    # class Animal:
    #     def __init__(self,aggressivity, life_value,name):
    #         self.name = name  # 每一个角色都有自己的昵称;
    #         self.aggressivity = aggressivity  # 每一个角色都有自己的攻击力;
    #         self.life_value = life_value  # 每一个角色都有自己的生命值;
    #     def eat(self):
    #         self.life_value += 10
    #
    # class Person(Animal):
    #     def __init__(self, name, aggressivity, life_value, money):
    #         Animal.__init__(self, name, aggressivity, life_value)
    #         self.money = money    #派生属性:父类没有的属性
    #
    #     def attack(self,dog):
    #         dog.life_value -= self.aggressivity
    #
    #     def get_weapon(self,weapon_obj):
    #         if self.money > weapon_obj.price:
    #             self.money -= weapon_obj.price  # 金老板花钱买武器
    #             self.weapon = weapon_obj  # 金老板装备打狗棒
    #             self.aggressivity += weapon_obj.aggr  # 金老板的攻击力增加了
    # class Dog(Animal):
    #     def __init__(self, name, breed, aggressivity, life_value):
    #         Animal.__init__(self,aggressivity,life_value,name)
    #         self.breed = breed  # 每一只狗都有自己的品种; #派生属性:父类没有的属性
    #
    #     def bite(self,people):  # 派生方法 :父类没有的方法
    #         people.life_value -= self.aggressivity
    #
    #     def eat(self):
    #         Animal.eat(self)
    #         print('dog is eating')
    
    # snoopy = Dog('太白','京巴',250,500)
    # print(snoopy.breed)
    # print(snoopy.name)
    # # Animal.eat(snoopy)
    # snoopy.eat()
    # print(snoopy.life_value)
    # snoopy.eat()
    # print(snoopy.life_value)
    #派生属性 : 在自己的init方法里 使用父类的init方法 —— 指名道姓调用方法
    #派生方法 : 在子类中增加父类没有的
    #只要子类有,就有子类的
    #只要想用父类,Animal.eat(snoopy)  父类名.父类的方法(子类对象) 2.7经典类中
    
    # 在新式类
    # class Animal:
    #     def __init__(self,aggressivity, life_value,name):
    #         self.name = name  # 每一个角色都有自己的昵称;
    #         self.aggressivity = aggressivity  # 每一个角色都有自己的攻击力;
    #         self.life_value = life_value  # 每一个角色都有自己的生命值;
    #     def eat(self):
    #         self.life_value += 10
    #
    # class Person(Animal):
    #     def __init__(self, name, aggressivity, life_value, money):
    #         # Animal.__init__(self, name, aggressivity, life_value)
    #         super().__init__(name, aggressivity, life_value)  #新式类
    #         self.money = money    #派生属性:父类没有的属性
    #
    #     def attack(self,dog):
    #         dog.life_value -= self.aggressivity
    #
    #     def get_weapon(self,weapon_obj):
    #         if self.money > weapon_obj.price:
    #             self.money -= weapon_obj.price  # 金老板花钱买武器
    #             self.weapon = weapon_obj  # 金老板装备打狗棒
    #             self.aggressivity += weapon_obj.aggr  # 金老板的攻击力增加了
    # class Dog(Animal):
    #     def __init__(self, name, breed, aggressivity, life_value):
    #         # Animal.__init__(self,aggressivity,life_value,name)
    #         # super(Dog,self).__init__(aggressivity,life_value,name)
    #         super().__init__(aggressivity,life_value,name)
    #         self.breed = breed  # 每一只狗都有自己的品种; #派生属性:父类没有的属性
    #
    #     def bite(self,people):  # 派生方法 :父类没有的方法
    #         people.life_value -= self.aggressivity
    #
    #     def eat(self):
    #         # Animal.eat(self)
    #         super().eat()
    #         print('dog is eating')
    # snoopy = Dog('太白','京巴',250,500)
    # print(snoopy.breed)
    # print(snoopy.name)
    # snoopy.eat()
    # print(snoopy.life_value)
    # super(Dog,snoopy).eat()   #Animal.eat(snoopy)
    # print(snoopy.life_value)
    
    #用子类的对象,调用父类的方法:
    #如果子类中没有这个方法,直接就使用父类的
    #如果子类中有同名方法:
        # 经典类 指名道姓 类名.方法名(子类对象) 类内外一致
        # 新式类 super方法 super(子类名,子类对象).方法名() 类内可以省略super的参数
    
    class Foo:
        def __init__(self):
            self.func()
    
        def func(self):
            print('Foo.func')
    
    class Son(Foo):
        def func(self):
            print('Son.func')
    
    s = Son()
    
    #钻石继承问题
    View Code

    钻石继承:

    #coding:utf-8
    #经典类和新式类的多继承问题,继承顺序问题
    #经典类 : 博大精深 所以经典类就是深度优先
    #新式类 :广度优先
    class F(object):
        pass
        def f(self):
            print('F')
    class E(F):
        pass
        def f(self):
            print('E')
    class D(F):
        pass
        # def f(self):
        #     print('D')
    class B(D):
        pass
        # def f(self):
        #     print('B')
    class C(E):
        pass
        def f(self):
            print('C')
    class A(B,C):
        pass
        # def f(self):
        #     print('A')
    
    a = A()
    a.f()
    print(A.mro()) #新式类:查看继承顺序
    # class A(object):pass #新式类
    
    # 在好多个有继承关系的类里面,找一个方法,找的顺序问题
    # 继承三层
    # py3 —— 广度优先
    # py2 —— 新式类
    #面试 —— 能对应 新式类 是广度优先 经典类是深度优先
    
    # 继承 —— 抽象类和接口类 —— 是一种设计模式
    
    # 多态
    View Code

    多态:

    这下面的图片就是我们理解多态的核心

    ==================================================================================================================================================

    #python不支持多态的
    class Animal:pass
    
    class Person(Animal):
        def attack(self):
            pass
    
    class Dog(Animal):
        def attack(self):
            pass
    
    def attack(obj):  #多态
        obj.attack()
    
    d = Dog()
    p = Person()
    attack(d) #d.attack()
    attack(p) #p.attack()
    
    
    print(10)
    
    #鸭子类型 list tuple是一对鸭子类型
    #列表
    #元组
    # 切片 : 字符串 列表 元组
    # + :字符串 列表 数字
    def len(l):pass
    
    
    # 继承
    # 子类对象调用父类方法  :指名道姓,super
    # 钻石继承问题
    
    #多态 - 鸭子类型
    
    #做总结
    #写博客
    #画思维导图 —— 周五交
    #写大作业 —— 把类设计好写好,之间的关系理清楚,做完登录,设计角色的功能
    #之前的知识
    View Code

    面向对象需要画思维导图,这个需要后续补上

  • 相关阅读:
    【数据结构】树的DFS序&欧拉序
    Codeforces 1335E2
    Codeforces 1335E1
    Codeforces 1338A/1339C
    【数据结构】ST算法
    Codeforces 1334C
    Codeforces 1333D
    Codeforces 1333C
    python中的socket编程实例与查看端口占用
    java中打印数组
  • 原文地址:https://www.cnblogs.com/2012-dream/p/7873257.html
Copyright © 2020-2023  润新知