zoukankan      html  css  js  c++  java
  • Python学习:15.Python面向对象(二、继承的各种情况)

    一、什么是继承

    继承是一种创建类的方法,在python中,一个类可以继承来自一个或多个父。原始类称为基类或超类。

    #创建父类
    class Parent1:
        pass
    
    class Parent2:
        pass
    
    # 继承父类,单继承
    class Obj1(Parent1):
        pass
    
    #继承父类,多继承
    class Obj2(Parent1,Parent2):
        pass

    二、什么时候使用继承

      在已经创建的几个类中,这几哥类中的方法和变量有相同的,这种时候我们就可以使用类的继承,将其它类中已有的方法和变量通过继承的方式,在新创建的类中,使用正常的方式就可以调用父类中的方法。剩下自己特有的方法只要在自己类中定义就可以。

      举个列子:人都会吃,喝,玩,小明也是一个人,所以小明也会,所以小明继承了人的属性,特别的是小明还会背古诗,就基于以上的说法写一个类的继承。

    class Man:
    
        def eat(self):
            print('')
    
        def drink(self):
            print('')
    
        def play(self):
            print('')
    
    
    class XiaoMing(Man):
    
        def recite(self):
            print('背古诗')
    
    xm = XiaoMing()
    xm.eat()
    xm.recite()
    
    
    输出结果:
    吃
    背古诗

    三、单继承与多继承

    单继承:仅仅继承一个父类,当查找方法的时候,首先在自己里面查找,然后到父类里面查找。

    class Biology:
        def split(self):
            print(self.name+" accrue")
    
    class Animal(Biology):#在类后面加括号加上所要继承类的名字,继承的是类的方法
        def GoWhoring(self):
            print("i like go whoring")
        def eat(self):
            print(self.name+" eat")
    
    class superman:
        def gamble(self):
            print("gamble is interesting")
        def GoWhoring(self):
            print("beautiful whoring")
            
    class Cat(Animal):
        def GoWhoring(self):
            print("i don't like go whoring")
        def __init__(self,name):
            self.name = name
        def cry(self):
            print(self.name + "")
                                                        #优先级:自己,父类(左边,右边)
    class Dog(Animal,superman):#在继承多个父类时,在两个父类都有同一个名字的方法时,优先选择括号左边的父类的方法
        def __init__(self,name):
            self.name = name
        def cry(self):
            print(self.name + "")
    
    mimi = Cat("mimi")
    mimi.eat()
    mimi.cry()                #当基类里方法存在,派生类里也存在同名方法,优先找派生类里的方法
    mimi.GoWhoring() #当父类里有一个方法自己也有一个同名的方法时,默认使用自己的方法
    husike = Dog("erha")#虽然Dog里没有eat和split但是由于Dog继承了Animal和的方法,而Animal继承了Biology的方法
    husike.eat()            #所以Dog可以使用Biology的方法    
    husike.cry()            #父类有一个名字叫"基类"  子类有一个名字叫"派生类"
    husike.split()
    husike.GoWhoring()
    faker = Animal()
    faker.GoWhoring()#优先使用自己的方法

    派生类可以继承基类里的所有功能。
    当基类里方法存在,派生类里也存在同名方法,派生类优先找派生类里的方法(意思是优先找自己的)。
    在Java、C#里面一个子类只能继承一个父类,多了报错,但是在python里可以继承多个父类

    在经典类中,继承是以深度优先,在新式类中,继承是以广度优先。

    Python 2.x中默认都是经典类,只有显式继承了object才是新式类。

    python 3.x中默认都是新式类,经典类被移除,不必显式的继承object。

    深度优先:

    class A():
        def save(self):
            print("This is from A")
    class B(A):
        pass
    class C(A):
        def save(self):
            print("This is from C")
    class D(B,C):
        pass
    
    fun =  D()
    fun.save()
    
    输出结果:
    This is from A"

    深度优先的时候就是一条道走到黑,从左向右找,先把左边的一个里面的全部找完在找右边的。

     广度优先:

    class A():
        def save(self):
            print("This is from A")
    class B(A):
        pass
    
    class C(A):
        def save(self):
            print("This is from C")
    class D(B,C):
        pass
    
    fun =  D()
    fun.save()
    
    输出结果:
    This is from C

    首先在左边的上一层父类中寻找,如果没有就到右边一个父类中寻找,没有就到左边父类的父类中寻找。

    广度优先多种情况解析

    情况一

    有A、B、C、D、E几个类,A为B的父类,B为C的父类,E为D的父类,D为C的父类 现在C需要使用一个方法,只有在A,E里有,第一次C先去B中寻找没有找到 然后就会去A里面找,A里没有就去D里面找,然后再去E里找。

    class A:
        def function(self):
            print("are you OK?A")
    
    class B(A):
        def function_fake(self):
            print("are you OK?B")
    
    class E:
        def function(self):
            print("are you OK?E")
    
    class D(E):
        def function_fake(self):
            print("are you OK?D")
    
    class C(B, D):
        def Sb(self):
            print("i am sb")
    
    faker = C()
    faker.function()
    
    输出结果:
    are you OK?A

    括号里为查找顺序。

    情况二

    它会先把没有共同的父类寻找玩,然后再找共同的父类,因为在这种情况下它想找到和自己关系最近的。

    class S:
        def function(self):
            print('are you Ok?S')
    
    class A(S):
        def function_fake(self):
            print("are you OK?A")
    
    class B(A):
        def function_fake(self):
            print("are you OK?B")
    
    class E(S):
        def function(self):
            print("are you OK?E")
    
    class D(E):
        def function_fake(self):
            print("are you OK?D")
    
    class C(B, D):
        def Sb(self):
            print("i am sb")
    
    faker = C()
    faker.function()
    
    输出结果:
    are you OK?E

     

    情况三

    当A、B、D、E、都没有C所要找的函数时才会找右边的F(括号右边)

    class F():
        def function(self):
            print("are you OK?F")
    
    class A:
        def function_fake(self):
            print("are you OK?A")
    
    class E:
        def function_fake(self):
            print("are you OK?E")
    
    class B(A,F):
        def function_fake(self):
            print("are you OK?B")
    
    class D(E):
        def function_fake(self):
            print("are you OK?D")
    
    class C(B, D):
        def Sb(self):
            print("i am sb")
    
    
    faker = C()
    faker.function()
    
    
    输出结果:
    are you OK?F

    情况四

    首先面执行一个 c1 = C();c1.xxx() ,xxx在D里面而且xxx又执行了self.ooo() 而ooo在BDE里都有它会执行哪个?

    class B:
        def ooo(self):
            print("B")
    
    
    class E:
        def ooo(self):
            print("E")
    
    
    class D(E):
        def xxx(self):
            self.ooo()
    
        def ooo(self):
            print("D")
    
    
    class C(B, D):
        pass
    
    
    c1 = C()
    c1.xxx()
    
    输出结果:
    B

    解析:首先找到c1.xxx在D里面,在D里面又执行了self.ooo(),这个self代指c1,而c1为C类的对象,意思还是c1.ooo,所以寻找ooo时还是从C开始,因为先找左边的所以,找到了B的ooo 以后找是谁执行的函数要看准self到底是谁的从self下手。

    红色为第二次寻找路径(寻找ooo方法的次序)

    今天的类的继承主要是多继承的时候父类中方法选择的。

  • 相关阅读:
    自己用Django搭建的blog和用户权限
    python实现简单爬虫功能
    异步任务队列Celery在Django中的使用
    Django添加全文搜索功能入门篇
    Django 最好的缓存memcached的使用
    Django中添加富文本编辑器
    Python之Django 访问静态文件
    Django中url的逆向解析 -> Reverse resolution of URLs
    python(Django之html模板继承)
    IOS7以后无需自定义,改变UITabbarItem的图片文字颜色
  • 原文地址:https://www.cnblogs.com/liudi2017/p/9297336.html
Copyright © 2011-2022 走看看