zoukankan      html  css  js  c++  java
  • python 类的知识点2

    **类知识点2**
    **在子类中调用父类的两种方法**

    方式一 父类名.父类方法()
        class Vehicle:  # 定义交通工具类
            Country = 'China'
            def __init__(self, name, speed, load, power):
                self.name = name
                self.speed = speed
                self.load = load
                self.power = power
       
            def run(self):
                print('开动啦...')

        class Subway(Vehicle):  # 地铁类嵌入交通工具类
            def __init__(self, name, speed, load, power, line):
                Vehicle.__init__(self, name, speed, load, power)  # 父类名.父类方法
                self.line = line
        def run(self):
            print('地铁%s号线欢迎您' % self.line)
            Vehicle.run(self)

        line13 = Subway('中国地铁', '180m/s', '1000人/箱', '电', 13)  # 实例化类,创造出一个类
        line13.run()   # 类绑定方法
    方法1中,使用了父类名.父类方法(),
         Vehicle.__init__(self, name, speed, load, power)
       
    方法二 使用super()函数
        class Vehicle: #定义交通工具类
             Country='China'
             def __init__(self,name,speed,load,power):
                 self.name=name
                 self.speed=speed
                 self.load=load
                 self.power=power
       
             def run(self):
                 print('开动啦...')
        class Subway(Vehicle): # 地铁
            def __init__(self,name,speed,load,power,line):
                    #super(Subway,self) 就相当于实例本身 在python3中super()等同于super(Subway,self)
                    super().__init__(name,speed,load,power)
                    self.line=line
           
            def run(self):
                print('地铁%s号线欢迎您' %self.line)
                super(Subway,self).run()
        class Mobike(Vehicle):#摩拜单车
            pass
        line13=Subway('中国地铁','180m/s','1000人/箱','电',13)
        line13.run()
                   
    方法2使用了super(),
      
        super().__init__(name,speed,load,power)
    super()相当于实例本身,在python3中super()等同于super(Subway,self)  方式一不依赖于继承,方式二依赖继承,即便没有直接的继承关系,super仍然会按照mro继续往后找
       
      
        class A:
            def test(self)
                super().test()
           
        class B:
            def test(self):
                print('from B')
           
        class C(A,B):
            pass
        c=C()
        c.test() #打印结果:from B
    在以上代码中,c=C(),表示实例化C类,创建c对象,c.test(),绑定test()方法属性到c对象,由于c无test方法属性,类C也没有,因此将从继承的A类里找,找到test(),因为test()方法属性里出现super().test(),super()的意义在于即使没有继承关系,仍然会按照mro线性顺序列表继续往后找对象基类。
    **组合与重用性**

    软件重用的重要方式除了继承之外还有另外一种方式,即:组合
    组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合
    继承中,类与类之间的关系为什么是什么的关系,组合则是什么有什么的关系

        class Head: # 英雄头饰类
             def head(self):
                 print('猪头')
       
        class Equip: #武器装备类
             def fire(self):
                 print('release Fire skill')
        
        class Riven: #英雄Riven的类,一个英雄需要有装备,还可以装扮头像,因而需要组合Equip,Head类
             camp='Noxus'
             def __init__(self,nickname):
                 self.nickname=nickname
                 self.equip=Equip()
                 self.head=[] #用Equip类产生一个装备,赋值给实例的equip属性
        
         r1=Riven('锐雯雯')
         r1.equip.fire()  # 可以使用组合的类产生的对象所持有的方法
         r1.head.apend(Head())
         r1.head[0].head()# 可以使用组合的类产生的对象所持有的方法
        release Fire skill
        猪头
       
       
     
    ** 接口** 
    接口:提供了一个类的集合,可以把接口当作类函数的集合,让子函数去实现功能
    归一化:基于同一个接口实现的类

    **抽象类**
    类是从一堆对象中抽取相同的内容,抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性,该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的。

    ** 在python中实现抽象类**
        #一切皆文件
        import abc #利用abc模块实现抽象类
        class All_file(metaclass=abc.ABCMeta):
            all_type='file'
            @abc.abstractmethod #定义抽象方法,无需实现功能
            def read(self):
                '子类必须定义读功能'
                pass
       
         class Txt(All_file):
             pass   
        t1=Txt()  # 程序报错
    会报错是因为其在继承All_file类之后没有定义read的抽象方法,实现read功能,改正如下
        class Txt(All_file): #子类继承抽象类,但是必须定义read方法
            def read(self):
                print('文本数据的读取方法')
               
        wenbenwenjian=Txt()
        wenbenwenjian.read()
        print(wenbenwenjian.all_type)
       
    **抽象类与接口**
    抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。
    抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计
      
      
    **多态**
    多态指的是一类事物有多种形态, 动物有多种形态:人,狗,猪

        import abc
        class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
            @abc.abstractmethod
            def talk(self):
                pass
       
        class People(Animal): #动物的形态之一:人
            def talk(self):
                print('say hello')
       
        class Dog(Animal): #动物的形态之二:狗
            def talk(self):
                print('say wangwang')
       
        class Pig(Animal): #动物的形态之三:猪
            def talk(self):
                print('say aoao')
    **多态性**
    指在不考虑实例类型的情况下使用实例,多态性分为静态多态性和动态多态性
    多态性好处
    1 增加了程序的灵活性
    2 增加了程序额可扩展性
    静态多态性:如任何类型都可以用运算符+进行运算
       
       
    动态多态性:如下
        peo=People()
        dog=Dog()
        pig=Pig()
       
        #peo、dog、pig都是动物,只要是动物肯定有talk方法
        #于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
        peo.talk()
        dog.talk()
        pig.talk()
       
        #更进一步,我们可以定义一个统一的接口来使用
        def func(obj):
            obj.talk()

    **鸭子类型 **  

    Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’
    python程序员通常根据这种行为来编写程序。
    例如,如果想编写现有对象的自定义版本,可以继承该对象
    也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。

        class TxtFile:
            def read(self):
                pass
       
            def write(self):
                pass
       
        class DiskFile:
            def read(self):
                pass
            def write(self):
                pass

    **封装**
    隐藏
    在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)
        #其实这仅仅这是一种变形操作
        #类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式:
       
        class A:
            __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
            def __init__(self):
                self.__X=10 #变形为self._A__X
            def __foo(self): #变形为_A__foo
                print('from A')
            def bar(self):
                self.__foo() #只有在类内部才可以通过__foo的形式访问到.
       
        #A._A__N是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形
       
    自动变形的特点:
    类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。
    这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。
    在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。
       
       
       
            #把fa定义成私有的,即__fa
        >>> class A:
        ...     def __fa(self): #在定义时就变形为_A__fa
        ...         print('from A')
        ...     def test(self):
        ...         self.__fa() #只会与自己所在的类为准,即调用_A__fa
        ...
        >>> class B(A):
        ...     def __fa(self):
        ...         print('from B')
        ...
        >>> b=B()
        >>> b.test()
        from A
        self.__fa()变成_A__fa,fa只在A类内部使用,如果是self.fa(),则返回到对象b里使用。
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
  • 相关阅读:
    【JAVA基础】正则表达式
    【JAVA基础】常用类的概述和使用
    【JAVA基础】反射机制
    献芹奏曝-Python面试题
    饮冰三年-人工智能-Python-65-Apollo之07 Docker环境部署
    饮冰三年-人工智能-Python-64-Apollo之06测试环境部署
    饮冰三年-人工智能-Docker-63-Docker部署文件帮助系统Mezzanine
    饮冰三年-人工智能-Python-62-ZooKeeper之04实战
    饮冰三年-人工智能-Python-61-ZooKeeper之03原理
    饮冰三年-人工智能-Python-60-ZooKeeper之02安装
  • 原文地址:https://www.cnblogs.com/zhoudabing/p/10443240.html
Copyright © 2011-2022 走看看