zoukankan      html  css  js  c++  java
  • 面向对象的程序设计

      面向过程的程序设计经常用于操作系统的内核,git等,一成不变的流水线式解决一个问题,极大程度降低程序复杂性。

      面向对象的程序设计解决了程序的扩展性(类可产生各种各样的对象,对于新增技能或修改技能可使用方法直接调用),但是可控性差,因为面向对象程序一旦开始就是由对象之间交互来解决问题。

      OOD面向对象的程序设计

      先找程序中所有的对象,将对象归纳出类(并归纳出共同属性与方法和不同的属性)。

      OOP面向对象编程

      编程时先定义出类,再根据类实例化出对象。

      python3统一了类与类型的概念,python3中的类型就是类。

      编程方式:

      面向过程: 根据代码在脚本的堆叠顺序,从上到下依次执行,

      函数式编程:将相同功能的代码封装到函数中,直接调用即可,减少代码重复性,

      面向对象:对函数进行分类和封装,将同类的函数放到一个类中,使调用更简单。

    类的简介

      类和对象
      类就是一个模板,模板里可以包含多个方法(即函数),方法里实现一些功能,对象则是根据模板创建的实例,通过实例对象可以执行类中的函数。

    #创建类  class+类名
    class foo:               #class是关键字,表示类,foo是类的名字
        def f1(self):               #类的方法1
            pass
        def f2(self):               #类的方法2
            pass
    
    #创建对象  对象 = 类名()
    bar = foo()   #创建一个bar对象 ,此对象中有类中所有的方法 ,创建对象,类名称后加括号即可 
    
    #调用对象的方法  对象.方法名()
    bar.f1()
    bar.f2()
    创建类和变量的方式

      类名+()就等于在执行Person.__init__(),执行完__init__()就会返回一个对象。这个对象类似一个字典,存着属于这个人本身的一些属性和方法。

      这里提一嘴特殊的类属性。

      类名.__name__# 类的名字(字符串)

      类名.__doc__# 类的文档字符串

      类名.__base__# 类的第一个父类

      类名.__bases__# 类所有父类构成的元组

      类名.__dict__# 查看类和对象的名称空间

      类名.__module__# 类定义所在的模块

      类名.__class__# 实例对应的类(仅新式类中)

      python中使用class定义类,在python3中只有新式类(默认继承object),而python2中有新式类(手写继承object)与经典类的区别,可使用__basic__查看继承关系。

      python2的经典类:

      类的一般操作形式:

    class Teacher:                 #定义类
        x=1  #调用属性时不论对象还是类指向的都是同一块内存地址,属性又称静态字段
        def __init__(self,name,sex,age,money):#init不能有返回值,里面放的是独有特征,共有特征使用单独函数定义
            self.name=name                    #普通字段
            self.sex=sex
            self.age=age
            self.money=money
        def search(self):#teacher调用函数或者实例化对象的绑定方法调用的不是同一块内存地址,普通方法
            print("scord")
        def study(self):
            print("study")
    print(Teacher.x)   #1
    t=Teacher('jeff','male','110',10)#实例化出来的对象
    print(t.name)    #jeff
    print(t.age)    #110
    t.study()       #study
    Teacher.y=5
    print(Teacher.y)#5
    class 类名:
        类属性 = None
        def __init__(self,参数1,参数2):
            self.对象的属性1 = 参数1
            self.对象的属性2 = 参数2
    
        def 方法名(self):pass
    
        def 方法名2(self):pass
    
    对象名 = 类名(1,2)  #对象就是实例,代表一个具体的东西
                      #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法
                      #括号里传参数,参数不需要传self,其他与init中的形参一一对应
                      #结果返回一个对象
    对象名.对象的属性1   #查看对象的属性,直接用 对象名.属性名 即可
    对象名.方法名()     #调用类中的方法,直接用 对象名.方法名() 即可
    #对象增加属性
    对象.新的属性名 = 1000
    通用的class定义方法

      类是整个单独的名称空间,定义类也就是单独定义了他的名称空间(变量,函数和类名字)用来存储类中定义的所有名字,这些名字称为类的属性,静态属性就是直接在类中定义的变量,动态属性就是定义在类中的方法。可以使用__dict__查看类和对象的名称空间。实例化对象会先从自己的dict查找变量,找不到就去类(父类)的dict找,没有则会报错。

      类可以进行实例化,可以进行属性引用。对象只能属性引用。对象本身只能引用属性(变量name,sex,age。。。)。

    t.name2='tom'#
    del t.name2#
    t.name='jerry'#
    print(t.name)#

      实例化对象之间的交互:

    class Riven:
        camp='Noxus'  #所有玩家的英雄(锐雯)的阵营都是Noxus;
        def __init__(self,nickname,aggressivity=54,life_value=414): #英雄的初始攻击力54;
            self.nickname=nickname  #为自己的锐雯起个别名;
            self.aggressivity=aggressivity #英雄都有自己的攻击力;
            self.life_value=life_value #英雄都有自己的生命值;
        def attack(self,enemy):   #普通攻击技能,enemy是敌人;
            enemy.life_value-=self.aggressivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值。
    
    class Garen:
        camp='Noxus'  #所有玩家的英雄(锐雯)的阵营都是Noxus;
        def __init__(self,nickname,aggressivity=54,life_value=414): #英雄的初始攻击力54;
            self.nickname=nickname  #为自己的锐雯起个别名;
            self.aggressivity=aggressivity #英雄都有自己的攻击力;
            self.life_value=life_value #英雄都有自己的生命值;
        def attack(self,enemy):   #普通攻击技能,enemy是敌人;
            enemy.life_value-=self.aggressivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值。
    
    
    #对象之间的交互
     r1=Riven('芮雯雯')
     g1=Garen('草丛轮')
     print(r1.life_value)
     g1.attack(r1)
     print(r1.life_value)
    德玛西亚大战瑞文

      私有属性

      特点:

      类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。

      这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。

      在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。

      注意:

      这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N。

    class people:
        __name = 'jeff'
        __age = 12
        def set(self):
            print(self.__name)
            print(self.__age)
    p = people()
    #print(p.__name,p.__age)   #AttributeError: 'people' object has no attribute '__name'
    p.set()
    运行结果;
    jeff
    12

      封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码;而外部使用用者只知道一个接口(函数),只要接口(函数)名、参数不变,使用者的代码永远无需改变。

    #类的设计者,轻松的扩展了功能,而类的使用者完全不需要改变自己的代码
    class Room:
        def __init__(self,name,owner,width,length,high):
            self.name=name
            self.owner=owner
            self.__width=width
            self.__length=length
            self.__high=high
        def tell_area(self): #对外提供的接口,隐藏内部实现,此时我们想求的是体积,内部逻辑变了,只需求修该下列一行就可以很简答的实现,而且外部调用感知不到,仍然使用该方法,但是功能已经变了
            return self.__width * self.__length * self.__high
    
    
    #对于仍然在使用tell_area接口的人来说,根本无需改动自己的代码,就可以用上新功能
     r1.tell_area()#对于用户只要知道这个接口的功能就可以了
    扩展性

      property属性

      把绑定方法装饰的像一个属性一样调用,被property装饰的属性会优先于对象的属性被使用。

    class People:
        def __init__(self,name,weight,height):
            self.name=name
            self.weight=weight
            self.height=height
        @property
        def bmi(self):
            return self.weight / (self.height**2)
    
    p1=People('egon',75,1.85)
    print(p1.bmi)
    property属性
    import math
    class Circle:
        def __init__(self,radius): #圆的半径radius
            self.radius=radius
    
        @property
        def area(self):
            return math.pi * self.radius**2 #计算面积
    
        @property
        def perimeter(self):
            return 2*math.pi*self.radius #计算周长
    
    c=Circle(10)
    print(c.radius)
    print(c.area) #可以像访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
    print(c.perimeter) #同上
    '''
    输出结果:
    314.1592653589793
    62.83185307179586
    '''
    #注意:此时的特性area和perimeter不能被赋值
    c.area=3 #为特性area赋值
    '''
    抛出异常:
    AttributeError: can't set attribute
    '''
    但是不能赋值

      将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则。

      对于obj.name我们想要在实际中会有需求能改他的值,实例.name='jeff'就是改self.__name。

      这就需要用到@name.setter,删除特性的方法@name.deleter。

    class People:
        def __init__(self,name,SEX):
            self.name=name
            # self.__sex=SEX
            self.sex=SEX #self.sex='male'   p1.sex='male'
        @property
        def sex(self):
            return self.__sex #p1.__sex
    
        @sex.setter
        def sex(self,value):
            # print(self,value)
            if not isinstance(value,str):
                raise TypeError('性别必须是字符串类型')
            self.__sex=value  #p1.__sex='male'
        @sex.deleter
        def sex(self):
            del self.__sex #del p1.__sex
    
    p1=People('cobila','male')
    p1.sex='female'
    print(p1.sex)
    特性方法的修改和删除

      类方法

    class people:
        country = 'china'
        # 类方法,用classmethod来进行修饰
        @classmethod
        def getCountry(cls):  #类方法自动将类作为cls传递进函数内
            return cls.country
        @classmethod
        def setCountry(cls, country):
            cls.country = country
    p = people()
    print(p.getCountry())  # 可以用过实例对象引用
    print(people.getCountry())  # 可以通过类对象引用
    p.setCountry('japan')
    print(p.getCountry())
    运行结果:
    china
    china
    japan

      静态方法

    class people:
        country = 'china'
        @staticmethod
        # 静态方法使用装饰器方式绑定,并且作用和普通函数一样并不会自动传递self
        def getCountry():
            return people.country
    print(people.getCountry())
    运行结果:
    china

      普通方法 默认有一个self对象传进来,并且只能被对象调用——绑定到对象

      类方法 默认有一个cls传进来表示本类,并且可以被类和对象(不推荐)调用——绑定到类

      静态方法 没有默认参数,并且可以被类和对象(不推荐)调用——非绑定

    面向对象三大特性

      封装

      封装顾名思义就是将东西装起来然后留出接口供用户使用,不需要知道内部发生了什么,只需要知道接口如何调用即可。在此之前所说的__init__定义的普通字段的赋值,并提供普通方法作为调用接口就是python中的封装结构。除此之外,私有属性也是封装的一种方法之一。

      好处:将变化隔离; 

      便于使用;

      提高复用性; 

      提高安全性;

      封装原则:

      将不需要对外提供的内容都隐藏起来;

       把属性都隐藏,提供公共方法对其访问。

      多重封装:

    #创建类
    class SQL:
        def __init__(self,name,passwd):
            self.name = name
            self.passwd = passwd
        def create(self,sql):
            print(sql)
    
    class test:
        def __init__(self,name,obj):
            self.name = name
            self.obj = obj
    
        def add(self,arg):
            print(arg)
    
    class test2:
        def __init__(self,obj):
            self.obj = obj
        def iner(slef,arg):
                print(arg)
    
    #创建对象
    c1 = SQL('fuzj','12313')
    c2 = test('aaa',c1)   #把c1对象封装到c2对象里,c2对象会有c1对象的所有方法
    c3 = test2(c2)          #把c2对象封装到c3对象中,c3对象会有c2对象的所有方法,同时也就有了c1对象的所有方法
    
    #调用
    c1.create("c1调用自身create方法")
    c2.obj.create('c2调用c1的create方法')
    c3.obj.add('c3调用c2的add方法')
    c3.obj.obj.create('c3调用c1的create方法')
    
    结果:
    c1调用自身create方法
    c2调用c1的create方法
    c3调用c2的add方法
    c3调用c1的create方法
    多重封装

      继承

      对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

    class ParentClass1: #定义父类
        pass
    
    class ParentClass2: #定义父类
        pass
    
    class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
        pass
    
    class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
        pass
    继承

      一个类可以继承多个父类(基类,超类),这点与其他语言略有不同,当类是经典类时,多继承情况下,会按照深度优先方式查找;当类是新式类时,多继承情况下,会按照广度优先方式查找。

    class D:
        def bar(self):
            print('D.bar')
    class C(D):
        def bar(self):
            print('C.bar')
    class B(D):
        def bar(self):
            print('B.bar')
    class A(B, C):
        def bar(self):
            print('A.bar')
    a = A()
    # 经典类执行bar方法时
    # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
    # 所以,查找顺序:A --> B --> D --> C
    # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
    a.bar()
    #新式类执行bar方法时的查找顺序为A --> B --> C --> D
    class Hero:#这个英雄类包含了所有英雄都有的属性和方法
        def __init__(self, nickname,
                     aggressivity,
                     life_value):
            self.nickname = nickname
            self.aggressivity = aggressivity
            self.life_value = life_value
    
        def attack(self, enemy):
            enemy.life_value -= self.aggressivity
    
    class Garen(Hero):#盖伦继承了英雄类
        camp='Demacia'
        def attack(self, enemy):
            pass
        def fire(self):#盖伦独有的喷火技能
            print('%s is firing' %self.nickname)
    class Riven(Hero):
        camp='Noxus'
    g1=Garen('garen',18,200)
    r1=Riven('rivren',18,200)
    # print(g1.camp)
    # print(r1.camp)
    # g1.fire()
    g1.attack(g1)
    瑞文大战德玛之继承
    class Animal:      #父类  
        def __init__(self,name,life_value,aggr):
            self.name = name
            self.life_value = life_value
            self.aggr = aggr  #攻击力
        def eat(self):
            self.life_value += 10
    
    class Person(Animal):  #子类 
        def __init__(self,money,name,life_value,aggr):
            super().__init__(name,life_value,aggr)#super调用父类的构造方法
            self.money = money   #派生属性
    
        def attack(self,enemy):    #人的派生方法
            enemy.life_value -= self.aggr
    
    class Dog(Animal): #派生子类
        def __init__(self,breed,name,life_value,aggr):
            #Animal.__init__(self,name,life_value,aggr)   #让子类执行父类的方法,就是父类名.方法名(参数),连self也得传就是super()
            super().__init__(name,life_value,aggr)  #super关键字——新式类
            #super(Dog,self).__init__(name,life_value,aggr)  #super关键字——新式类
            self.breed = breed
        def bite(self,person):   #狗的派生方法
            person.life_value -= self.aggr
    
        def eat(self):       # 父类方法的重写
            super().eat()
            print('dog is eating~~~ ')
    
    ha2 = Dog('牛头梗','旺财',20000,100)
    print(ha2.life_value)
    ha2.eat()
    print(ha2.life_value)
    # super(Dog,ha2).eat()  #调用父类的
    print(ha2.life_value)
    人狗大战之派生
    class Hero:
        def __init__(self, nickname, aggressivity, life_value):
            self.nickname = nickname
            self.aggressivity = aggressivity
            self.life_value = life_value
        def attack(self, enemy):
            print('Hero attack')
            enemy.life_value -= self.aggressivity
    # print(Hero.__init__)
    # print(Hero.attack)
    class Garen(Hero):
        camp = 'Demacia'
        def __init__(self, nickname, aggressivity, life_value, script):
            Hero.__init__(self,nickname,aggressivity,life_value)
            # self.nickname = nickname
            # self.aggressivity = aggressivity
            # self.life_value = life_value
            self.script = script
        def attack(self, enemy):  # self=g1,enemy=r1
            # self.attack(enemy) #g1.attack()
            Hero.attack(self, enemy)
            print('from garen attack')
        def fire(self):
            print('%s is firing' % self.nickname)
    # g1=Garen('garen',18,200) #Garen.__init__(g1,'garen',18,200)
    g1=Garen('garen',18,200,'人在塔在') #Garen.__init__(g1,'garen',18,200)
    print(g1.script)
    继承更加精简了代码

      多态

      多态即多种形态,在运行时确定其状态,在编译阶段无法确定其类型,这就是多态。Python中的多态和Java以及C++中的多态有点不同,Python中的变量是弱类型的,在定义时不用指明其类型,它会根据需要在运行时确定变量的类型(个人觉得这也是多态的一种体现),并且Python本身是一种解释性语言,不进行预编译,因此它就只在运行时确定其状态,故也有人说Python是一种多态语言。

      组合

      与继承不同,组合不是什么是什么的关系,而是一种什么有什么的关系,比如学生有课程,他们是一种并行的关系而不是可以继承的关系。

    class Student:
        def __init__(self,ID,name,sex):
            self.id=ID
            self.name=name
            self.sex=sex
            self.course_list=[]
    class Course:
        def __init__(self,name,price,period):
            self.name=name
            self.price=price
            self.period=period
    
    s1=Student('123123123123','cobila','female')
    
    python_obj=Course('python',1,'7m')
    linux_obj=Course('linux',1,'2m')
    
    s1.course_list.append(python_obj)
    s1.course_list.append(linux_obj)
    print(s1.course_list[0].name)
    print(s1.course_list[0].price)
    运行结果:
    python
    1

      关于组合的问题看到一个哥们在博客里的人狗大战的代码,与德玛西亚大战瑞文一样,可以有一个装备类,装备有技能,也有属性,可以通过购买装备组合,也就是人与狗的实例化对象都可以拥有装备,装备加属性加技能再进行交互。

    class Person:  # 定义一个人类
        '''
            这是一个游戏里人物的数据类型
        '''
        role = 'person'  # 人的角色属性都是人
        def __init__(self, name, aggressivity, life_value):
            self.name = name  # 每一个角色都有自己的昵称;
            self.aggressivity = aggressivity  # 每一个角色都有自己的攻击力;
            self.life_value = life_value  # 每一个角色都有自己的生命值;
        def attack(self,dog):
            # 人可以攻击狗,这里的狗也是一个对象。
            dog.life_value -= self.aggressivity
            print("{0}打了{1}一下,{1}剩余血量{2}".format(self.name, dog.name, dog.life_value))
    
    class Dog:  # 定义一个狗类
        '''
            这是一个游戏里狗的数据类型
        '''
        role = 'dog'  # 狗的角色属性都是狗
        def __init__(self, name, breed, aggressivity, life_value):
            self.name = name  # 每一只狗都有自己的昵称;
            self.breed = breed  # 每一只狗都有自己的品种;
            self.aggressivity = aggressivity  # 每一只狗都有自己的攻击力;
            self.life_value = life_value  # 每一只狗都有自己的生命值;
        def bite(self,people):
            # 狗可以咬人,这里的狗也是一个对象。
            people.life_value -= self.aggressivity
            print("{0}咬了{1}一下,{1}剩余血量{2}".format(self.name,people.name,people.life_value))
    
    class Weapon:
        '''
            这是一个游戏里武器的数据类型
        '''
        def __init__(self,name, price, aggrev, life_value):
            self.name = name    #武器名称
            self.price = price  #武器价格
            self.aggrev = aggrev    #武器伤害加成
            self.life_value = life_value    #武器血量加成
    
        def update(self, obj):  #obj就是要带这个装备的人
            obj.money -= self.price  # 用这个武器的人花钱买所以对应的钱要减少
            obj.aggressivity += self.aggrev  # 带上这个装备可以让人增加攻击
            obj.life_value += self.life_value  # 带上这个装备可以让人增加生命值
    
        def prick(self, obj):  # 这是该装备的主动技能,绞龙
            obj.life_value -= 3000  # 假设攻击力是3000
            print("{0}发动主动技:蛟龙==>{1}剩余血量{2}".format(self.name, obj.name, obj.life_value))
    
    
    a = Person("苍井井",10,1000)
    b = Dog("egon","狼狗",200,20000)
    c = Weapon("蛟龙鞭",1000,40,2000)
    a.money = 2000
    
    #判断是否买的起武器
    if a.money > c.price :
        c.update(a)
        a.weapon = c
    
    #大战开始
    while True :
        a.attack(b)
        if b.life_value <= 0 :
            print(b.name + "" + a.name + "打死了!")
            break
        a.weapon.prick(b)
        if b.life_value <= 0 :
            print(b.name + "" + a.name + "绞死了!")
            break
        b.bite(a)
        if a.life_value <= 0 :
            print(a.name+""+b.name+"咬死了!")
            break
    人狗大战实例

      接口归一化设计

      父类中定义不操作,子类进行定义的衍生(子类都有相同功能,并且功能操作可能不一样)。如果子类没有定义或者也pass了,那这个方法就没有实际的意义了,为了防止这种现象的出现要采取一些措施。

    class Interface:#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。
        def read(self): #定接口函数read
            pass
    
        def write(self): #定义接口函数write
            pass
    
    
    class Txt(Interface): #文本,具体实现read和write
        def read(self):
            print('文本数据的读取方法')
    
        def write(self):
            print('文本数据的读取方法')
    
    class Sata(Interface): #磁盘,具体实现read和write
        def read(self):
            print('硬盘数据的读取方法')
    
        def write(self):
            print('硬盘数据的读取方法')
    
    class Process(Interface):
        def read(self):
            print('进程数据的读取方法')
    
        def write(self):
            print('进程数据的读取方法')
    
    
    
    t1=Txt()
    s1=Sata()
    p1=Process()
    
    
    
    t1.read()
    t1.write()
    
    s1.read()
    s1.write()
    
    p1.read()
    p1.write()
    可能需要的场景
    class Animal:
        def run(self):
            raise AttributeError('子类必须实现这个方法')
        def speak(self):
            raise AttributeError('子类必须实现这个方法')
    class People(Animal):
        def run(self):
            print('人正在走')
    
        # def speak(self):
        #     print('说话')
    
    class Pig(Animal):
        def run(self):
            print('pig is walking')
        def speak(self):
            print('哼哼哼')
    
    peo1=People()
    # peo1.run()
    peo1.speak()#异常咯
    low主动抛异常

      这使得虽然大家的操作都不一样,但是调用的时候方法都是一样的,这就是归一化设计。

      这里存在一个问题,我们需要进行拓展,如果说,我们的子类没有进行父类的某一项普通方法的定义,根据广度优先的查找顺序,会在父类中找到此方法,但是此方法没有任何定义,自然这个操作毫无意义,所以我们可以在父类进行raise主动将异常抛出,或者使用abc模块自动抛出异常。

    import abc
    #抽象类:本质还是类,与普通类额外的特点的是:加了装饰器的函数,子类必须实现他们
    class Animal(metaclass=abc.ABCMeta):
        tag='123123123123123'
        @abc.abstractmethod
        def run(self):
            pass
        @abc.abstractmethod
        def speak(self):
            pass
    class People(Animal):
        # def run(self):  #子类没有定义父类有的方法,但是没有搜寻父类的方法直接报错
        #     pass
        def speak(self):
            pass
    
    peo1=People()
    print(peo1.tag)
    运行结果:
    TypeError: Can't instantiate abstract class People with abstract methods run

       注意:抽象类不能被实例化

    super()函数的用法

      super在python2中的用法:

      1:super(自己的类,self).父类的函数名字

      2:super只能用于新式类

    class People(object):
        def __init__(self,name,sex,age):
            self.name=name
            self.age=age
            self.sex=sex
        def walk(self):
            print('%s is walking' %self.name)
    class Chinese(People):
        country='China'
        def __init__(self,name,sex,age,language='Chinese'):
            # self.name=name
            # self.sex=sex
            # self.age=age
            # People.__init__(self,name,sex,age)
            super(Chinese,self).__init__(name,sex,age)
            self.language=language
    c=Chinese('egon','male',18)
    print c.name,c.age,c.sex,c.language
    py2super
    class People:
        def __init__(self,name,sex,age):
            self.name=name
            self.age=age
            self.sex=sex
        def walk(self):
            print('%s is walking' %self.name)
    class Chinese(People):
        country='China'
        def __init__(self,name,sex,age,language='Chinese'):
            # self.name=name
            # self.sex=sex
            # self.age=age
            # People.__init__(self,name,sex,age)
            super().__init__(name,sex,age)
            self.language=language
        def walk(self,x):
            super().walk()
            print('子类的x',x)
    c=Chinese('egon','male',18)
    # print(c.name,c.age,c.sex,c.language)
    c.walk(123)
    py3super

      __str__

      _str__定义在类内部,必须返回一个字符串类型,打印由这个类产生的对象时,会触发执行.

    class People:
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def __str__(self):
            return '<name:%s,age:%s>' %(self.name,self.age)
    
    p1=People('egon',18)
    print(p1)
    str(p1) #此时print触发----->p1.__str__()
    #所以打印结果为<name:egon,age:18>
    __str__
  • 相关阅读:
    Android Media Playback 中的MediaPlayer的用法及注意事项(二)
    Android Media Playback 中的MediaPlayer的用法及注意事项(一)
    34. Search for a Range
    33. Search in Rotated Sorted Array
    32. Longest Valid Parentheses
    31. Next Permutation下一个排列
    30. Substring with Concatenation of All Words找出串联所有词的子串
    29. Divide Two Integers
    28. Implement strStr()子串匹配
    27. Remove Element
  • 原文地址:https://www.cnblogs.com/Jeffding/p/7376515.html
Copyright © 2011-2022 走看看