zoukankan      html  css  js  c++  java
  • 类的析构、继承

    析构方法

    实例被销毁的时候自动调用。网络编程用的多。

    class Dog(object):
        def __init__(self,name):
            self.name = name
            self.__weight = 100
    
        def sayhi(self):
            print('my wigth is ', self.__weight,)
    
        def __del__(self):
            print('del.........')
    d = Dog('二哈')
    del  d   #del.........
    print('-------------------') #-------------------
    

     del d 并没有真正的把这个对象删除,只是把对象的引用删除了。同时垃圾回收机制把一个没有引用的空间给删除了,在删除之前执行的__del()__.

    继承

    使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

    通过继承创建的类称作子类 或者派生类。

    被继承的类称作基类、父类或者超类。

    某些oop语言中,一个子类可以继承多个基类。但是,一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

    继承的实现有两种:实现继承和接口继承

    1、实现继承是指基类的属性和方法而无需额外编码的能力

    2、接口继承是指使用属性和方法的名称、但是子类必须提供实现的能力。也就是子类重构父类的方法。

    使用继承时,需考虑两个类之间的关系是属于关系。

    抽象类仅定义将由子类创建的一般属性和方法。

    OO开发范式大致为:划分对象-》抽象类-》将类组织成为层次结构(继承和合成)->用类与实例进行设计和实现几个阶段。

    简单的继承:

    class Person(object):
        def talk(self):
            print('person is talking...')
    
    class BlackPerson(Person):    #继承Person这个类
        pass
    
    b =  BlackPerson()               
    b.talk()                              #person is talking...
    

     重新父类:

    class Person(object):
        def talk(self):
            print('person is talking...')
    
    class BlackPerson(Person):
        def talk(self):
            print('balabala...')
    
    b =  BlackPerson()
    b.talk()                       #balabala...
    

     重写了就调用自己的,没有重新就调用父类的。

    如果父类有构造方法,子类继承父类之后也会继承父类的构造方法,如果子类重写了就不用父类的构造方法。

    class Person(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def talk(self):
            print('person is talking...')
    
    class BlackPerson(Person):
        def talk(self):
            print('balabala...')
    
    b =  BlackPerson()      #TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
    b.talk()
    

     继承了父类的构造方法,实例化的时候也必须要传递参数。

    class Person(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def talk(self):
            print('person is talking...')
    
    class BlackPerson(Person):
        def talk(self):
            print('balabala...')
    
    b =  BlackPerson('jim',20)
    b.talk()                           #balabala...
    

     重写构造函数

    class Person(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def talk(self):
            print('person is talking...')
    
    class BlackPerson(Person):
        def __init__(self,name):
            self.name = name
        def talk(self):
            print('balabala...')
    
    b =  BlackPerson('jim')
    b.talk()                            #balabala...
    

    子类重写父类构造,那么就会调用自己的构造,但是我又需要父类的构造函数,有些功能相同的代码不想重写。这个时候可以使用先继承在重构。

     先继承在重构

    class Person(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def talk(self):
            print('person is talking...')
    class WhitePerson(Person):
        pass
    
    class BlackPerson(Person):
    
        def __init__(self,name,age,strength):  #先继承,在重构   子类重构父类方法,实例化的时候参数都传到子类,self就是b
            Person.__init__(self,name,age)     #这里调用父类的构造方法  这里的self,name,age 都来自与子类
            print(self.name,self.age)           # jim 20
    
        def talk(self):
            print('balabala...')
    
    b =  BlackPerson('jim','20','500')
    b.talk()
    

    子类的实例传到父类,让父类赋值。

     

    子类调用父类的方法

    class Person(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def talk(self):
            print('person is talking...')
     
    class BlackPerson(Person):
    
        def __init__(self,name,age,strength):  #先继承,在重构   子类重构父类方法,实例化的时候参数都传到子类,self就是b
            Person.__init__(self,name,age)     #这里调用父类的构造方法  这里的self,name,age 都来自与子类
    
        def talk(self):
            Person.talk(self)   
            print('balabala...') 
    
    b =  BlackPerson('jim','20','500')
    b.talk() #person is talking... #balabala...
    

     小练习:

    算下学校老师和学生的注册人数,并打印用户信息。

    class SchoolMember(object):
        '''学校成员基类'''
        member = 0                          # 计数器
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
            self.enroll()
    
        def enroll(self):
            '''注册'''
            print('just enerolled a new school member [%s]'% self.name)
            SchoolMember.member += 1                  #实例本身有就调用本身的,没有就调用全局的
        def tell(self):
            print('----%s info-----'% self.name)
            for k,v in self.__dict__.items():
                print('	',k,v)
        def __del__(self):
            print('%s退学了..'%self.name)
            SchoolMember.member -= 1
    
    class Teacher(SchoolMember):
        '''讲师类'''
    
        def __init__(self,name,age,sex,salary,course):
            SchoolMember.__init__(self,name,age,sex)
            self.salary = salary
            self.course = course
    
        def teaching(self):
            print('Teacher [%s] is teaching [%s]'%(self.naem,self.course))
    
    
    class Student(SchoolMember):
        '''学生类'''
    
        def __init__(self,name,age,sex,course,tuition):
            SchoolMember.__init__(self,name,age,sex)
            self.course = course
            self.tuition = tuition
            self.amount = 0
    
        def pay_tuition(self,amount):
            print('student [%s] has just paied [%s]'%(self.name,amount))
            self.amount += amount
    
    t1 = Teacher('jim',20,'M',5000,'python')
    s1 = Student('Lily',22,'W','python',300000)
    s2 = Student('Lilei',23,'M','python',200000)
    t1.tell()
    s1.tell()
    s2.tell()
    print(SchoolMember.member)
    del s2
    print(SchoolMember.member)
    
    just enerolled a new school member [jim]
    just enerolled a new school member [Lily]
    just enerolled a new school member [Lilei]
    ----jim info-----
    	 age 20
    	 course python
    	 sex M
    	 salary 5000
    	 name jim
    ----Lily info-----
    	 age 22
    	 course python
    	 sex W
    	 tuition 300000
    	 amount 0
    	 name Lily
    ----Lilei info-----
    	 age 23
    	 course python
    	 sex M
    	 tuition 200000
    	 amount 0
    	 name Lilei
    3
    Lilei退学了..
    2
    Lily退学了..
    jim退学了..
    

    多继承

    class SchoolMember(object):
        '''学校成员基类'''
        member = 0                          # 计数器
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
            self.enroll()
    
        def enroll(self):
            '''注册'''
            print('just enerolled a new school member [%s]'% self.name)
            SchoolMember.member += 1                  #实例本身有就调用本身的,没有就调用全局的
        def tell(self):
            print('----%s info-----'% self.name)
            for k,v in self.__dict__.items():
                print('	',k,v)
        def __del__(self):
            print('%s退学了..'%self.name)
            SchoolMember.member -= 1
    
    class School(object):
        def open_branch(self,addr):
            print('openning a new branch in ',addr)
    
    class Teacher(SchoolMember,School):   #多继承
        '''讲师类'''
        def __init__(self,name,age,sex,salary,course):
           # SchoolMember.__init__(self,name,age,sex)
            super(Teacher,self).__init__(name,age,sex)
            self.salary = salary
            self.course = course
    
        def teaching(self):
            print('Teacher [%s] is teaching [%s]'%(self.naem,self.course))
    
    class Student(SchoolMember):
        '''学生类'''
    
        def __init__(self,name,age,sex,course,tuition):
            SchoolMember.__init__(self,name,age,sex)
            self.course = course
            self.tuition = tuition
            self.amount = 0
    
        def pay_tuition(self,amount):
            print('student [%s] has just paied [%s]'%(self.name,amount))
            self.amount += amount
    
    t1 = Teacher('jim',20,'M',5000,'python')
    t1.open_branch('SZ')
    print(SchoolMember.member)
    

     执行结果

    just enerolled a new school member [jim]
    openning a new branch in  SZ
    1
    jim退学了..
    

    新式类VS经典类

    接着上面的例子练习:

    修改Teacher类中调用父类构造的方法。其它代码不修改

    # SchoolMember.__init__(self,name,age,sex)   #经典类的写法
      super(Teacher,self).__init__(name,age,sex) #新式类的写法
    -------------------------------------------------
    t1 = Teacher('jim',20,'M',5000,'python')           #学生的不调用
    t1.tell()
    print(SchoolMember.member)

     执行结果:

    just enerolled a new school member [jim]
    ----jim info-----
    	 course python
    	 name jim
    	 salary 5000
    	 age 20
    	 sex M
    1
    jim退学了..
    

     可以看到效果和之前的一样 .super这种写法是一种新式类的写法。

     新式类和经典类的区别

    1.语法

    class Person(object): #新式类
      super class Person: #经典类
      ParentClass.__init__

     2 多继承时的继承顺序

    看个小例子:

    四个类继承顺序如下:

    新式类写法

    class A(object):
        def __init__(self):
            self.n = 'A'
    class B(A):
        def __init__(self):
            self.n = 'B'
    
    class C(A):
        def __init__(self):
            self.n = 'C'
    
    class D(B,C):
        def __init__(self):
            self.n = 'D'
    d = D()
    print(d.n)  #D
    

     d把所有的父类方法重新了,打印肯定是它自己的

    如果D没有构造函数,那么这里会打印谁的?

    class A(object):
        def __init__(self):
            self.n = 'A'
    class B(A):
        def __init__(self):
            self.n = 'B'
    
    class C(A):
        def __init__(self):
            self.n = 'C'
    
    class D(B,C):
        pass
        '''
         def __init__(self):
            self.n = 'D'
        '''
    
    d = D()
    print(d.n)  #B
    

     继承顺序从左往右。所有先继承B

    如果B没有构造函数,所以会继承C的,如果C也没有的话就会继承A的,这种叫广度查找,会把一个层级的查找完

    class A(object):
        def __init__(self):
            self.n = 'A'
    class B(A):
        pass
    
    class C(A):
        def __init__(self):
            self.n = 'C'
    
    class D(B,C):
        pass
    
    d = D()
    print(d.n) #C
    

     经典类写法

    class A:
        def __init__(self):
            self.n = 'A'
    class B(A):
        def __init__(self):
            self.n = 'B'
    
    class C(A):
        def __init__(self):
            self.n = 'C'
    
    class D(B,C):
        pass
    
    d = D()
    print(d.n) #B
    

     同样去掉B的构造函数

    class A:
        def __init__(self):
            self.n = 'A'
    class B(A):
        pass
    
    class C(A):
        def __init__(self):
            self.n = 'C'
    
    class D(B,C):
        pass
    
    d = D()
    print(d.n)#C
    

     去掉C的构造函数

    class A:
        def __init__(self):
            self.n = 'A'
    class B(A):
        pass
    
    class C(A):
        pass
    
    class D(B,C):
        pass
    
    d = D()
    print(d.n)#A
    

     并没有什么区别,继承顺序也是一样的。

    在Python2.7下,如果B没有构造函数,会直接找A,并不会找C,r如果A没有才会找C,这种叫深度查找。

  • 相关阅读:
    day22 Python shelve模块
    day22 Python pickle模块
    day22 Python sys模块
    day22 Python os模块
    day22 Python random模块
    day22 Python 时间模块
    day21 Python 实现的深度优先搜索实现迷宫算法
    day21 Go 实现的深度优先搜索实现迷宫算法
    杂篇
    杂篇
  • 原文地址:https://www.cnblogs.com/qing-chen/p/7425816.html
Copyright © 2011-2022 走看看