博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
类的析构、继承
阅读量:6271 次
发布时间:2019-06-22

本文共 8913 字,大约阅读时间需要 29 分钟。

析构方法

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

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这个类    passb =  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):    passclass 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('\t',k,v)    def __del__(self):        print('%s退学了..'%self.name)        SchoolMember.member -= 1class 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 += amountt1 = 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 s2print(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 Lilei3Lilei退学了..2Lily退学了..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('\t',k,v)    def __del__(self):        print('%s退学了..'%self.name)        SchoolMember.member -= 1class 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 += amountt1 = 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  SZ1jim退学了..

 

 

新式类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 M1jim退学了..

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

 新式类和经典类的区别

1.语法

class Person(object): #新式类   superclass 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):    passclass C(A):    def __init__(self):        self.n = 'C'class D(B,C):    passd = 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):    passd = D()print(d.n) #B

 同样去掉B的构造函数

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

 去掉C的构造函数

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

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

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

 

转载于:https://www.cnblogs.com/qing-chen/p/7425816.html

你可能感兴趣的文章
EPP(Eclipse PHP)语法高亮仿EditPlus配置
查看>>
OA账号架构权限的问题
查看>>
030——VUE中鼠标语义修饰符
查看>>
python编辑csv
查看>>
sql游标的使用与exec的两种用法
查看>>
数据结构
查看>>
78/90 Subsets --back tracking
查看>>
非托管资源的释放
查看>>
开篇寄语
查看>>
Dijkstra算法的C++实现
查看>>
phpstorm psr2样式.xml
查看>>
js 无限级分类
查看>>
umask值与Linux中文件和目录权限的关系
查看>>
python自动化开发-8
查看>>
bzoj 2127: happiness
查看>>
Python 3.5 之路 day1
查看>>
selenium使用chrome抓取自动消失弹框的方法
查看>>
实现strStr()---简单
查看>>
只有PD号的调起
查看>>
返回一个整数数组中最大子数组的和
查看>>