day23 继承介绍 先抽象再继承 在继承背景下验证对象的属性查找 派生 在子类派生出的新方法中重用父类功能的方法一 在子类派生出的新方法中重用父类功能的方法二 经典类与新式类 菱形继承 super()对象严格依赖mro列表 周末作业

面向对象的三大特性:继承,封装,多态

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、抽象老师类与学生类得到父类,用继承的方式减少代码冗余


原文地址:https://www.cnblogs.com/wangmiaolu/p/10119319.html