• python入门(十四):面向对象(属性、方法、继承、多继承)


    1、任何东西
    1)属性(特征:通常可以用数据来描述)
    (类变量和实例变量)
    2)可以做一些动作(方法)

    类来管理对象的数据。
    属性:类变量和实例变量(私有变量)
    方法:
        1)实例方法
        2)类方法
        3)静态方法
     
    2、面向对象和函数管理数据:
     类:
    有专有数据(可以存储,和对外使用)
    方法(用于操作专有数据的),实现操作数据的规则。

    函数:
    无专有数据,谁给他传值都可以处理,并返回
    本身不能存储数据。

    class compute:    #定义了类compute

        def __init__(self,a,b):
            self.a = a
            self.b = b

        def add(self):    #方法是对输入的数进行的操作,说明已经存储

            return self.a+self.b

    def add(a,b):    #定义了函数add()
        return a+b

    #print(add(1,2))
    c= compute(1,2)    #类具备存储的功能
    print(c.add())

    print(c.a)                          #可以查看当时输入的数据,因为已经存储

    print(c.b)                          #可以查看当时输入的数据,因为已经存储

    print(c.a+1)                        #可以对输入的数据进行更改

    print(c.b+1)                        #可以对输入的数据进行更改

    c.a+=1                               #可以对输入的数据进行赋值

    print(c.a)

    c.b+=1         #可以对输入的数据进行赋值

    print(c.b)                         

    运行结果:

    E:>python a.py

    3

    3

    1

    2

    2

    3

    2

    3

     类:作为一个整体,
    把一组相关数据放到类的实例里面,进行存储、计算等实现安全性、独立性,规则的操作统一。

    3、实例方法
     class Person:

        def __init__(self,name,gender):
            self.name = name
            self.gender = gender

        def get_name(self):#实例方法,必须要实例化
            return self.name

    print(Person.get_name())         #不能直接通过类名调用实例方法。

    原因:实例方法未经过实例化,仅仅通过类名找到了调用方法,但是执行该方法时,找self的值时,没有,所以找不到实例的数据。


    #print(Person("吴老师","Male").get_name())#只能使用一次(连着写,没有存到变量里,使用一次就消失了)
    wulaoshi = Person("吴老师","Male")        #将实例化存到一个变量中
    print(wulaoshi.get_name())    #调用变量中的实例方法
     
    4、类方法
     class Person:
        count = 0 #类变量

        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1

        def get_name(self):#实例方法,必须要实例化
            return self.name

    #类方法:可以使用类变量,不能使用实例变量(参数没有self,找不到实例的地址,因此不能用实例变量。)
    #通过类名来使用,类名.get_instance_count()
    #也可以通过实例调用,实例对象.get_instance_count()
        @classmethod    #装饰器
        def get_instance_count(cls):    #类方法,cls不必非得是cls,但建议用cls
            return Person.count      #类方法是可通过类名,直接调用该方法    


    #只能使用一次
    #print(Person("吴老师","Male").get_name())
    #wulaoshi = Person("吴老师","Male")#实例化
    #print(wulaoshi.get_name())
    #print(Person.count)
    #Person("吴老师","Male")
    #print(Person.count)
    #print(Person.get_instance_count())
    print(Person("吴老师","Male").get_instance_count())#通过实例对象调用类方法
     

    可以在类方法中创建实例:

    class Person:

        count=0

        def __init__(self,name,gender):

            self.name = name

            self.gender = gender

            Person.count += 1

        def get_name(self):

            return self.name

        @classmethod                                #装饰器

        def get_instance_count(cls):           #类方法

            return Person.count

        @classmethod

        def create_a_instance(cls):

            return Person("zhang","male")

    print(Person.create_a_instance())

    运行结果:

    E:>python a.py

    <__main__.Person object at 0x0000020602080588>

    5、静态方法
     class Person:
        count = 0 #类变量
        nation = "中国"

        def __init__(self,name,gender):    #构造方法
            self.name = name
            self.gender = gender
            Person.count +=1

        def get_name(self):#实例方法,必须要实例化
            return self.name

        @classmethod    #类方法
        def get_instance_count(cls):
            return Person.count

        @classmethod    #类方法
        def create_a_instance(cls):
            return Person("张","女")

        @staticmethod   #静态方法:不需要self和cls
        def get_nation():
            return Person.nation
     
         @staticmethod   #静态方法:不需要self和cls
        def get_more():
            Person.count +=100
            return Person.count

    #只能使用一次
    #print(Person("吴老师","Male").get_name())
    #wulaoshi = Person("吴老师","Male")#实例化
    #print(wulaoshi.get_name())
    #print(Person.count)
    #Person("吴老师","Male")
    #print(Person.count)
    #print(Person.get_instance_count())
    #print(Person.create_a_instance())
    #print(Person("吴老师","Male").get_instance_count())
    print(Person.get_nation())
    print(Person("吴老师","Male").get_nation())    #通过实例调用静态方法
    print(Person("吴老师","Male").get_more())
     
     三种方法的区别:
    1 实例方法,参数要有self,必须通过实例化的对象去调用。
    2 类方法,要加上@classmethod来声明,参数至少有一个,
    一般定义为cls,只能使用类变量,不能使用实例变量。
    通过类名或者实例对象调用。
    3 静态方法,要加上@staticmethod来声明,可以没有参数,
    使用类变量,不能使用实例变量。
    通过类名或者实例对象调用。
     

    不想做实例化,且只操作类变量的时候:类方法、静态方法
    如果想使用实例变量,只能使用实例方法了。

    6、单继承

    1) 子类没有写构造方法:

     class Person:
        count = 0 #类变量
        nation = "中国"

        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1
            print("创建了一个新的人")

        def get_name(self):#实例方法,必须要实例化
            return self.name

    class ChinaPerson(Person):    #子类什么都没有干
        pass  #如果子类没有定义__init__构造方法,会自动调用父类的。
     

    cp = chinaPerson()  

    运行结果:

    E:>python a.py

    Traceback (most recent call last):

      File "a.py", line 18, in <module>

        cp = chinaPerson()

    TypeError: __init__() missing 2 required positional arguments: 'name' and 'gender'

    #如果子类没有定义构造方法,会自动调用父类的。所以实例化时,需要两个参数

    cp = ChinaPerson("吴老师","男")    #子类实例化
    print(cp.name)    #子类中,沿用了父类的name
    print(cp.gender)    #子类中,沿用了父类的gender
    print(cp.get_name())   #子类中,沿用了父类的方法
    print(cp.count)   
     

    """
    继承:子类具备所有父类的共有变量和共有方法
    如果子类没有定义__init__构造方法,会自动调用父类的。
    好处:站在老爸的肩膀上,增加属性,增加方法
    在原有的基础上进行扩展。
    """

    2) 子类自定义构造方法

    class Person:

        count = 0                 #count是父类的类变量

        nation = "中国"

        def __init__(self,name,gender):

            self.name = name

            self.gender = gender

            Person.count+=1

            print("创建了一个新的人")

        def get_name(self):

            return self.name

    class chinaPerson(Person):

        def __init__(self,name,gender):       #子类自定义的构造方法

            self.name = name

            self.gender = gender

            

        def get_gender(self):

            return self.gender

    cp = chinaPerson("laoshi","男")

    print(cp.count)

    运行结果:

    E:>python a.py

    0  

    #由于子类自定义了构造方法,而Person.count+=1的语句是在父类的构造方法中,所以在执行子类的实例中,不会进行Person.count+=1,所以输出结果为0

    3) 子类写明调用父类构造方法

     class Person:
        count = 0 #类变量
        nation = "中国"

        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1
            print("创建了一个新的人")

        def get_name(self):#实例方法,必须要实例化
            return self.name

    class ChinaPerson(Person):
          #如果子类没有定义__init__构造方法
          #会自动调用父类的。
        def __init__(self,name,gender):
            Person.__init__(self,name,gender)    #子类中写明调用父类的构造方法

        def get_gender(self):
            return self.gender

    cp = ChinaPerson("吴老师","男")
    print(cp.count)       #父类的类变量会加一
     
    --------------------------------------------------------------------------------------------------------------

    class Person:

        count = 0

        nation = "中国"

        def __init__(self,name,gender):

            self.name = name

            self.gender = gender

            Person.count+=1

            print("创建了一个新的人")

        def get_name(self):

            return self.name

    class chinaPerson(Person):

        def get_gender(self):

            return self.gender

    cp = chinaPerson("laoshi","男")

    print(cp.name)

    print(cp.gender)

    print(cp.get_name)

    print(cp.get_gender())               #可以调用子类自身的方法

    运行结果:

    E:>python a.py

    创建了一个新的人

    laoshi

    <bound method Person.get_name of <__main__.chinaPerson object at 0x0000023446930588>>

     
     
    7、多继承

    在括号里面写上多个基类(父类)

    1)子类的构造函数,如果没有实现,则调用第一个基类的构造函数

     class Person:
        count = 0 #类变量
        nation = "中国"

        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1
            print("创建了一个新的人")

        def get_name(self):#实例方法,必须要实例化
            return self.name

    class Bird:

        def __init__(self,color):
            print("a bird is birthed!")
            self.color = color

        def fly(self):
            print("I can fly in the sky!")

    class ChinaBirdPerson(Person,Bird):    #该子类()中有两个基类
          #如果子类没有定义__init__构造方法,会自动调用父类的。
          #该子类没有定义自己的构造函数

        def get_gender(self):
            return self.gender

    cp = ChinaBirdPerson("吴老师","男")

    print(cp.count)
    运行结果:
    E:>python a.py
    创建了一个新的人   #该子类的实例调用的是第一个父类的构造方法
    1

    -------------------------------------------------------------------------

    print(cp.color)                    #打印第二个基类的参数color

    运行结果:

    E:>python a.py

    创建了一个新的人

    Traceback (most recent call last):

      File "a.py", line 32, in <module>

        print(cp.color)

    AttributeError: 'chinaBirdPerson' object has no attribute 'color' #子类没有color对象

    原因:虽然子类能够继承过来Bird这个基类但是没有进行Bird的初始化,所以不会调用。

    因为子类没有构造函数的情况下,则调用第一个基类的构造函数。

     
    2) 子类的构造函数,将两个基类都进行初始化,都继承
     class Person:
        count = 0 #类变量
        nation = "中国"

        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1
            print("创建了一个新的人")

        def get_name(self):#实例方法,必须要实例化
            return self.name

    class Bird:

        def __init__(self,color):
            print("a bird is birthed!")
            self.color = color

        def fly(self):
            print("I can fly in the sky!")

    class ChinaBirdPerson(Person,Bird):
          #如果子类没有定义__init__构造方法
          #会自动调用父类的。
        def __init__(self,name,gender,color):    #子类的构造函数的参数的数量可任意,不必与基类的参数数量保持一致
            Person.__init__(self,name,gender)    #子类中调用了第一个基类的构造方法
            Bird.__init__(self,color)         #子类中调用了第二个基类的构造方法

        def get_gender(self):
            return self.gender

    cp = ChinaBirdPerson("吴老师","男","红色")

    print(cp.color)

    运行结果:

    E:>python a.py

    创建了一个新的人          #初始化基类1

    Bird is birthed              #初始化基类2

    red                       #可以打印基类2的变量

     
    java里面是没有多继承的,但是有多个接口
    -------------------------------------------------------------------------------------------------------------
     class Person:
        count = 0 #类变量
        nation = "中国"

        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1
            print("创建了一个新的人")

        

    class Bird:

        def __init__(self,color):
            print("a bird is birthed!")
            self.color = color

        def fly(self):
            print("I can fly in the sky!")

        def get_name(self):#实例方法,必须要实例化
            return "bird has no name"

    class ChinaBirdPerson(Person,Bird):
          #如果子类没有定义__init__构造方法
          #会自动调用父类的。
        def __init__(self,name,gender,color):
            Person.__init__(self,name,gender)
            Bird.__init__(self,color)

        def get_gender(self):
            return self.gender

    cp = ChinaBirdPerson("吴老师","男","红色")
    print(cp.get_name())
     
    运行结果:

    E: est_test_test>py -3 b.py
    创建了一个新的人
    a bird is birthed!
    bird has no name

    -------------------------------------------------
     class ChinaBirdPerson(Person,Bird):
          #如果子类没有定义__init__构造方法
          #会自动调用父类的。
        def __init__(self,name,gender):
            Person.__init__(self,name,gender)
            #Bird.__init__(self,color)

        def get_gender(self):
            return self.gender

    cp = ChinaBirdPerson("吴老师","男")
    print(cp.color)
     
    运行结果:

    E: est_test_test>py -3 b.py
    创建了一个新的人
    Traceback (most recent call last):
    File "b.py", line 36, in <module>
    print(cp.color)
    AttributeError: 'ChinaBirdPerson' object has no attribute 'color'

    3) 子类的两个基类都有相同名字的方法时,调用该方法时,执行括号左面基类的方法,会进行深度优先的规则查找。

    class Person:

        count = 0

        nation = "中国"

        def __init__(self,name,gender):

            self.name = name

            self.gender = gender

            Person.count+=1

            print("创建了一个新的人")

        def get_name(self):             #基类1有get_name()方法

            return self.name

    class Bird:

        def __init__(self,color):

            print("Bird is birthed")

            self.color = color

        def fly(self):

            print("I can fly in the sky")

        def get_name(self):             #基类2有get_name()方法

            print("Bird has no name")

    class chinaBirdPerson(Person,Bird):

        def __init__(self,name,gender,color):

            Person.__init__(self,name,gender)

            Bird.__init__(self,color)

        def get_gender(self):

            return self.gender

    cp = chinaBirdPerson("laoshi","男","红")

    print(cp.get_name())                  

    运行结果:

    E:>python a.py

    创建了一个新的人      #初始化基类1

    Bird is birthed          #初始化基类2

    laoshi                 #调用基类1的get_name()方法

    4) 多继承时的深度优先

    class P:

        def get_name(self):         #爷爷类P有get_name()方法

            print("P name")

    class Person(P):                #父类Person继承了P

        count = 0

        nation = "中国"

        def __init__(self,name,gender):

            self.name = name

            self.gender = gender

            Person.count+=1

            print("创建了一个新的人")

    class Bird:

        def __init__(self,color):

            print("Bird is birthed")

            self.color = color

        def fly(self):

            print("I can fly in the sky")

        def get_name(self):          #第二父类中有get_name()方法

            print("Bird has no name")

    class chinaBirdPerson(Person,Bird):

        def __init__(self,name,gender,color):

            Person.__init__(self,name,gender)

            Bird.__init__(self,color)

        def get_gender(self):

            return self.gender

    cp = chinaBirdPerson("laoshi","男","红")

    print(cp.get_name())

    运行结果;

    E:>python a.py

    创建了一个新的人       #基类1初始化

    Bird is birthed           #基类2初始化

    P name                #深度优先,调用P的get_name()方法

    None

    多继承的时候同名方法,会进行深度优先的查找。
    py3都是新式类,深度优先,没有经典类
     
    import inspect
    print(inspect.getmro(chinaBirdPerson))    #可以用 inspect.getmro 来获取类的 MRO(方法解析顺序)
     MRO方法解析表确实P在前面
     

    当爷爷类有同名方法,并且第二个父类有同名方法时,子类调用方法时,按照深度优先的原则,而非广度优先的原则

     
    从父类、爷爷类去查找方法,叫做深度优先
    从多继承的同级类去查找方法,叫做广度优先
     
      p  -->get_name(爷爷类)
           Person(父类)                Bird-->get_name(父类)
              ChinaBirdPerson(孙类)

    cp.get_name() 
     
     
     
     class P:   class P():   class P(object):三种类的定义方法等价
     
     
  • 相关阅读:
    Avizo
    NEWS
    HOWTO
    InstallShield 2012 Spring优惠升级到最新版本(2015.4.30之前)
    Windows系统补丁KB2962872导致InstallShield无法启动(解决方案已更新)
    HOWTO: InstallScript MSI工程取Log
    安装软件列表
    阿里云推荐码 hut29f
    ios 缺少合规证明
    ios开发错误之: Undefined symbols for architecture x86_64
  • 原文地址:https://www.cnblogs.com/suitcases/p/10561955.html
Copyright © 2020-2023  润新知