类,是类,是类,就是类
类的特点:封装, 继承, 多态
类的使用与性质方法汇总:
1 class People(object): 2 n = 123 #类变量 3 def __init__(self, name, age, height): #这里的self就是实例化的变量名(p1) 4 #构造函数(在实例化时做一些类的初始化的工作) 5 self.name = name 6 self.age = age 7 self.height = height 8 9 def talk(self): 10 print("%s is talking......"%(self.name)) 11 12 def walk(self): 13 print("%s is walking......"%(self.name)) 14 15 def sleep(self): 16 print("%s is sleeping......"%(self.name)) 17 18 class Person(People): 19 def __init__(self, name, age, height, hobby): #定义子类自己的方法 20 # People.__init__(self, name, age, height) #继承的两种方式 21 super(Person, self).__init__(name, age, height) 22 self.hobby = hobby 23 24 def play(self): 25 print("%s likes to play %s." % (self.name, self.hobby)) 26 27 # def play(self): #可以在子类里面直接定义方法 28 # print("%s likes to play..."%(self.name)) 29 30 # p1 = Person('jenny', 22, 90, 'guitar') 31 # p1.name = 'jack' #可以以实例化的变量名(p1)在类的外边调用类的方法 32 # p1.play() 33 # print(p1.n, People.n) #可以通过变量名或者类的名字去调用类变量 34 # print(p1.name, People.name) #类名是不能调用实例变量,原因还是self就是p1 35 36 Person.n = 666 #不会改变p1的n,只改变原类以及p2中的n 37 p1 = Person('jenny', 22, 90, 'guitar') 38 p1.n = 2223 #p1.n只能修改自身实例化的n,对于原类以及别的实例化对象都没有影响 39 #(本质是在p1的内存里加入了n) 40 print(p1.n, Person.n) 41 42 p2 = Person('danny', 14, 100, 'football') 43 print(p2.n)
类变量的用途:共用的属性,节省开销;
class Person: cn = "中国" #所有的实例共用一份 def __init__(self, cn='china'): #这样子的创建方式会在每个实例中开辟一块内存 pass
析构函数:在实例释放,销毁的时候执行,通常用于做一些收尾工作,如关闭一些数据库链接以及打开的临时文件等;
class People(object): n = 123 def __init__(self, name, age, height): self.name = name self.age = age self.height = height def __del__(self): #析构函数 print('del this file!') def talk(self): print("%s is talking......"%(self.name)) def walk(self): print("%s is walking......"%(self.name)) def sleep(self): print("%s is sleeping......"%(self.name)) class Person(People): def __init__(self, name, age, height, hobby): super(Person, self).__init__(name, age, height) self.hobby = hobby def play(self): print("%s likes to play %s." % (self.name, self.hobby))
第一种写法: p1 = Person('jenny', 22, 90, 'guitar') p1.play() p2 = Person('danny', 14, 100, 'football') p2.play() input: jenny likes to play guitar. danny likes to play football. del this file! del this file!
第二种写法: p1 = Person('jenny', 22, 90, 'guitar') p1.play() del p1 #删除实例化变量就调用析构函数 p2 = Person('danny', 14, 100, 'football') p2.play() input: jenny likes to play guitar. del this file! danny likes to play football. del this file!
私有方法&私有属性:
class People(object): def __init__(self, name, age, height): self.name = name self.age = age self.__height = height #私有属性 # def __del__(self): #私有方法 # print('del this file!') def __talk(self): print("%s is talking......"%(self.name)) p1 = People('jenny', 22, 90) # p1.__height = 100 #在这里应该属于新建了一个变量 # print(p1.__height) #'People' object has no attribute '__height' p1.__talk() #'People' object has no attribute '__talk'
多继承:
2.7 经典类:深度优化; 新式类:广度优化;
3.x 均是广度优化
#class People: #经典类 class People(object): #新式类 def __init__(self, name, age, height): self.name = name self.age = age self.__height = height def __talk(self): print("%s is talking......"%(self.name)) def walk(self): print("%s is walking......"%(self.name)) def sleep(self): print("%s is sleeping......"%(self.name)) # class Relationship(object): #实例化时首先去父类中寻找构造方法,在调用该函数时早已经实例化变量 # def make_friends(self, obj): # print("%s is making friends with %s"%(self.name, obj.name)) class Relationship(object): #实例化时首先去父类中寻找构造方法,在调用该函数时早已经实例化变量 def __init__(self, n1, n2, n3): #测试继承类的执行顺序 print(self.name) def make_friends(self, obj): print("%s is making friends with %s"%(self.name, obj.name)) class Teacher(Relationship, People): #'Teacher' object has no attribute 'name',意味着从左到右执行 # def __init__(self, name, age, height, hobby): #存在时,在这里进行初始化 # super(Teacher, self).__init__(name, age, height) #新式类的写法 # self.hobby = hobby def play(self): print("%s likes to play %s." % (self.name, self.hobby)) p1 = Teacher('jenny', 22, 90) p2 = Teacher('danny', 14, 100) p1.make_friends(p2) #input:jenny is making friends with danny
另外一种类似多继承的形式——组合:
1 class People(object): 2 def __init__(self, name, age, height): 3 self.name = name 4 self.age = age 5 self.height = height 6 7 class Person(object): 8 def __init__(self, job, sex): 9 self.job = job 10 self.sex = sex 11 12 person_obj = Person("teacher", "F") #在这里实例化person类 13 14 class Teacher(People): 15 def __init__(self, name, age, height, Person_obj, hobby): #直接传入实例化的对象 16 People.__init__(self, name, age, height) 17 self.person = person_obj 18 self.hobby = hobby 19 20 p1 = Teacher('jenny', 22, 90, "teacher", "football") 21 22 print(p1.person.sex) #F 23 print(p1.person.job) #teacher
使用列表进一步说明继承:
class People(object): #新式类 def __init__(self, name, age, height): self.name = name self.age = age self.__height = height self.friends = [] #定义列表 class Relationship(object): #实例化时首先去父类中寻找构造方法,在调用该函数时早已经实例化变量 def make_friends(self, obj): print("%s is making friends with %s"%(self.name, obj.name)) self.friends.append(obj) #添加实例化变量名 class Teacher(People, Relationship): def teach(self): print("%s likes to teach." %(self.name)) class Student(People, Relationship): def study(self): print("%s likes to study." %(self.name)) p1 = Teacher('jenny', 22, 90) s1 = Student('danny', 14, 100) p1.make_friends(s1) print(p1.friends[0].name) #danny ,相当于将s1存入到列表中
继承的完整程序分析:
class School(object): #object是基类 def __init__(self,name,addr): self.name = name self.addr = addr self.students = [] self.staffs = [] def enroll(self, stu_obj): print("为%s办理入学手续"%(stu_obj.name)) self.students.append(stu_obj) def hire(self, staff_obj): print("%s入职"%(staff_obj.name)) self.staffs.append(staff_obj) class ShoolMate(object): def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def tell(self): pass class Teacher(ShoolMate): def __init__(self,name,age,sex,salary,course): super(Teacher,self).__init__(name,age,sex) self.salary = salary self.course = course def tell(self): print('''--------info of [%s]---------- Name:%s, Age:%s, Sex:%s, Salary:%s, Course:%s '''%(self.name,self.name,self.age,self.sex,self.salary,self.course)) def teach(self): print("%s is teaching course [%s]"%(self.name,self.course)) class Student(ShoolMate): def __init__(self, name, age, sex, id, grade): super(Student, self).__init__(name, age, sex) self.id = id self.grade = grade def tell(self): print('''--------info of [%s]---------- Name:%s, Age:%s, Sex:%s, ID:%s, Grade:%s ''' % (self.name, self.name, self.age, self.sex, self.id, self.grade)) def teach(self): print("%s is learning in [%s]" % (self.name, self.grade)) school = School('xxx', 'earth') t1 = Teacher("Jan", 34, 'F', 500000, 'math') t2 = Teacher("Lisan", 55, 'M', 30000, 'English') s1 = Student('Jenny', 12, 'F', 1001, 'grade_one') s2 = Student('Danny', 13, 'M', 1002, 'grade_two') # t1.tell() # s1.tell() school.enroll(s1) school.enroll(s2) school.hire(t1) print(school.students[0].name) #使用学校实例化变量名调用其中的student和staff print(school.staffs[0].age)
关于类的多态特性分析:
多态:一种接口,多种实现(接口重用)
python不直接支持多态,但可间接实现多态。
1 class Animal(): 2 def __init__(self, name): 3 self.name = name 4 5 def talk(self): 6 pass 7 8 @staticmethod #静态装饰器 9 def animal_talk(obj): 10 obj.talk() 11 12 class Cat(Animal): 13 def talk(self): 14 print("miao!") 15 16 class Dog(Animal): 17 def talk(self): 18 print("wang!") 19 20 21 c = Cat('mimi') 22 d = Dog('wangwang') 23 Animal.animal_talk(c) #间接实现了多态 24 Animal.animal_talk(d)
附:静态方法, 类方法, 属性方法
静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性;
class Human(object): def __init__(self, name): self.name = name @staticmethod #静态方法 def eat(self, food): print("%s is eating %s"%(self.name, food)) d = Human("xiaohuang") d.eat(d, 'baozi') #将实例化的变量传参进去
类方法:只能访问类变量, 不能访问实例变量
class Dog(object): name = 'dahuang' def __init__(self, name): self.name = name #访问不了这里 @classmethod #类变量 def eat(self, food): print("%s is eating %s"%(self.name, food)) d = Dog("xiaohuang") d.eat('baozi')
属性方法:把一个方法变成一个静态属性
class Dog(object): name = 'dahuang' def __init__(self, name): self.name = name #访问不了这里 self.__food = None @property #attribute def eat(self): print("%s is eating %s"%(self.name, self.__food)) @eat.setter def eat(self, food): print("set to food:", food) self.__food = food @eat.deleter def eat(self): del self.__food print("delete!") d = Dog("xiaohuang") d.eat #xiaohuang is eating None d.eat = 'baozi' #set to food: baozi d.eat #xiaohuang is eating baozi del d.eat #这里是删除不了的,要想删除,调用@set.deleter
浙公网安备 33010602011771号