python-面向对象(三)

类的继承

概念

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

3. 如何使用继承?
	   新式类:继承了object类的子子孙孙类都是新式类
     经典类:没有继承了object类的子子孙孙类都是经典类
    
     # 新式类和经典类只有在python2中区分
     # 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):
        People.__init__(self, name, age, gender)
        self.course = course


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

    def score(self, stu_obj, score):
        stu_obj.score = score


s1 = Student('mjc', 99, 'male')
t1 = Teacher('jason', 18, 'male', 100)
print(s1.name)
t1.score(s1, 90)
print(s1.score)

单继承下的属性查找

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

    def f2(self):
        print('from Foo:s2')
        self.f1()  # 从对象本身开始再出发,所以从Bar类中的 f1


class Bar(Foo):
    def f3(self):
        print('from Bar:f3')

    def f1(self):
        print('from Bar:f1')


obj = Bar()
obj.f2()  
# from Foo:s2
# from Bar:f1

多继承下的属性查找(菱形问题)

Ux9lsD

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__)  # 只有新式才有这个属性可以查看线性列表,经典类没有这个属性
print(F.__bases__)  # 查看继承了哪些父类

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

mro列表

class A:
    def test(self):
        print('from A:test')
        super().test()


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


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


s = C()
s.test()
print(C.__mro__)

# from A:test
# from B:test
# (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

super()

# 用于调用父类的一个方法

多态与多态性

抽象类

# 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

import abc

class Animal(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def talk(self):
        pass


class People(Animal):
    # pass  # 这个地方必须定义 talk 抽象方法 如果没定义实例化就会报错
    def talk(self):
        print('哈哈哈')


c = People()

多态

# 定义时的类型和运行时的类型不一样,就称为多态。
class Pig():
    def talk(self):
        print('哼哼哼')


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

# dog、pig都是动物,只要是动物肯定有talk方法
# 于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
obj1 = Pig()
obj2 = Dog()

鸭子类型

动态语言调用实例方法时不检查类型,只要方法存在,参数正确,就可以调用。这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。

def len1(a):
    return a.__len__()


s = 'test'
l = ['1', '2']

len1(s)
len1(l)

父类限制子类

# 父类限制子类的行为
class Animal():
    def speak(self):
        raise Exception("必须实现speak方法")
posted @ 2021-12-06 19:22  klcc-cc  阅读(64)  评论(0)    收藏  举报