Day 23 面向对象进阶

面向对象进阶

类的继承

什么是继承

  • 继承是一种新建类的方式,新建的类称为子类,被继承的类称为父类
  • python当中,父类,子类(派生类),父类和子类只有在继承的时候才会产生
  • 继承是为了获取父类的属性

为什么要用继承

  • 集成可以减少代码冗余

对象的继承

  • python中支持一个子类继承多个父类,但是不推荐使用继承多个父类,当你继承多个的时候,功能与功能之间就会混乱,所以建议继承一个
  • python3中如果一个类没有继承任何类,那么默认继承object类
  • python2中如果一个类没有继承任何类,不会继承object类

对象查找属性的顺序

先对象自己,后然后对象的类,然后父类,在父类,知道object类

类的派生

派生就是子类定义新的属性,同时还继承父类的所有属性

方法一:指名道姓的访问某一个类的函数,该方式与继承无关

class Animal():
    def __init__(self, height, weight):  
        self.height = height  
        self.weight = weight  

    def jiao(self):
        print(self.__class__.__name__, '叫')
        
class People(Animal):
    def __init__(self, name, age,height,weight):
        Animal.__init__(self,height,weight)
        self.name = name
        self.age = age

    def read(self):
        print('read')
        
p1=People('nick',18,180.140)
print(p1.__dict__)

方法二:派生

  • 严格以继承属性查找关系
  • super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性的(按照继承的关系)
  • super的完整用法是super(自己的类名,self),在python2中需要完整写明,二python3中可以简写为super()
class OldBoyPeople:
    school='oldboy'
    
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
        
class OldBoyStudent(OldBoyPeople):
    def __init__(self,name,age,sex,stu_id):
        super().__init__(name,age,sex)
        self.stu_id=stu_id
    def choose_course(self):
        print(f'{self.name} is choosing course')
        
stu1=OldBoyStudent('nick',19,'male','001')

类的组合

组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象

组合就是用来解决类与类之间代码冗余的问题

class People:
    def __init__(self,name,sex):
        self.name=name
        self.sex=sex

    def eat(self):
        print(f'{self.name}开始吃')

class Student(People):
    def __init__(self,id,name,sex):
        super(Student, self).__init__(name,sex)
        self.id=id

    def choose_course(self,course):
        self.course=course      #相当于student派生一个course属性,该属性引用外部传入的course也就是Course生成的对象
        print(f'{self.name}选择了课程{course.name}')

class Teacher(People):
    def __init__(self,level,name,sex):
        super(Teacher, self).__init__(name,sex)
        self.level=level

    def scored(self,student,course,score):
        print(f'{self.name}给学生{student.name}的课程{course.name}打{score}分')

class Admin(People):
    def create_course(self,name,price):
        course=Course(name,price)
        print(f'管理员{self.name}创建了课程{name}')
        return course


class Course:
    def __init__(self,name,price):
        self.name=name
        self.price=price



st1=Student('01','zhujian','male')
st2=Student('02','tom','male')
print(st1.__dict__)
print(st2.__dict__)

t1=Teacher('1','nick','male')
print(t1.__dict__)

a1=Admin('egon','male')
print(a1.__dict__)

linux=a1.create_course('linux',6666)
python=a1.create_course('python',8888)

st1.choose_course(python)
st2.choose_course(linux)

t1.scored(st1,python,'96')
t1.scored(st2,linux,'95')

菱形继承问题

类的分类

  1. 新式类
  • 继承了object的类以及该类的子类,都是新式类
  • python3中所有的类都是新式类
  1. 经典类
  • 没有继承object的类以及该类的子类,都是经典类
  • 只有python2中才有经典类

菱形继承问题

如果继承关系为菱形结构,即子类的父类最后继承了同一个类,那么属性的查找有两种:

  • 经典类:深度优先:一条路走到底.先从子类的第一个父类开始查找,直到这个子类继承的最后一个父类,如果没有找到就从子类的第二个父类开始查找(但不会找到最后一个父类),然后是子类的第三个父类,第四个父类,直到找到需要的属性
  • 新式类:广度优先:不直接找最后一个继承的父类,先从子类的子一个父类开始找,跳过继承的最后一个父类,然后子类的第二个父类,第三个,直到最后一个父类然后再去查找他们继承的最后一个父类

普通继承就是按照正常循序查找

多态与多态性

多态

多态指的是一类事物有多种形态(一个抽象类有多个子类,因而多态的概念依赖于继承)

多态性

多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用给一个函数名调用不同内容的函数

猜你喜欢

转载自www.cnblogs.com/masterjian924/p/11056499.html