Python面向对象笔录(二)

继承

继承是⾯向对象三⼤特性之⼀
通过继承我们可以使⼀个类获取到其他类中的属性和⽅法
在定义类时,可以在类名后⾯的括号中指定当前类的⽗类(超类、基类)
继承提⾼了类的复⽤性。让类与类之间产⽣了关系。有了这个关系,才有了多态的特性

class Person():

    def __init__(self,name):
        print('Person __init__ 被调用')
        self.name = name

    def run(self):
        print('Person'+self.name+'可以奔跑')

    def ability(self):
        print('Person 可以制造工具')

class China(Person):

    def __init__(self,name,city):
        print('China __init__ 被调用')
        self.name = name
        self.city = city

    def eat(self):
        print(f'China {self.name}住在{self.city} 正在吃饭!')

if __name__ == '__main__':

    cp = China('张学友','香港')
    cp.ability() #继承父类的方法
    cp.run() #继承父类的方法
    cp.eat() #调用自己的方法函数
    '''
    China __init__ 被调用
    Person 可以制造工具
    Person张学友可以奔跑
    China 张学友住在香港 正在吃饭!
    
    '''
    # 检查对象是否为类的实例
    r = isinstance(cp,China)
    print(r) # True
    r = isinstance(cp,Person)
    print(r) # True

    # issubclass()检查一个类是否是另一个类的子类
    print(issubclass(Person,object)) # True
    # 在创建类时,如果省略了父类,则默认父类为object
    # object是所有类的父类,所有类都继承自object
    # 所有的对象都是object的实例
    # class Person(object):
    #
    #     pass
    # issubclass()检查一个类是否是另一个类的子类

方法重写

如果在⼦类中有和⽗类同名的⽅法,则通过⼦类实例去调⽤⽅法时,会调⽤⼦类的⽅法⽽不是⽗类的⽅法,这个特点我们称之为⽅法的重写(覆盖)。
当我们调⽤⼀个对象的⽅法时:

  1. 会优先去当前对象中寻找是否具有该⽅法,如果有则直接调⽤;
  2. 如果没有,则去当前对象的⽗类中寻找,如果⽗类中有则直接调⽤⽗类中的⽅法;
  3. 如果没有,则去⽗类中的⽗类寻找,以此类推,直到找到object;
  4. 如果依然没有找到就报错了。
class Class_a(object):

    def __init__(self):
        print('I am Class Class_a')

    def fun(self):
        print('I am Class_a fun')

    def fun_a(self):
        print('I am Class_a fun_a')

class Class_b(Class_a):

    def __init__(self):
        print('I am Class Class_b')

    def fun(self):
        print('I am Class_b fun')

    def fun_b(self):
        print('I am Class_b fun_b')

class Class_c(Class_b):

    def __init__(self):
        print('I am Class Class_c')

    def fun_b(self):
        print('I am Class_c fun_b')

if __name__ == '__main__':

    class_c = Class_c()
    # 结果为: I am Class Class_c

    class_c.fun_b()
    # 结果为: I am Class_c fun_b
    # 覆盖:优先调用自己内部的方法


    class_c.fun()
    # I am Class_b fun
    # 自己没有方法,就去父类找

    class_c.fun_a()
    # I am Class_a fun_a
    # 自己没有就去父类找,父类没有,再去从父类的父类寻找

super()函数

在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,通过super()可以直接获取当前类的父类的方法

super函数的主要作用如下:

单继承中, super用来指代隐式指代父类, 避免直接使用父类的名字
常用于super 的一个最常见用法可以说是在子类中调用父类的初始化方法。super的一大好处在于,当父类的名字修改时,其继承类不用修改调用方法


class Parent():

    def __init__(self,name):
        print('I am Parent __init__')
        self.name = name


class Subclass(Parent):

    def __init__(self, name,age):
        #self.name = name
        # 通过super()可以直接获取当前类的父类
        super().__init__(name)
        self.age = age

    def p_c(self):
        print(self.name,self.age)

if __name__ == '__main__':

    Sc = Subclass('小刚',12)
    Sc.p_c()
    #为了实现继承, python会在MRO列表上从左到右开始查找基类, 直到找到第一个匹配这个属性的类为止
    print(Subclass.mro())
    # [, , ]

多继承中, 解决Diamond问题 (TODO)

最能感受到super函数的作用在于进行钻石继承的时候。
钻石继承:由一个基类衍生两个及以上的超类,然后在衍生,在类树的最底层生成一个子类,这样的类树结构就是一个类似 钻石外形,所以,最底层类继承称为钻石继承

多重继承

在Python中是支持多重继承的。也就是我们可以为一个类同时制定多个父类;
可以在类名的()后边添加多个类,来实现多重继承;
多重继承,会使子类同时拥有多个父类,并且会获取到所有父类中的方法;
在开发中没有特殊情况,应该尽量避免使?多重继承。因为多重继承会让我们的代码更加复杂;
如果多个父类中有同名的方法,则python会按照MRO(method resolution order) 方法解析顺序列表进行查找。

class Parent_first():

    def __init__(self,name):
        print('I am Parent_first __init__')
        self.name = name

class Parent_second():

    def __init__(self,name):
        print('I am Parent_second __init__')
        self.name = name

class Subclass(Parent_first,Parent_second):

    def __init__(self, name,age):
        #self.name = name
        # 通过super()可以直接获取当前类的父类
        #Parent_first.__init__(self, name)
        #Parent_second.__init__(self, name)

        super().__init__(name)
        self.age = age

    def p_c(self):
        print(self.name,self.age)

if __name__ == '__main__':

    Sc = Subclass('小刚',12)
    #I am Parent_first __init__
    Sc.p_c()
    #为了实现继承, python会在MRO列表上从左到右开始查找基类, 直到找到第一个匹配这个属性的类为止
    print(Subclass.mro())
    # [, , 

多态

多态是面向对象的三大特性之一。从字面理解就是多种形态一个对象可以以不同形态去呈现,Python中多态是指一类事物有多种形态。比如动物有多种形态,人,狗,猫,等等。文件有多种形态:文本文件,可执行文件。多态性是指在不考虑实例类型的情况下使用实例,多态性分为静态多态性和动态多态性。


class Animals(object):

    def __init__(self):
        print('I am Animals __init__')

    def talk(self):
        print('I am Animals talk')


class People(Animals):

    def __init__(self):
        print('I am People __init__')

    def talk(self):
        print('人在谈话')


class Cat(Animals):

    def __init__(self):
        print('I am Cat __init__')

    def talk(self):
        print('小猫喵喵叫')


class Dog(Animals):

    def __init__(self):
        print('I am Dog __init__')

    def talk(self):
        print('小狗 汪汪叫')


# 定义一个统一的接口来访问
def func(obj):
    obj.talk()

if __name__ == '__main__':

    cat = Cat()
    dog = Dog()
    peo = People()

    func(cat)
    func(dog)
    func(peo)

面向对象三大特性
封装 确保对象中数据的安全
继承 保证了对象的扩展性
多态 保证了程序的灵活性


面向对象三大特性:
1.封装:确保对象中数据的安全
2.继承:保证了对象的扩展性;
3.多态:保证了程序的灵活性

你可能感兴趣的:(Python笔记)