day6 面向对象 封装 继承 多态 类与实例在内存中的关系 经典类和新式类
一面向对象
面向对象编程
OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。
面向对象的几个核心特性如下
class类
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法
Object 对象
一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同
Encapsulation 封装
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
Inheritance 继承
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承
继承时子类重写构造函数时有两种写法:
class A(object): def __init__(self, name, age): self.name = name self.age = age class B(A): def __init__(self, name, age, job): # A.__init__(self, name, age) super(B, self).__init__(name, age) self.job = job
# 第一种 A.__init__(self, name, age)
# 第二种 super(B, self).__init__(name, age)
# 建议使用super(B, self).__init__(name, age),第一种必须要使用继承的A,而且继承多个类的情况下,新式类默认使用的广度优先的继承逻辑。
Polymorphism 多态
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。
对不同类的对象发出相同的消息将会有不同的行为。比如,你的老板让所有员工在九点钟开始工作, 他只要在九点钟的时候说:“开始工作”即可,而不需要对销售人员说:“开始销售工作”,对技术人员说:“开始技术工作”, 因为“员工”是一个抽象的事物, 只要是员工就可以开始工作,他知道这一点就行了。至于每个员工,当然会各司其职,做各自的工作。
多态允许将子类的对象当作父类的对象使用,某父类型的引用指向其子类型的对象,调用的方法是该子类型的方法。这里引用和调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定
class Animal(object): def __init__(self, name): # Constructor of the class self.name = name def talk(self): # Abstract method, defined by convention only # raise NotImplementedError("Subclass must implement abstract method") print('%s..' % self.name) class Cat(Animal): def talk(self): print('%s: 喵喵喵!' % self.name) class Dog(Animal): def talk(self): print('%s: 汪!汪!汪!' % self.name) def func(obj): # 一个接口,多种形态, 既可以是cat,dog,还可以是animal obj.talk() c1 = Cat('小晴') d1 = Dog('李磊') a1 = Animal('fish') func(c1) func(d1) func(a1)
类与实例在内存中的关系
经典类和新式类的区别
1、python3以后完全使用了新式类,python2中如果class name: 则表示经典类,class name(object):表示新式类
2、继承的区别,新式类是按照广度来进行继承,示例如下B继承A,C继承A,class D(B,C),如果是新式类中则按广度继承,先继承B的,如果B没有则继承C,经典类中如果B没有则直接网上一级,继承A的
二、作业
import time class School(object): def __init__(self, school_name, address): self.school_name = school_name self.address = address self.school_class = [] self.school_teacher = [] self.school_students = [] self.school_course = [] def join_teacher(self, name, sex, age, course_name): teacher = Teacher(name, sex, age, course_name) self.school_teacher.append(teacher) return teacher def create_course(self, name, price, cycle): course = Course(name, price, cycle) self.school_course.append(course) return course def create_class(self, name, obj_teacher, obj_course): my_class = MyClass(name, obj_teacher, obj_course) self.school_class.append(my_class) return my_class def student_register(self, obj_student): self.school_students.append(obj_student) def student_payment(self, obj_student, obj_class): if obj_student in self.school_students: obj_class.students.append(obj_student) else: print('%s is not register' % obj_student.name) class MyClass(object): def __init__(self, name, obj_teacher, obj_course): self.name = name self.teacher = obj_teacher self.course = obj_course self.record = [] self.students = [] class Student(object): def __init__(self, name, sex, age, obj_class, obj_school): self.name = name self.sex = sex self.age = age self.my_class = obj_class self.school = obj_school def register(self, obj_school): obj_school.student_register(self) def payment(self, obj_school, obj_class): obj_school.student_payment(self, obj_class) def goto_class(self, sign_stat=1): my_record = StudentRecord(self.name, sign_stat, sign_date=time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())) return my_record class Teacher(object): def __init__(self, name, sex, age, course_name): self.name = name self.sex = sex self.age = age self.course_name = course_name @staticmethod def teaching(obj_class, times): my_record = Record(obj_class.name, times, date=time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())) for student in obj_class.students: student_record = student.goto_class() student_record.grade = 100 my_record.student_record.append(student_record) obj_class.record.append(my_record) class Course(object): def __init__(self, name, price, cycle): self.name = name self.price = price self.cycle = cycle class Record(object): def __init__(self, class_name, times, date): self.class_name = class_name self.times = times self.date = date self.student_record = [] class StudentRecord(object): def __init__(self, name, sign_stat, sign_date): self.student_name = name self.sign_stat = sign_stat self.sign_date = sign_date self.grade = None school_sc = School('制胜教育学校', '四川') school_sh = School('驭胜教育学校', '上海') linux = school_sc.create_course('linux', 5000, 120) python = school_sc.create_course('python', 6000, 150) go = school_sh.create_course('go', 6000, 140) glen = school_sc.join_teacher('glen', 'man', 23, linux.name) alex = school_sh.join_teacher('alex', 'women', 36, go.name) linux22 = school_sc.create_class('linux22', glen, linux) go22 = school_sh.create_class('go22', alex, go) jack = Student('jack', 'man', 18, linux22, school_sc) alice = Student('alice', 'women', 22, go22, school_sh) jack.register(school_sc) alice.register(school_sh) jack.payment(school_sc, linux22) alice.payment(school_sh, go22) glen.teaching(linux22, 1) print(linux22.record[0].student_record[0].student_name)