面向对象的三大特性:继承,封装,多态
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、抽象老师类与学生类得到父类,用继承的方式减少代码冗余