• Python Day6


    本章内容

    面向对象

    面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

    面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

    而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

    在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。

    类和实例

    面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

    仍以Student类为例,在Python中,定义类是通过class关键字:

    # _author_=AbeoHu
    class FOO:#
        def __init__(self):#定义对象
            pass
    class people:#
        def __init__(self):#定义对象
            pass

    执行一个简单的面向对象的代码:

    # _author_=AbeoHu
    class FOO:#
        def __init__(self,name,leader):#定义对象
            self.name=name
            self.leader=leader
    p1=FOO('xiaohu','213')
    print(p1.name,p1.leader)

    动态字段:

    # _author_=AbeoHu
    class FOO:#
        def __init__(self,name,leader):#定义对象
            self.name=name
            self.leader=leader
    p1=FOO('xiaohu','213')#动态字段
    print(p1.name,p1.leader)
    class people:
        def __init__(self,age,oo):
            self.age=age
            self.oo=oo
    h1=people('333','2222')#动态字段
    print(h1.age,h1.oo)

    静态字段:

    我在class里面定义个变量:

    class FOO:#
        meno='中国'#静态字段,不能被动态调取的,他是属于类的
        def __init__(self,name,leader):#定义对象
            self.name=name
            self.leader=leader
    p1=FOO('xiaohu','213')#动态字段
    print(FOO.meno)#调用静态字段

    动态方法:

    # _author_=AbeoHu
    class FOO:#
        meno='中国'#静态字段,不能被动态调取的,他是属于类的
        def __init__(self,name,leader):#定义对象
            self.name=name
            self.leader=leader
        def foo(self):
            print(self.name+'正在开运动会')#动态方法
    p1=FOO('xiaohu','213')#动态字段
    print(p1.foo())#调用动态方法

    静态方法:

    # _author_=AbeoHu
    class FOO:#
        meno='中国'#静态字段,不能被动态调取的,他是属于类的
        def __init__(self,name,leader):#定义对象
            self.name=name
            self.leader=leader
        def foo(self):
            print(self.name+'正在开运动会')#动态方法
        @staticmethod
        def fo():#静态方法
            print('每个省')
    p1=FOO('xiaohu','213')#动态字段
    print(p1.foo())#调用动态方法
    print(FOO.fo())#调用静态方法

    特性:将方法改成字段

    # _author_=AbeoHu
    class FOO:#
        meno='中国'#静态字段,不能被动态调取的,他是属于类的
        def __init__(self,name,leader):#定义对象
            self.name=name
            self.leader=leader
        @property#特性
        def foo(self):
            #print(self.name+'正在开运动会')#动态方法
            return '111'
        @staticmethod
        def fo():#静态方法
            print('每个省')
    p1=FOO('xiaohu','213')#动态字段
    print(p1.foo)#调用特性
    print(FOO.fo())#调用静态方法

    公有私有:

    私有字段前面要加__

    class FOO:
        def __init__(self,name,age,home):
            self.name=name
            self.age=age#公有字段
            self.__home=home#私有字段
        def show(self):#通过方法调用私有字段
            print(self.__home)
    P1=FOO('xiaohu','jiman',True)
    P1.show()#调用方法

    私有方法:

    class FOO:
        def __init__(self,name,age,home):
            self.name=name
            self.age=age#公有字段
            self.__home=home#私有字段
        def show(self):#通过方法调用私有字段
            print(self.__home)
        def __sha(self):#私有方法
            print('我是AbeoHu')
        def foo(self):#通过公有方法调用私有方法
            self.__sha()
    P1=FOO('xiaohu','jiman',True)
    P1.show()#调用方法
    P1.foo()#调用私有方法

    通过特性调用私有方法:

    class FOO:
        def __init__(self,name,age,home):
            self.name=name
            self.age=age#公有字段
            self.__home=home#私有字段
        def show(self):#通过方法调用私有字段
            print(self.__home)
        def __sha(self):#私有方法
            print('我是AbeoHu')
        def foo(self):#通过公有方法调用私有方法
            self.__sha()
        @property#通过特性调用私有方法
        def fo(self):
            self.__sha()
    P1=FOO('xiaohu','jiman',True)
    P1.show()#调用方法
    P1.foo()#调用私有方法
    P1.fo

    通过另类方法调用:

    class FOO:
        def __init__(self,name,age,home):
            self.name=name
            self.age=age#公有字段
            self.__home=home#私有字段
        def show(self):#通过方法调用私有字段
            print(self.__home)
        def __sha(self):#私有方法
            print('我是AbeoHu')
        def foo(self):#通过公有方法调用私有方法
            self.__sha()
        @property#通过特性调用私有方法
        def fo(self):
            self.__sha()
    P1=FOO('xiaohu','jiman',True)
    P1.show()#调用方法
    P1.foo()#调用私有方法
    P1.fo
    P1._FOO__sha()#通过另类方法调用私有方法,不建议

    析构函数不常用:

    class Foo:
        def __init__(self):#构造函数
            pass
        def __del__(self):#析构函数
            print("解释器要销毁我了,我要做最后一次呐喊")

    类的继承:

    class FOO():
        def __init__(self):
            pass
        def sport(self):
            print('抽烟喝酒')
    class foo(FOO):#FOO代表继承FOO类
        def __init__(self):
            pass
        def s(self):
            FOO.sport(self)#调用FOO的对象
    s1=foo()#调用
    s1.s()

    如果想要增加新的功能(两种方法):

    class FOO():
        def __init__(self):
            pass
        def sport(self):
            print('抽烟喝酒')
    class foo(FOO):#FOO代表继承FOO类
        def __init__(self):
            pass
        def s(self):
            FOO.sport(self)#调用FOO的对象
            print('烫头')
    s1=foo()#调用
    s1.s()

     如果想修改呢?在子类下边定义函数:

    class FOO():
        def __init__(self):
            pass
        def sport(self):
            print('抽烟喝酒')
    class foo(FOO):#FOO代表继承FOO类
        def __init__(self):
            pass
        def sport(self):
                print("抽烟")
    s1=foo()#调用
    s1.sport()

    super函数,继承父类的init构造函数:

    class FOO(object):#给父类一个object类
        def __init__(self):
            print('fffff')
        def sport(self):
            print('抽烟喝酒')
    class foo(FOO):#FOO代表继承FOO类
        def __init__(self):
            super(foo,self).__init__()#调用父类init
        def sport(self):
                print("抽烟")

    经典类和新式类区别

    新式类:object

    class foo(object)
    经典类:没有object的就是经典类

    class foo

    经典类和新式类的继承,构造函数的查找顺序

     以python3为例:

    以下查找顺序叫做广度优先:

     还有一种叫做 深度优先,出现在python2的经典类中

    总结:

    python2 中经典类是按深度优先来继承的,新式类是按广度优先来继承的

    python3 中经典类和新式类都是统一按广度优先来继承的

    多态化

    同一个接口,多种实现

    OK,那我们先来定义个继承的类

    class Animail(object):
        def run(self):
            print("Animail is running")
    class Dog(Animail):
        pass
    class Cat(Animail):
        pass

    那么我们定义个变量,将Dog和Cat打印出来

    d=Dog()
    b=Cat()
    d.run()
    b.run()
    Animail is running
    Animail is running

    两者都会运行

    OK,那咱们再做个稍微的修改

    我在dog里面就是dog在运行,我在cat里面就是cat在运行,就是修改继承过来的类

    class Animail(object):
        def run(self):
            print("Animail is running")
    class Dog(Animail):
        def run(self):
            print("Dog is running")
    class Cat(Animail):
        def run(self):
            print("Cat is running")
    d=Dog()
    b=Cat()
    d.run()
    b.run()

    要理解多态的好处,我们还需要在定义个函数来做传参

    class Animail(object):
        def run(self):
            print("Animail is running")
        def run_rwit(animail):#定义新函数作为传参
            animail.run()
            animail.run()
    class Dog(Animail):
        def run(self):
            print("Dog is running")
    class Cat(Animail):
        def run(self):
            print("Cat is running")

    OK,我们来运行下,看看区别,我们先把类Animail作为传参掉进去:

    class Animail(object):
        def run(self):
            print("Animail is running")
        def run_rwit(animail):#定义新函数作为传参
            animail.run()
            animail.run()
    class Dog(Animail):
        def run(self):
            print("Dog is running")
    class Cat(Animail):
        def run(self):
            print("Cat is running")
    C=Animail
    C.run_rwit(Animail())
    结果
    Animail is running
    Animail is running

    OK,那我们将Dog通过传传进去,同样也是打印dog的类:

    class Cat(Animail):
        def run(self):
            print("Cat is running")
    C=Animail
    C.run_rwit(Dog())
    Dog is running
    Dog is running

    类推,不管你是Cat还是Dog,还是Animail,他都是通过一个对象调用进去的,这就叫多态

    你会发现,新增一个Animal的子类,不必对run_twice()做任何修改,实际上,任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。

    多态的好处就是,当我们需要传入DogCatTortoise……时,我们只需要接收Animal类型就可以了,因为DogCatTortoise……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思:

    对于一个变量,我们只需要知道它是Animal类型,无需确切地知道它的子类型,就可以放心地调用run()方法,而具体调用的run()方法是作用在AnimalDogCat还是Tortoise对象上,由运行时该对象的确切类型决定,这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:

    对扩展开放:允许新增Animal子类;

    对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

    继承还可以一级一级地继承下来,就好比从爷爷到爸爸、再到儿子这样的关系。而任何类,最终都可以追溯到根类object,这些继承关系看上去就像一颗倒着的树。比如如下的继承树:

  • 相关阅读:
    基于mAppWidget实现手绘地图--索引&DEMO
    C语言数据结构----栈的定义及实现
    libvirt命令行文档
    清理系统方法
    Linux 经典电子书共享下载
    使用数组实现队列----《数据结构与算法分析---C语言描述》
    清理系统垃圾
    epoll的内部实现 & 百万级别句柄监听 & lt和et模式非常好的解释
    进程、线程、socket套接字-资源大小 & 切换代价
    网络编程学习-面向工资编程
  • 原文地址:https://www.cnblogs.com/AbeoHu/p/5819317.html
Copyright © 2020-2023  润新知