/* 看板娘 */ /* 粒子吸附*/

面向对象的三大特征 - 封装 - 继承(重要) - 多态 - 继承的属性查找顺序 - 单继承下的属性查找 - 多继承下的属性查找 - super()和mro()列表 - 多态与多态性(了解)

一、面向对象的三大特征

封装:封装指的就是把数据与功能都整合到一起

继承应用

1. 什么是继承?
# 继承就是新建类的一种方式,新建的类我们称为子类或者叫派生类,被继承的类我们称为父类或者基类
# 子类可以使用父类中的属性或者方法
2. 为什么要用继承?
类解决了对象与对象之间的代码冗余问题
继承解决的是类与类之间的代码冗余问题

3. 如何使用继承?
新式类:继承了object类的子子孙孙类都是新式类
经典类:没有继承了object类的子子孙孙类都是经典类

# 新式类和经典类只有在python2中区分

class Student:     #定义学生的类
    school = 'SH'   
    def __init__(self,name,age,gender):  #初始化对象实行实际传参
        self.name = name
        self.age = age
        self.gender = gender
    def choose(self):
        print("%s选课成功" %self.name)
stu1 = Student('jj',18, 'male')
stu2 = Student('qq',18, 'male')
stu3 = Student('aa',18, 'male')
stu4 = Student('bb',18, 'female')
class Teacher:
    school = 'SH'
    def __init__(self,name, age,gender,level):
        self.name = name
        self.age = age
        self.gender = gender
        self.level = level
    def score(self):
        print('%s正在为学生打分'% self.name)
tea1 = Teacher('nn',18,'male',80)
tea2 = Teacher('lxx',38,"male",3)

从上面看出:类与类之间存在重复代码。老师与学生都是人类,所以我们可以得到如下的继承关系,实现代码冗余

方式一,指明道姓地引用某一个函数,与继承无关



class people:
    school = 'SH'
    def __init__(self ,name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
class student(people):
    def choose(self):
        print('%s 选课成功' %self.name)
class teacher(people):
    def __init__(self,name,age, gender,level):
        people.__init__(self, name, age, gender)  #再子类的派生功能中重用父类功能
        self.level = level
    def score(self):
        print('%s 正在为学生打分'%self.name)

stu1 = student('jj',18,'male')
stu2 = student('tom',19, 'female')
teal = teacher('mm',18,'male',3)
tea2 = teacher('ll',18,'male',5)



print(stu2.name)

print(stu1.school)
print(teal.name)

方式二:SUPER()返回一个特殊的对象,该对象会参考发起属性查找的哪一个类的mro列表,去当前类的父类中找属性,严格以来继承

class people:
    school = 'SH'    #公用的属性
    def __init__(self,name,age,gender):    #共用的方法
        self.name = name
        self.age = age
        self.gender = gender
class Teacher(people):
    def __init__(self,name, age, gender,level):
        #people.__init__(self, name, age, gender)
        super(Teacher, self).__init__(name,age,gender)
        self.level = level
    def score(self):
        print('%s 正在给学生打印分数' % self.name)

tea1 = Teacher('hxx',18,'male',10)
print(tea1.__dict__)  #{'name': 'hxx', 'age': 18, 'gender': 'male', 'level': 10}

继承的实现原理

继承顺序

Python中子类可以同时继承多个父类,如A(B,C,D)

如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性

如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先

 

 

 

 

 

 

 

 继承顺序

# 继承顺序
class A(object):
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性

# 新式类继承顺序:F->D->B->E->C->A
# 经典类继承顺序:F->D->B->A->E->C
# python3中统一都是新式类
# pyhon2中才分新式类与经典类

super()和mro列表

class People():
    school = 'SH'

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
        
class Teacher(People):

    def __init__(self, name, age, gender, level):
        self.level = level
        super().__init__(name, age, gender) # super的使用

        
# mro列表练习1
class A:
    def test(self):
        print('from A.test')
        super().test()


class B:
    def test(self):
        print('from B')


class C(A, B):
    pass


c = C()
c.test()


# mro列表练习2 
class B:
    def test(self):
        print('B---->test')

    def aaa(self):
        print('B---->aaa')

class A:
    def test(self):
        print('A---->test')
        super().aaa()


class C(A, B):
    def aaa(self):
        print('C----->aaa')


c = A()
# c.test()  # 打印结果:
print(A.mro())

多态与多态性(了解)

1. 什么是多态
水:液态水,固态水,气态水
动物:人,猪,狗,猫 ...



# 抽象类: 抽象类只能被继承,不能被实例化
class Animal(metaclass=abc.ABCMeta):

    @abc.abstractmethod  # 该方法已经是抽象方法了
    def speak(self): pass

    @abc.abstractmethod
    def login(self):pass

class People(Animal):
    def speak(self):
        # print('嗷嗷嗷')
        pass
    def login(self):
        pass


class Pig(Animal):
    def speak(self):
        print('哼哼哼')


class Dog(Animal):
    def speak(self):
        print('汪汪汪')


obj = People()
obj.speak()


# 多态练习
class Pig():
    def speak(self):
        print('哼哼哼')


class Dog():
    def speak(self):
        print('汪汪汪')

class Txt():
    def speak(self):
        print('Txt')

obj = People()
obj1 = Pig()
obj2 = Dog()
obj3 = Txt()

# 多态带来的特性:在不用考虑对象数据类型的情况下,直接调用对应的函数

def animal(animal):
    return animal.speak()

animal(obj)
animal(obj1)
animal(obj2)
animal(obj3)

# 父类限制子类的行为
class Animal():
    def speak(self):
        raise Exception("必须实现speak方法")

 

posted @ 2021-12-06 20:54  红绿灯的黄呀  阅读(30)  评论(0)    收藏  举报