zoukankan      html  css  js  c++  java
  • 面向对象基础总结

    继承

    什么是继承?

    继承是一种新建类的方式 新建类称为 子类 /派生类 被继承的类称之为 父类/基类/超类

    继承的 特性: 子类可以遗传/重用父类的属性

    1.python中一个子类可以同时继承多个父类

    2.在继承背景下说 python中的类分为 两种,新式类,经典类

    新式类:但凡继承了object的类 以及该类的子类 都是 新式类(可以用到 object的方法)在python中一个类即便是没有显示的继承任何类 默认就会继承object

    ​ 经典类:没有继承object的类,以及该类的子类 .. 都是经典类 python2 中才会区分新式类和经典类 在python中一个类即便是没有显示的继承任何类 也不会继承object

    class Foo(object):  python3和python2 中都可以用的新式类
        pass
    
    print(Foo.__bases__) # 查看基类符 父类
    

    为何要是用继承?

    减少类与类之间的代码冗余

    class Foo(object):
        x = 111
    
    class Sub(Foo):
        x = 222
    f = Sub()
    f.x = 333
    print(f.x)
    

    在子类派生的新方法中重用父类功能的方式一

    指名道姓的方式: 指名道姓的引用某一个;类的函数
        # 总结 和继承没有关系 2.访问的是类的函数 没有自动传值得效果
    class Oldboy:
        def __init__(self, name, age, sex):
            self.name = name 
            self.age = age 
            self.sex = sex
            
    class Student(Oldboy):
        def __init__(self,name, age, sex, score):
            Oldboy.__init__(self,name, age, sex)
            self.score = score
    

    菱形继承问题:

    新式类:广度优先,从左往右一个分支一个分支的查找,最后一个分支才去顶级查找

    经典类:深度优先查找,从左往右有个分支一个分支的查找,在第一个分支就去顶级查找

     f.mto() #等于f.__mro__ 查看顺序 mro列表就是一个简单的所有基类的线性顺序
    class A:
        pass
    
    class B(A):
        pass
    
    class C(B):
        pass
    
    print(C.mro())
    
    # [<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
    

    在子类派生的新方法中重用父类功能的方式二super

    super(自己的类名,自己的  对象)必须在类中使用
    #在python2中 :super(自己的类名,自己的对象)
    #在python3中 :super()
    #调用该函数会得到一个返回值 是一个特殊的对象 对象访问一个功能 就是绑定方法 自动传值  该对象专门用来父类中的属性!!!
                                 
    完全参照mro列表查找    严格依赖继承 mro列表 访问的是一个绑定方法 有自动传值的方法
    
    class Oldboy:
        def __init__(self, name, age, sex):
            self.name = name 
            self.age = age 
            self.sex = sex
            
    class Student(Oldboy):
        def __init__(self,name, age, sex, score):
            
            Oldboy.__init__(self,name, age, sex)
            super(Oldboy,self).__init__(name, age, sex)
            super().__init__(name, age, sex) 
            
            self.score = score
    
    
    

    组合

    组合指的是某一个对象拥有一个属性,这个属性是另外一个类的对象

    多态

    什么是多态?

    同一种事物分不同的形态

    class Animal: #动物有了就全都有了
        def speak(self):
            pass
    class dog(Animal):
        pass
    class pig(Animal):
        pass
    class people(Animal):
        pass
    obj = dog()
    obj1 = pig()
    obj2 = people()
    
    obj.speak()
    obj1.speak()
    obj2.speak()
    
    

    为什么使用多态

    多态性:在多态的背景下,可以不用考虑对象具体类型的前提下而直接使用对象

    模块abc 强制子类遵循父类的规范

     import abc
    class Animal(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def speak(self):
            pass
    
    class People(Animal):
        def speak(self):
            print('say helllo')
    
    
    class pig(Animal):
        def speak(self):
            print('henehnehen')
    
    
    class dog(Animal):
        def speak(self):
            print('wannwanwna')
    
    obj = People()
    obj2 = pig()
    obj3 = dog()
    

    python中 不推崇限制你 崇尚鸭子类型 只要你长得像 你就是

    封装

    什么是封装? 装 :往名称空间里/容器里存入名字

    封: 代表 将存放于名称空间的名字隐藏起来 对外 不对内

    如何装?

    在类定的属性前加__开头 没有结尾 (****)

    class A:
        __x = 123
        def __init__(self, name, age):
            self.__name = name
            self.__age = age
        def get__(self):  #通过函数是可以访问的
            print(self.__name, self.__age)
            
    # 对外隐藏  内部是可以访问到的
    
    #__ 到底如何实现了隐藏 
    只要是__开头的 他就会把你的开头改成  _A__X : 123 仅仅只是语法意义上的变形 并不会真正的限制类外部的访问
    
    #如何实现的对外隐藏 对内开放
    改变形操作 只会在类定义阶段 检测语法时 执行一次,类定义阶段之后新增的__开头的属性并不会变形  
    

    为什么要封装?

    封数据属性 : 将数据属性隐藏起来 类外部无法直接操作属性 需要类内部开辟一个接口 可以使外部间接的操作属性 (可以在接口上定义任意的控制逻辑 从而严格的控制属性)

    封函数属性 :隔离复杂度 还是不能直接给外部使用 需要开个接口来调用

    property装饰器 是用来将类中的函数属性装饰成数据属性

    class D:
        def __init__(self, name, height, weight):
            self.__name = name
            self.height = height 
            self.weight = weight
    	@property
        def bim(self):
            return self.weight / (self.height**2)
         
        @bin.setter
        def bin(self,obj)
            if type(obj) is not str:
                print('输入字符串呀')
        	self.__name == obj
           
        @bin.deleter
        def bin(self)
        	del self.__name
      
      s = D()
    s.bim  #就可以调用了
    s.bim = 'engon'
    del s.bin
    
    bin = property(get_bin, set_bin, del_bin)
    
    
    

    绑定方法 与 非绑定方法

    两大类 三小种

    绑定方法 绑定给谁 就会把谁当做第一个参数传入

    绑定给对象的 类中定义的函数都是绑定给对象的

    classmethod 会将类作为第一个参数自动传入 (需要类名或其他 )

    staticmethod 非绑定方法 既不与类绑定 又不与对象绑定 普通函数没有自动传值的效果

    class A:
    	def index(self):
    		print('我是对象绑定')
    		
    	@classmethod
    	def f2 (cls):
    		print('我是绑定给类的')
    
    import uuid 
    uuid.uuid4()  生成一个第一无二的编号
    

    面向对象高级(边边脚脚)

    isinstance () 判断一个对象是否是一个类的实例 返回true false

    print(isinstance([1,23,4], list))
    
    

    issubclass() 判断是否是子类 (父类, 子类)

    反射 属性操作 通过字符串 反射或者映射到对象或者类的属性上

    hasarrt 本质 'name' in obj.__dict __判断有没有

    getattr 本质 obj.dict['name'] 获取属性的值 没有报错 第三个参数有的话找不到返回

    setattr 设置值 修改值 setattr(obj,'name', 'egon') 存在修改 不存在 添加

    delattr delattr(obj, 'name') 删除

    内置方法 str del

    # 内置方法是  满足某种条件下自动触发
    __str__ 在对象被打印时自动触发,可以用来定义对象被打印时的输出信息
    __del__ 在对象被删除时先自动触发  可以用来回收对象以外的其他相关资源 
    __call__ (self, *args, **kwargs)  在对象被调用时先自动触发  可以用来回收对象以外的其他相关资源 
    
    趁自己还没死 多折腾折腾
  • 相关阅读:
    Java入门系列之集合Hashtable源码分析(十一)
    哈希算法原理【Java实现】(十)
    Java入门系列之集合LinkedList源码分析(九)
    双链表算法原理【Java实现】(八)
    Java入门系列之集合ArrayList源码分析(七)
    动态数组原理【Java实现】(六)
    Java入门系列之类继承、抽象类、接口(五)
    Java入门系列之包装类(四)
    Java入门系列之StringBuilder、StringBuffer(三)
    Java入门系列之字符串特性(二)
  • 原文地址:https://www.cnblogs.com/lddragon/p/11267382.html
Copyright © 2011-2022 走看看