• python基础之继承原理,多态与封装


    1.什么是继承? 继承是一种创建新的类的方式。
    class A:
    pass
    class B:
    pass
    2.如何继承---->如何寻找继承关系

    现实生活中找继承关系是自下而上,在程序中写是自上而下
    继承是一种"是"的关系:
    人类、猪类、狗类都是继承动物类,因为他们都是动物

    3.为什么要用继承?
    解决代码重用问题?解决的是:什么是什么的问题-->继承

    4.派生:子类继承了父类的属性,然后衍生(或派生)出自己新的属性
    如果子类衍生出的新的属性与父类的某个属性名字相同
    那么再调用子类的这个属性,就以子类自己这里的为准了
    5.在子类中重用父类的函数,父类名.父类的函数(参数)

    6.组合对继承来说,也是用来重用代码,但是组合描述的是一种"有"的关系
    老师有课程
    学生有成绩
    学生有课程
    学校有老师
    学校有学生

    class Course:
    def __init__(self,name,price,period):
    self.name=name
    self.price=price
    self.period=period
    class Teacher:
    def __init__(name.course):
    self.name=name
    self.course=course
    class Student:
    def __init__(name.course):
    self.name=name
    self.course=course
    python=Course('python',15800,'7m')
    t1=Teacher('egon',python)
    s1=Student('alex',python)
    
    print(s1.course.name)
    print(s1.course.period)
    组合示例

    继承原理1(python3中的新式类):

    #新式类的继承,在查找属性时遵循:广度优先
    class A(object):    #A继承object类,在Python3中写不写都一样
        def test(self):
            print('from A')
        pass
    class X(A):
        # def test(self):
        #     print('from X')
        pass
    class B(X):
        # def test(self):
        #     print('from B')
        pass
    class C(A):
        def test(self):
            print('from C')
        pass
    class D(B):
        # def test(self):
        #     print('from D')
        pass
    class E(C):
        def test(self):
            print('from E')
        pass
    class F(D,E):
        # def test(self):
        #     print('from F')   #从F自己这里找
        pass
    f1=F()
    f1.test()
    print(F.mro())
    #MRO程序列表会生成一个列表
    #python到底是如何实现继承的,对于定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表。
    继承原理示例1-1

    #广度优先:F->D->B->E->C->A->object
    #广度优先:从左边开始走,但是不走到头,再从右边开始走
    class A(object):
        def test(self):
            print('from A')
        pass
    
    class B(A):
        # def test(self):
        #     print('from B')
        pass
    class C(A):
        # def test(self):
        #     print('from C')
        pass
    
    class D(B):
        # def test(self):
        #     print('from D')
        pass
    class E(C):
        # def test(self):
        #     print('from E')
        pass
    class F(D,E):
        # def test(self):
        #     print('from F')
        pass
    f1=F()
    f1.test() #先在f1找,没有,然后再F找
    print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性
    继承原理示例1-2

    继承原理2(python3中的新式类):

    # Auther:bing
    #新式类的继承,在查找属性时遵循:广度优先
    class X(object):
        def test(self):
            print('from X')
        pass
    class Y(object):
        def test(self):
            print('from Y')
        pass
    class B(X):
        def test(self):
            print('from B')
        pass
    class C(Y):
        def test(self):
            print('from C')
        pass
    class D(B):
        def test(self):
            print('from D')
        pass
    class E(C):
        def test(self):
            print('from E')
        pass
    class F(D,E):
        def test(self):
            print('from F')
        pass
    f1=F()
    f1.test()
    #深度优先
    #F-->D-->B-->X-->E-->C-->Y-->object,先从左边开始找,再找右边,相当于一个V形
    继承原理2

    继承原理图2,深度优先

    #F-->D-->B-->X-->E-->C-->Y-->object,先从左边开始找,再找右边,相当于一个V形

    继承原理3(python3中的新式类):

    class A(object):
        def test(self):
            print('from A')
        pass
    class B(A):
        def test(self):
            print('from B')
        pass
    class C(A):
        def test(self):
            print('from C')
        pass
    class D(A):
        def test(self):
            print('from D')
        pass
    class E(B):
        def test(self):
            print('from E')
        pass
    class F(C):
        def test(self):
            print('from F')
        pass
    class G(D):
        def test(self):
            print('from G')
        pass
    class H(E,F,G):
        def test(self):
            print('from H')
        pass
    h1=H()
    h1.test()
    
    #广度优先
    继承原理3

     #执行顺序是E-B-F-C-G-D-A-object,先从左边,再从中间在从右边找

    #经典类的继承
    class A:
        def test(self):
            print('from A')
        pass
    class B(A):
        def test(self):
            print('from B')
        pass
    class C(A):
        def test(self):
            print('from C')
        pass
    class D(B):
        def test(self):
            print('from D')
        pass
    class E(C):
        def test(self):
            print('from E')
        pass
    class F(D,E):
        def test(self):
            print('from F')
        pass
    f1=F()
    f1.test()
    # print(F.__mro__)
    #MRO程序列表会生成一个列表
    #python到底是如何实现继承的,对于定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表。
    #F-D-B-A-E-C-object
    python2中经典类的继承

    #F-D-B-A-E-C-object

    super用法:

    #super在Python3中的用法:
    class People:
        def __init__(self,name,sex,age):
            self.name=name
            self.sex=sex
            self.age=age
        def walk(self):
            print('%s is walking' %self.name)
    
    class Chinese(People):
        country='China'
        def __init__(self,name,sex,age,language='Chinese'):
            # self.name=name
            # self.sex=sex
            # self.age=age
            # People.__init__(self,name,sex,age)
            super(Chinese,self).__init__(name,sex,age)  #调用父类(People类)的__init__方法(绑定方法)
            self.language=language
        def walk(self,x):
            super().walk()
            print('子类的x',x)
    c=Chinese('egon','male','18')
    print(c.name,c.age,c.sex,c.language)
    c.walk(123)
    
    ----------输出--------
    egon 18 male Chinese
    egon is walking
    子类的x 123
    
    #super在python2中的用法:
    #1:super(自己的类,self).父类的函数名称
    #2:super只能用于新式类
    super应用

     多态与多态性:

    多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承)
    1、序列类型有多种形态:字符串,列表,元组
    2、动物有多种形态:人,狗,猪
    python默认就支持多态,python对类型没有任何限制,可以定义函数的参数,可以传入不同的对象进来
    多态性依赖于:
    1.继承

     2.定义统一的接口,可以传入不同类型的值,但是调用的逻辑都一样,执行的结果却不一样
    多态示例:
    class Animal:   #多态:同一种事物的多种形态
        def run(self):
            raise AttributeError('子类必须实现这个方法')
    
    class People(Animal):
        def run(self):
            print('人正在走')
    class Pig(Animal):
        def run(self):
            print('pig is walking')
    class Dog(Animal):
        def run(self):
            print('dog is running')
    peo1=People()   #每一个对象都可以调用run()方法
    pig1=Pig()  ##每一个对象都可以调用run()方法
    d1=Dog()
    
    # peo1.run()
    # pig1.run()
    #统一的接口
    def func(obj):  #obj这个参数没有类型限制,可以传入不同类型的值
        obj.run()   #调用的逻辑都一样,执行的结果却不一样
    func(peo1)
    func(pig1)
    func(d1)
    多态示例1:
    >>> a="hello"    #定义一个字符串
    >>> l=[1,2,3]    #定义一个列表
    >>> def func(obj):    #定义一个函数
    ...     return obj.__len__()    #返回该数据类型的长度
    ...
    >>> func(a) 调用func函数
    5
    >>> func(l)
    3
    
    >>> l=[1,2,3,4]
    >>> t=(1,2)
    >>> d={'a':1}
    >>> func(l)
    4
    >>> func(t)
    2
    >>> func(d)
    1
    多态示例2

     封装:

    #封装,隔离复杂度
    class A:
        X=1
        def test(self):
            print('from A')
    
    
    print(A.X)
    A.test(123455)
    a=A()
    a.y=1
    print(a.y)
    封装示例1
    class A:
        __x=1   #_A__x
        def __test(self): #_A__test
            print('from A')
    print(A.__x)
    print(A.__dict__)
    print(A._A__x)
    a=A()
    print(a._A__x)
    print(A.__dict__)
    A._A__test(123)
    print(A._A__test(123))
    a=A()
    a._A__test()
    __名字,这种语法,只有在定义的时候才会有变形的效果,如果类或者对象已经产生了,就不会有变形效果
    
    class B:
        pass
    B.__x=1
    print(B.__dict__)
    
    b=B()
    b.__x=1
    print(b.__dict__)
    print(b.__x)
    封装示例2
    class A:
        def fa(self):
            print('from A')
        def test(self):
            self.fa()
    class B(A):
        def fa(self):
            print('from B')
    b=B()
    b.test()    #b.test-->B----A b.fa()
    封装示例3
    #在定义阶段会变形
    class A:
        def __fa(self): #变形成 _A__fa
            print('from A')
        def test(self):
            self.__fa() #变形成 self._A__fa
    class B(A):
        def __fa(self): #_B__fa
            print('from B')
    b=B()   #self._A__fa
    b.test()    #b.test-->B----A b.fa()
    封装示例4
    class A:
        def __init__(self):
            self.__x=1
        def tell(self): #定义在类的内部,在类内部可以用__x调用,通过调用接口函数往外访问,相当于用__语法变形了,但是没有限制它能对外访问
            print(self.__x)
    a=A()
    print(a.__dict__)
    # print(a.__x)    #在类外部不能直接调用类内部的函数,只要隐藏起来了,外部就是不让访问,好处是实现了真正的隐藏,外部根本拿不到。坏处是:如果考虑不周到,把一些本不该隐藏的属性隐藏起来了,那么外部访问只能在类内部定义接口,一堆接口会导致面条式代码
    print(a._A__x)
    a.tell()    #在类外部调用
    封装示例5
  • 相关阅读:
    [心得]如何快速利用SqlMap做安全檢測
    [心得]群裡提問的流水序號產生方式
    STL中使用reverse_iterator时,如何正确使用erase函数
    西山居面试之旅
    LAMP兄弟连 视频教程集
    [译]理解Windows消息循环
    C++设计模式 -- 解析和实现
    winsock 收发广播包
    SqlServer sysobjects_table
    查询反模式
  • 原文地址:https://www.cnblogs.com/bingabcd/p/6740517.html
Copyright © 2020-2023  润新知