面向对象的三大特性:继承,封装,多态
1、什么是继承?
继承是一种新建类的方式,在python中支持一个儿子继承多个爹
新建的类称为子类或者派生类
类又可以称为基类或者超类
子类会遗传父类的属性
2、为什么要用继承
减少代码的冗余
3、怎么用继承
''' class ParentClass1: pass class ParentClass2: pass class Subclass1(ParentClass1): pass class Subclass2(ParentClass1,ParentClass2): pass # print(Subclass1.__bases__) print(Subclass2.__bases__) # 在python2中有经典类与新式类之分 # 在python3中全都为新式类
寻找继承关系
class OldboyPeople: school='oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def f1(self): print('爹的f1') class OldboyTeacher(OldboyPeople): def change_score(self): print('teacher %s is changing score'%self.name) tea1=OldboyTeacher('egon',18,'male') print(tea1.__dict__) print(tea1.name) print(tea1.school) tea1.f1()
基于继承再找属性关系
class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def f1(self): print('爹的f1') class OldboyTeacher(OldboyPeople): def change_score(self): print('teacher %s is changing score' %self.name) tea1 = OldboyTeacher('egon', 18, 'male') # print(tea1.__dict__) # print(tea1.name) # print(tea1.school) # print(tea1.change_score) # print(tea1.f1) class Foo: def f1(self): print('Foo.f1') def f2(self): #self=obj print('Foo.f2') self.f1() #obj.f1() class Bar(Foo): def f1(self): print('Bar.f1') obj=Bar() # print(obj.__dict__) obj.f2() #基于对象自己的,再去找类的
派生
子类定义自己新的属性,如果与父类同名,以子类自己的为准
# #派生:子类定义自己新的属性,如果与父类同名,以子类自己的为准 # class OldboyPeople: # school = 'oldboy' # # def __init__(self, name, age, sex): # self.name = name # self.age = age # self.sex = sex # # def f1(self): # print('爹的f1') # class OldboyTeacher(OldboyPeople): # def change_score(self): # print('teacher %s is changing score' %self.name) # # def f1(self): # print('儿子的f1') # # tea1 = OldboyTeacher('egon', 18, 'male') # tea1.f1() # class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def f1(self): print('爹的f1') class OldboyTeacher(OldboyPeople): def __init__(self,name,age,sex,level,salary): self.name=name self.age=age self.sex=sex self.level=level self.salary=salary def change_score(self): print('teacher %s is changing score' %self.name) def f1(self): print('儿子的f1') tea1 = OldboyTeacher('egon', 18, 'male',9,3.1) print(tea1.name,tea1.age,tea1.sex,tea1.level,tea1.salary) #继承可以继承父类特有的属性,派生是可以定制属于自己的东西
在子类派生出的新方法中重用父类功能方法
# 在子类派生出的新方法中重用父类的功能 #方式一:指名道姓地调用(其实与继承没有什么关系的) # OldboyPeople.__init__(self,name, age, sex) # class OldboyPeople: # school = 'oldboy' # # def __init__(self, name, age, sex): # self.name = name # self.age = age # self.sex = sex # # def tell_info(self): # print(""" # ===========个人信息========== # 姓名:%s # 年龄:%s # 性别:%s # """ %(self.name,self.age,self.sex)) # # class OldboyTeacher(OldboyPeople): # # tea1,'egon', 18, 'male', 9, 3.1 # def __init__(self, name, age, sex, level, salary): # # self.name = name # # self.age = age # # self.sex = sex # OldboyPeople.__init__(self,name, age, sex) # # self.level = level # self.salary = salary # # def tell_info(self): # OldboyPeople.tell_info(self) # print(""" # 等级:%s # 薪资:%s # """ %(self.level,self.salary)) # # tea1 = OldboyTeacher('egon', 18, 'male', 9, 3.1) # # print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary) # # tea1.tell_info() #方式二:super()调用(严格依赖于继承) #super()的返回值是一个特殊的对象,该对象专门用来调用父类中的属性 #了解:在python2中,需要super(自己的类名,self) class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def tell_info(self): print(""" ===========个人信息========== 姓名:%s 年龄:%s 性别:%s """ %(self.name,self.age,self.sex)) class OldboyTeacher(OldboyPeople): # tea1,'egon', 18, 'male', 9, 3.1 def __init__(self, name, age, sex, level, salary): # OldboyPeople.__init__(self,name, age, sex) super(OldboyTeacher,self).__init__(name,age,sex) self.level = level self.salary = salary def tell_info(self): # OldboyPeople.tell_info(self) super().tell_info() print(""" 等级:%s 薪资:%s """ %(self.level,self.salary)) tea1 = OldboyTeacher('egon', 18, 'male', 9, 3.1) # print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary) tea1.tell_info()
经典类与新式类
# python2中分为经典类与新式类 python3中只有新式类 ''' 1、新式类: 继承object的类,以及该类的子类,都是新式类 在python3中,如果一个类没有指定继承的父类,默认就继承object 所以说python3中所有的类都是新式类 2、经典类(只有在python2才区分经典类与新式类): 没有继承object的类,以及该类的子类,都是经典类 ''' # print(object) class Foo(object): pass class Bar(Foo): pass # print(Foo.__bases__) #这条指令能够查看继承的父类 print(Bar.__bases__)
菱形继承(了解为主)
super()对象严格依赖mro列表
周末作业
1.类的属性和对象的属性有什么区别?
2.面向过程编程与面向对象编程的区别与应用场景?
4.什么是绑定到对象的方法,如何定义,如何调用,给谁用?有什么特性
5.如下示例,请用面向对象的形式优化一下代码
在没有学习类这个概念时,数据与功能是分离的,如下
def exc1(host,port,db,charset): conn=connect(host,port,db,charset) conn.execute(sql) return xxx def exc2(host,port,db,charset,proc_name) conn=connect(host,port,db,charset) conn.call_proc(sql) return xxx # 每次调用都需要重复传入一堆参数 exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;') exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')
6、下面这段代码的输出结果将是什么?请解释。
class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass print(Parent.x, Child1.x, Child2.x) Child1.x = 2 print(Parent.x, Child1.x, Child2.x) Parent.x = 3 print(Parent.x, Child1.x, Child2.x)
7、定义学校类,实例化输出:北京校区、上海校区两个对象
校区独有的特性有:
校区名=“xxx”
校区地址={'city':"所在市","district":"所在的区"}
多门课程=["xxx","yyy","zzz"]
多个班级名=["xxx","yyy","zzz"]
校区可以:
1、创建班级
2、查看本校区开设的所有班级名
3、创建课程
4、查看本校区开设的所有课程名
8、定义出班级类,实例化出两个班级对象
班级对象独有的特性:
班级名="xxx"
所属校区名="xxx"
多门课程名=["xxx","yyy","zzz"]
多个讲师名=["xxx","xxx","xxx"]
班级可以:
1、查看
11、定义讲师类,实例化出egon,lqz,alex,wxx四名老师对象
老师对象独有的特征:
名字="xxx"
等级="xxx"、
老师可以:
修改学生的成绩
12、用面向对象的形式编写一个老师类,老师有特征:编号、姓名、性别、年龄、等级、工资,老师类中有功能
13、按照定义老师的方式,再定义一个学生类
14、抽象老师类与学生类得到父类,用继承的方式减少代码冗余
相关答案
""" 1.类的属性和对象的属性的区别: 对象只属于自己 可以通过 对象名.属性名来调用对象的属性 类可以被该类所有的对象继承,类可以通过 类名.属性名来调用对象的属性 2.面向过程编程与面向对象编程的区别与应用场景? 面向过程: 考虑的是步骤,扩展性差 维护性差 但是化繁为简 应用场景是 对扩展性要求不高的程序 比如:脚本程序等 面向对象: 考虑的是对象,扩展性强,维护性强,但是复杂,不可预知结果 应用场景是 对扩展性要求高的程序 比如:qq 微信 游戏等 3.什么是绑定到对象的方法,、如何定义,如何调用,给谁用?有什么特性 方法: 把对象和函数进行绑定 定义: 在类中定义函数 调用: 可以用对象调用 也可以用类调用 给对象用 特性: 在对象调用类中的方法时,默认会把对象传入到方法中 用类名调用方法的话,则需要手动传入对象 """ """ 5、如下示例, 请用面向对象的形式优化以下代码# 在没有学习类这个概念时,数据与功能是分离的, 如下 def exc1(host, port, db, charset,aaa): conn = connect(host, port, db, charset,aaa) conn.execute(sql) return xxx def exc2(host, port, db, charset, proc_name) conn = connect(host, port, db, charset) conn.call_proc(sql) return xxx exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;') exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字') """ # class Mysql: # host = '127.0.0.1' # port = 3306 # db = 'db1' # charset = 'utf8' # # def exc1(self,sql): # conn = connect(self.host,self.port,self.db,self.charset) # conn.execute(sql) # return True # # def exc2(self,host, port, db, charset, proc_name): # conn = connect(host, port, db, charset) # conn.call_proc(proc_name) # return True # # obj = Mysql() # obj.exc1('select * from tb1;') # obj.exc2('存储过程的名称') # 6、下面这段代码的输出结果将是什么?请解释 # class Parent(object): # x = 1 # # class Child1(Parent): # pass # # class Child2(Parent): # pass # # # print(Parent.x, Child1.x, Child2.x) # 1 1 1 # # 先找子类 子类中没有沿着继承关系往父类找 # # Child1.x = 2 # Child1.x有了自己的x属性 优先访问自己的 # print(Parent.x, Child1.x, Child2.x) # 1 2 1 # # Parent.x = 3 # 修改父类中的属性 # print(Parent.x, Child1.x, Child2.x) # 3 2 3 # # 子类Child1已经有属于自己的属性,即 x = 2,不会在继承父类的属性 """ 7、定义学校类,实例化出:北京校区、上海校区两个对象 校区独有的特征有: 校区名=“xxx” 校区地址={'city':"所在市",'district':'所在的区'} 多们课程名=['xxx','yyy','zzz'] 多个班级名=['xxx','yyy','zzz'] 校区可以: 1、创建班级 2、查看本校区开设的所有班级名 3、创建课程 4、查看本校区开设的所有课程名 """ # class School: # def __init__(self, name, address, course, grade): # self.name = name # self.address = address # self.course = course # self.grade = grade # # def make_grade(self, grade_name): # self.grade.append(grade_name) # print('%s班开课啦' % grade_name) # # # def check_grade(self): # print(self.grade) # # def make_course(self, course_name): # self.course.append(course_name) # print('添加了%s课程' % course_name) # # def check_course(self): # print(self.course) # # bj = School('北京校区',{'city':'北京','district':'朝阳区'},['python','linux','go'],['python1期','linux1期','go1期']) # sh = School('上海校区',{'city':'上海','district':'浦东新区'},['python','linux','go'],['python1期','linux1期','go1期']) # # # bj.check_course() # bj.check_grade() # bj.make_grade('java1期') # bj.make_course('java') # # bj.check_course() # bj.check_grade() """ 8、定义出班级类,实例化出两个班级对象 班级对象独有的特征: 班级名=‘xxx’ 所属校区名=‘xxx’ 多门课程名=['xxx','yyy','zzz'] 多个讲师名=['xxx','xxx','xxx'] 班级可以: 1、查看本班所有的课程 2、查看本班的任课老师姓名 """ # class Grade: # def __init__(self,name,area_name,courses=[],teachers=[]): # self.name = name # self.area_name = area_name # self.courses = courses # self.teachers = teachers # # # def check_course(self): # print("%s班级 共开设%s个学科:" % (self.name,len(self.courses))) # print(self.courses) # # # def check_taacher(self): # print("%s班级 共有%s个任课老师:" % (self.name,len(self.teachers))) # print(self.teachers) # # py1 = Grade('python4期','上海校区',['python初级','python高级'],['egon','yang','zhang']) # py2 = Grade('python5期','上海校区',['python初级','python高级','python进阶'],['egon','yang','ji']) # py1.check_course() # py1.check_taacher() """ 9、定义课程类,实例化出python、linux、go三门课程对象 课程对象独有的特征: 课程名=‘xxx’ 周期=‘3mons’ 价格=3000 课程对象可以: 1、查看课程的详细信息 """ # class Course: # def __init__(self,name,month,price): # self.name = name # self.month = month # self.price = price # # def check_grade(self): # print("名称:%s 周期:%s 价格:%s" % (self.name,self.month,self.price)) # # c1 = Course('python','3mons',3000) # c2 = Course('linux','3mons',3400) # c3 = Course('go','3mons',3500) # # c1.check_grade() # c2.check_grade() # c3.check_grade() """ 10、定义学生类,实例化出张铁蛋、王三炮两名学生对象 学生对象独有的特征: 学号=10 名字=”xxx“ 班级名=['xxx','yyy'] 分数=33 学生可以: 1、选择班级 3、注册,将对象序列化到文件 """ import json # # # 要实现第一个要求 需要有一个班级李列表 # classes = ["python1期","go1期","python2期","java20期"] # class Student: # def __init__(self, number, name, grade,class_names=[]): # self.number = number # self.name = name # self.class_names = class_names # self.grade = grade # # #选课 # def chioce_class(self): # print("班级列表:") # for i in classes: # print(i) # res = input("请选择班级:").strip() # if res in self.class_names: # print("你已加入该班级...") # elif res in classes: # self.class_names.append(res) # print("加入成功!") # else: # print("输入不正确....") # # #序列化 # def save(self): # dic = {'number': self.number, 'name': self.name, 'class_name': self.class_names, 'grade': self.grade} # with open(self.name, 'wt', encoding='utf-8')as f: # json.dump(dic, f) # print('save successful') # # # # stu1 = Student(10, '张铁蛋', 'a3') # stu2 = Student(10, '王三炮', 'a3') # # stu1.chioce_class() # stu1.save() """ 11、定义讲师类,实例化出egon,lqz,alex,wxx四名老师对象 老师对象独有的特征: 名字=“xxx” 等级=“xxx”、 老师可以: 1、修改学生的成绩 """ # class Teacher(): # def __init__(self, name, level): # self.name = name # self.level = level # # #通过名字 反序列化得到学生对象 修改完成后在写入到文件 # def change(self, name, new_grade): # with open('%s' % name, 'rt', encoding='utf-8')as f: # dic = json.load(f) # dic['grade'] = new_grade # print(dic) # with open('%s' % name, 'wt', encoding='utf-8')as f: # json.dump(dic, f) # print("修改成功!") # # # # # tea1 = Teacher('egon', '高级') # # tea2 = Teacher('lqz', '高级') # # tea3 = Teacher('alex', '高级') # # tea4 = Teacher('wxx', '高级') # # # tea1.change('张铁蛋',90) """ 12、用面向对象的形式编写一个老师类, 老师有特征:编号、姓名、性别、年龄、等级、工资,老师类中有功能 1、生成老师唯一编号的功能,可以用hashlib对当前时间加上老师的所有信息进行校验得到一个hash值来作为老师的编号 def create_id(self): pass 2、获取老师所有信息 def tell_info(self): pass 3、将老师对象序列化保存到文件里,文件名即老师的编号,提示功能如下 def save(self): with open('老师的编号','wb') as f: pickle.dump(self,f) 4、从文件夹中取出存储老师对象的文件,然后反序列化出老师对象,提示功能如下 def get_obj_by_id(id): return pickle.load(open(id,'rb')) """ from hashlib import md5 import pickle,time # # # class Teacher: # def __init__(self, name, gender, age, level, wages): # self.name = name # self.gender = gender # self.age = age # self.level = level # self.wages = wages # self.id = self.create_id() # # def create_id(self): # md = md5(str(time.time()).encode("utf-8")) # return md.hexdigest() # # def tell_info(self): # print("姓名:%s,性别:%s,年龄:%s,级别:%s,工资:%s,id:%s" % # (self.name,self.gender,self.age,self.level,self.wages,self.id)) # # def save(self): # with open(self.id, 'wb') as f: # pickle.dump(self, f) # # @staticmethod # def get_obj_by_id(id): # return pickle.load(open(id, 'rb')) # # #序列化 # # t = Teacher("blex","男",20,"高级",3) # # t.save() # # #反序列化 # t2 = Teacher.get_obj_by_id("59905193f41f1f658cd9f0c530a59ab7") # t2.tell_info() """ 13、按照定义老师的方式,再定义一个学生类 """ # class Student: # def __init__(self, name, gender, age, level, wages): # self.name = name # self.gender = gender # self.age = age # self.level = level # self.wages = wages # self.id = self.create_id() # # def create_id(self): # md = md5(str(time.time()).encode("utf-8")) # return md.hexdigest() # # def tell_info(self): # print("姓名:%s,性别:%s,年龄:%s,级别:%s,工资:%s,id:%s" % # (self.name,self.gender,self.age,self.level,self.wages,self.id)) # # def save(self): # with open(self.id, 'wb') as f: # pickle.dump(self, f) # # @staticmethod # def get_obj_by_id(id): # return pickle.load(open(id, 'rb')) """ 14、抽象老师类与学生类得到父类,用继承的方式减少代码冗余 """ # # from hashlib import md5 # import pickle,time class BaseClass: def __init__(self, name, gender, age, level, wages): self.name = name self.gender = gender self.age = age self.level = level self.wages = wages self.id = self.create_id() def create_id(self): md = md5(str(time.time()).encode("utf-8")) return md.hexdigest() def tell_info(self): print("姓名:%s,性别:%s,年龄:%s,级别:%s,工资:%s,id:%s" % (self.name,self.gender,self.age,self.level,self.wages,self.id)) def save(self): with open(self.id, 'wb') as f: pickle.dump(self, f) @staticmethod def get_obj_by_id(id): return pickle.load(open(id, 'rb')) class Teacher(BaseClass): pass class Student(BaseClass): pass # #序列化 # t = Teacher("blex","男",20,"高级",3) # t.save() # # #反序列化 t2 = Teacher.get_obj_by_id("ba0698c54af43dcbefbc42605902677a") t2.tell_info()
7、定义学校类,实例化出:北京校区、上海校区两个对象
校区独有的特征有:
校区名=“xxx”
校区地址={'city':"所在市",'district':'所在的区'}
多们课程名=['xxx','yyy','zzz']
多个班级名=['xxx','yyy','zzz']
校区可以:
1、创建班级
2、查看本校区开设的所有班级名
3、创建课程
4、查看本校区开设的所有课程名
8、定义出班级类,实例化出两个班级对象
班级对象独有的特征:
班级名=‘xxx’
所属校区名=‘xxx’
多门课程名=['xxx','yyy','zzz']
多个讲师名=['xxx','xxx','xxx']
班级可以:
1、查看本班所有的课程
2、查看本班的任课老师姓名
9、定义课程类,实例化出python、linux、go三门课程对象
课程对象独有的特征:
课程名=‘xxx’
周期=‘3mons’
价格=3000
课程对象可以:
1、查看课程的详细信息
10、定义学生类,实例化出张铁蛋、王三炮两名学生对象
学生对象独有的特征:
学号=10
名字=”xxx“
班级名=['xxx','yyy']
分数=33
学生可以:
1、选择班级
3、注册,将对象序列化到文件
11、定义讲师类,实例化出egon,lqz,alex,wxx四名老师对象
老师对象独有的特征:
名字=“xxx”
等级=“xxx”、
老师可以:
1、修改学生的成绩
12、用面向对象的形式编写一个老师类, 老师有特征:编号、姓名、性别、年龄、等级、工资,老师类中有功能
1、生成老师唯一编号的功能,可以用hashlib对当前时间加上老师的所有信息进行校验得到一个hash值来作为老师的编号
def create_id(self):
pass
2、获取老师所有信息
def tell_info(self):
pass
3、将老师对象序列化保存到文件里,文件名即老师的编号,提示功能如下
def save(self):
with open('老师的编号','wb') as f:
pickle.dump(self,f)
4、从文件夹中取出存储老师对象的文件,然后反序列化出老师对象,提示功能如下
def get_obj_by_id(self,id):
return pickle.load(open(id,'rb'))
13、按照定义老师的方式,再定义一个学生类
14、抽象老师类与学生类得到父类,用继承的方式减少代码冗余