美文网首页
面向对象

面向对象

作者: Yanl__ | 来源:发表于2019-08-22 09:20 被阅读0次

    对象 = 类名()
    A = className()

    1. 过程
    • 类名() 首先会创造出一个对象,创建了一个self变量
      self可以理解为一个接受参数的字典
    • 调用init方法,类名括号里的参数会被这里接收
    • 执行init方法
    • 返回self
    1. 对象能做的事
    • 查看属性
    • 调用方法
    • __dict__ 对于对象的增删查改操作都可以通过字典的语法进行
    1. 类名能做的事
    • 实例化对象
    • 调用方法: 要自己传递self参数
    • 调用类中的属性(静态属性)
      类中的静态变量,可以被对象和类调用
      1.对于不可变数据类型来说,类变量最好用类名操作
      2.对于可变数据类型(eg:list)来说,对象名的修改是共享的,重新赋值是独立的
    course.language = ['chinese']  # 类中的静态属性
    ----------------------------------------
    x.language[0] = 'english'  # 修改是共享的,会修改类中的静态属性的值,以及所有实例中的值
    x.language = ['english']  # 修改是独立的,只会修改实例x中的值。类中的静态属性以及其他实例中的静态属性的值都不会变
    
    • __dict__ 对于类中的名字只能看,不能操作
    • 类名.静态属性 = 新值 可以更改静态属性

    绑定方法

    对象调用类中的方法的时候,会把值传入方法,它们之间发生了绑定关系

    组合

    一个对象的属性值是另外一个类的对象

    A.b 
    b是另一个类的对象 
    A.b.func  (func是另一个类中的方法)
    

    例子:

    from math import pi
    class Circle:
        def __init__(self, r):
            self.r = r
        def area(self):
            return self.r**2*pi
        def perimeter(self):
            return 2*pi*self.r
    
    class Ring:
        def __init__(self, outside_r, inside_r):
            self.outside_c = Circle(outside_r)  # 组合
            self.inside_c =Circle(inside_r)  # 组合
    
        def area(self): return self.outside_c.area() - self.inside_c.area()
        def perimeter(self): return self.outside_c.perimeter() + self.inside_c.perimeter()
    
    ring = Ring(20, 10)
    print(ring.area())
    print(ring.perimeter())
    

    接口类、抽象类

    # java : 面向对象编程
    # 设计模式   —— 接口
    # 接口类 : python原生不支持
    # 抽象类 : python原生支持的
    from abc import abstractmethod,ABCMeta
    class Payment(metaclass=ABCMeta):  # 元类 默认的元类 type
        @abstractmethod
        def pay(self,money):pass   # 没有实现这个方法
    # 规范 :接口类或者抽象类都可以
    # 接口类 支持多继承,接口类中的所有的方法都必须不能实现 —— java
    # 抽象类 不支持多继承,抽象类中方法可以有一些代码的实现 —— java
    class Wechat(Payment):
        def pay(self,money):
            print('已经用微信支付了%s元'%money)
    
    class Alipay(Payment):
        def pay(self,money):
            print('已经用支付宝支付了%s元' % money)
    
    class Applepay(Payment):
        def pay(self,money):
            print('已经用applepay支付了%s元' % money)
    
    def pay(pay_obj,money):  # 统一支付入口
        pay_obj.pay(money)
    
    # wechat = Wechat()
    # ali = Alipay()
    app = Applepay()
    # wechat.pay(100)
    # ali.pay(200)
    p = Payment()
    

    继承

    在python3中,所有的类,如果没有继承父类,那么默认继承object类。class A(object):pass =class A:pass

    • 父类中没有的属性,在子类中出现 叫做派生属性
    • 父类中没有的方法,在子类中出现,叫做派生方法
    • 只要是子类的对象调用,子类中有的方法,一定用子类的,子类中没有的去父类中找,如果也没有,则会报错。
    class Base:
        def __init__(self, name):
            self.name = name
            self.Testfunc()  # self 是谁的对象就先从谁中找方法
    
        def Testfunc(self):
            print('do Base Testfunc')
    
    class Son(Base):
        def Testfunc(self):
            print('do Son Testfunc')
    
    
    sonobj = Son('zhang')
    # 创建一个子类对象,先执行init方法,son中没有,从父类中找,执行父类中的init方法,其中self.Testfunc() Testfunc方法父类,子类中都有,
    # 看self是谁的对象,self是创建的子类对象,现在子类Son中找该方法,如果没有再从父类中找
    
    # 输出 do Son Testfunc
    
    • 如果子类中有的方法,依然想用父类中的方法
      1.父类名.方法名(self, 其他参数) ,并且传self参数
      1. super().方法名(其他参数) 不需要自己传self
    1. 通过父类名称.init()执行父类的init函数
    2. 通过super().init()执行父类的init函数
    class Animal:
        def __init__(self, name, aggr, hp):
            self.name = name
            self.aggr = aggr
            self.hp = hp
    
        def eat(self):
            print('animal eating')
    
    class Dog(Animal):
        def __init__(self, name, aggr, hp, kind):
            Animal.__init__(self, name, aggr, hp)  #  通过父类名称.__init__()执行父类的init函数
            # super().__init__(name, aggr, hp)  # 通过super().__init__()执行父类的init函数
            self.kind = kind
    
    zhao = Dog('zhaoritian', 100, 50, 'teddy')
    print(zhao.name)
    
    多继承
    • 在Java的角度上看,接口类和抽象类是有区别的
      1. java没有多继承,所以为了接口隔离原则,设计了接口这个概念,支持多继承了
      2. java本来就支持单继承,所以就有了抽象类
      3. 在python中即支持单继承也支持多继承,所以对于接口类和抽象类的区别就不那么明显类
    • (新式类)python3中,寻找父类 使用的是广度优先原则
    • (经典类)python2中,寻找父类 使用的是深度优先原则
    • A.mro()可以查看A类的继承顺序
    • 新式类 默认继承object
    • super 只在python3中有。 super不是单纯找父类,而是根据调用者的节点位置的广度优先顺序来的


      image.png

    多态

    • 多态
      python天生支持多态(传参数时,不需要指定参数类型)
    • 鸭子类型
      在不依赖父类的情况下实现两个相似的类中的同名方法

    封装

    在python中只要 __名字 就把这个名字私有化了。私有化后就不能从类的外部直接调用了。

    私有
    • 私有属性
    • 私有方法
    1. 所有的私有, 都是在变量的左边加上双下划线
      • 对象的私有属性
      • 类中的私有方法
      • 类中的静态私有属性
    2. 所有的私有的,都不能在类的外部使用(只是从代码级别做了变形,并没有真的约束。 在类外调用用 类名_名字)
    class Person:
        __key = 123  # 静态私有属性
        def __init__(self, name, passwd):
            self.name = name
            self.__passwd = passwd  # 私有属性
    
        def __get_pwd(self):  # 私有方法
            print(self.__dict__)
            return self.__passwd  # 只要在类的内部调用私有属性,都会自动加上 _类名
    
        def login(self):
            return self.__get_pwd()
    
    
    test1 = Person('yan', '123456')
    print(test1._Person__passwd)  # _类名__属性名
    test1.__one = 1  # 在类的外部不能创建私有属性,此处创建的并不是私有静态属性
    print(test1.__one)
    print(test1.login())
    print(test1.__get_pwd())  # 在类的外面不能调用私有方法
    
    1. 父类的私有属性 子类不能调用
    2. 使用私有这个概念的场景:
      • 隐藏这个属性,不想让类的外部调用
      • 保护这个属性,不想让属性随意被改变
      • 保护这个属性,不想被子类继承

    相关文章

      网友评论

          本文标题:面向对象

          本文链接:https://www.haomeiwen.com/subject/xqqbsctx.html