• 面向对象的三大特征
    • 封装
    • 继承(重要)
    • 多态
  • 继承的属性查找顺序
    • 单继承下的属性查找
    • 多继承下的属性查找
  • super()和mro()列表
  • 多态与多态性(鸭子类型)
  • 组合
  • 面向对象的内置函数(魔术方法,魔法,__开头__的方法)
  • 反射(掌握4个方法)

一、继承

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

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

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

类的继承

# 以学生选课系统为例
# 父类,公共类
class People():
    school = 'SH'

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

# 学生类
class Student(People):

    def __init__(self, name, age, gender, course=None):
        if course is None:
            course = []
        People.__init__(self, name, age, gender)
        self.courses = course

    def choose_course(self, course):
        self.courses.append(course)
        print('%s 选课成功 %s' % (self.name, self.courses))


stu = Student('ly', 19, 'male')

# teacher类
class Teacher(People):

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

    def score(self, stu_obj, score):
        stu_obj.score = score  # 给学生打分
        print('%s给%s打了%s分' % (self.name, stu_obj.name, score))


tea = Teacher('ly', 19, 'male', 10)
print(tea.name)
print(tea.level)

二、继承的属性查找顺序

单继承下属性查找

class Foo:
    def f1(self):
        print('Foo.f1')

    def f2(self):
        print('Foo.f2')
        self.f1()


class Bar(Foo):
    def f1(self):
        print('Bar.f1')


obj = Bar()  # {}
obj.f2()
"""
Foo.f2
Bar.f1
"""

# 练习
class Foo:
    def __f1(self):  # _Foo__f1()
        print('Foo.f1')

    def f2(self):
        print('Foo.f2')
        self.__f1()  # _Foo__f1()


class Bar(Foo):
    def __f1(self):  # # _Bar__f1()
        print('Bar.f1')


obj = Bar()  # {}
obj.f2()
"""
Foo.f2
Foo.f1
"""

image

多继承下的属性查找

# 新式类:按照广度优先查询
# 经典类:按照深度优先查询
class A(object):
    def test(self):
        print('from A')


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

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


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

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


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中才分新式类与经典类

image
image

三、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方法")

五、组合

组合:就是一个对象拥有一个属性,该属性的值是另外一个对象

解决类与类之间的代码冗余问题
    1.继承:满足什么是什么的关系,is-a的关系
    2.组合:有的关系,eg:教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...


class People():
    school = 'SH'

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

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


python = Course('python', '6mon', 10000)
linux = Course('linux', '5mon', 20000)


class Student(People):
    def __init__(self, name, age, gender, course=None):
        if course is None:
            course = []
        self.courses = course
        super().__init__(name, age, gender, )

    def choose_course(self, stu_obj, course):
        stu_obj.courses.append(course)

stu = Student('ly', 20, 'male')
stu.courses.append(python)
stu.courses.append(linux)
# [python, linux]

for course in stu.courses:
    print(course)
'''
对象内存地址
<__main__.Course object at 0x00000211C6A5D908>
<__main__.Course object at 0x00000211C6A5D860>
'''

for course in stu.courses:
    print(course.price)
'''
10000
20000
'''

六、面向对象的内置函数

1. __init__()
2. __str__()
3. __del__()
4. __enter__()
5. __exit__()
6. __call__()

class Student():
    school = 'SH'

    # 调用类的时候触发
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def tell(self):
        print('name: %s, age: %s' % (self.name, self.age))

    # 打印对象的时候,自动触发的函数
    # 返回值只能是字符串
    def __str__(self):
        # return 'name:%s' % self.name  # name:ly  print(stu)结果
        return 123  # TypeError: __str__ returned non-string (type int)

    # 1. 手动执行del
    # 2. 程序执行完毕触发
    def __del__(self):
        print('__del__')
    '''
    <__main__.Student object at 0x0000023DBF22E240>
    __del__
    '''


    # 对象加括号自动触发
    def __call__(self, *args, **kwargs):
        print('__call__')


stu = Student('ly', 20)

七、反射(掌握4个方法)

# 对象通过字符串来操作属性

1. getattr 查
print(getattr(stu, 'name1', None))  # stu.name
stu.func()
print(getattr(stu, 'func'))
getattr(stu, 'func')()  # 必须掌握

2. setattr 改
setattr(stu, 'x', 123)
print(stu.__dict__)

3. hasattr 判断
print(hasattr(stu, 'name'))

4. delattr 删
delattr(stu, 'name')
print(stu.__dict__)
posted on 2021-12-06 17:26  幽星  阅读(42)  评论(0)    收藏  举报