Python学习笔记之封装、重写、MRO(方法解析顺序)、多态

本文介绍了面向对象编程的四大特征。封装是将属性和方法封装到类对象中;继承可实现代码重用,有单继承和多继承,子类能重写父类功能;重写可让子类自定义父类属性或方法;多态是一种接口多种实现,实现接口重用,还提及了MRO概念。

封装
是面向对象编程的三大特征之一,将属性和方法 封装 到一个抽象的类对象中,在方法内部对属性进行操作,在类对象外部调用方法

class Student(object):
    def __init__(self):
        self.__score = 90
        
    def get_score(self):
        return self.__score
    
    def set_score(self, score):
        if 0<=score<=100:
            self.__score = score
        else:
            raise ValueError("成绩必须在0~100之间")
s = Student()
s.get_score()
>
>
90
s = Student()
s.set_score(88)
print(s.get_score())
>
>
88

继承
主要体现是实现代码的 重用,相同的代码不需要重复的编写;
子类可以在父类功能上进行重写,扩展类的功能。
单继承:子类只有一个直接父类时称为单继承
多继承:子类有多个直接父类时称为多继承
子类会继承父类(包括直接和间接父类)的所有属性和方法

class Animal(object):
    def eat(self):
        print("吃饭")
        
    def drink(self):
        print("喝水")
class Dog(Animal):
    def swim(self):
        print("游泳")
class Bird(Animal):
    def fly(self):
        print("飞翔")
dog = Dog()
dog.eat()
dog.drink()
dog.swim()
>
>
吃饭
喝水
游泳
bird = Bird()
bird.eat()
bird.drink()
bird.fly()
>
>
吃饭
喝水
飞翔

重写
如果子类对继承父类的某个属性或方法不满意,可以在子类中对其进行重写从而提供自定义的实现,重写的方式为:在子类中定义与父类中同名的属性或方法(包括装饰器)

子类重写父类的属性后,通过子类或其实例对象只能访问重写后的属性,而无法访问被重写的父类的属性
子类重写父类的方法后,通过子类或其实例对象只能访问重写后的方法,而无法访问被重写的父类的方法

class ParentClass(object):
    ca = "ca(父类)"
    
    def __init__(self):
        print("__init__()被调用了(父类)")
    def im(self):
        print("im()被调用了(父类)")
        
    @classmethod
    def cm(cls):
        print("cm()被调用了(父类)")
        
class ChildClass(ParentClass):
    ca = "ca(子类)"
    
    def __init__(self):
        print("__init__()被调用了(子类)")
        
    def im(self):
        print("im()被调用了(子类)")
        
    @classmethod
    def cm(cls):
        print("cm()被调用了(子类)")

cc = ChildClass()
print(ChildClass.ca)
print(cc.ca)
cc.im()
ChildClass.cm()
cc.cm()
>
>
__init__()被调用了(子类)
ca(子类)
ca(子类)
im()被调用了(子类)
cm()被调用了(子类)
cm()被调用了(子类)

父类中被重写的名为xxx的方法,在子类重写后的方法中可以通过super().xxx()进行调用

class ChildClass(ParentClass):
    ca = "ca(子类)"
    
    def __init__(self):
        super().__init__()
        print("__init__()被调用了(子类)")
        
    def im(self):
        super().im()
        print("im()被调用了(子类)")
        
    @classmethod
    def cm(cls):
        super().cm()
        print("cm()被调用了(子类)")
cc = ChildClass()
print(ChildClass.ca)
print(cc.ca)
cc.im()
ChildClass.cm()
cc.cm()
>
>
__init__()被调用了(父类)
__init__()被调用了(子类)
ca(子类)
ca(子类)
im()被调用了(父类)
im()被调用了(子类)
cm()被调用了(父类)
cm()被调用了(子类)
cm()被调用了(父类)
cm()被调用了(子类)

MRO(方法解析顺序)
对于支持继承的编程语言来说,其方法(属性)可能定义在当前类,也可能来自于基类,所以在方法调用时就需要对当前类和基类进行搜索以确定方法所在的位置。而搜索的顺序就是所谓的「方法解析顺序」(Method Resolution Order,或MRO)
在这里插入图片描述

class A(object):
    def f(self):
        print("A.f")
        
class B(A):
    def f(self):
        print("B.f")
        
class C(A):
    def f(self):
        print("C.f")
        
class D(B, C):
    def f(self):
        print("D.f")
d = D()
d.f()
>
>
D.f


class A(object):
    def f(self):
        print("A.f")
        
class B(A):
    pass
        
class C(A):
    def f(self):
        print("C.f")
        
class D(B, C):
    pass
#pass可以理解为跳过的意思
d = D()
d.f()
>
>
C.f

对于一颗类继承树,可以调用最底层类对象的方法mro()或访问最底层类对象的特殊属性__mro__

print(D.mro())
>
>
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

如果想调用指定父类中被重写的方法,可以给super()传入两个实参:super(a_type, obj),其中obj所对应类对象的MRO中,a_type后面的那个类对象

class A(object):
    def f(self):
        print("A.f")
        
class B(A):
    def f(self):
        print("B.f")
        
class C(A):
    def f(self):
        print("C.f")
        
class D(B, C):
    def f(self):
        super(B,self).f()
d = D()
d.f()
>
>
C.f()

多态
一种接口多种实现,实现接口的重用。简单的说多态就是“具有多种形态”

class Q(object):
    def r(self):
        print("666")
        
class W(Q):
    def r(self):
        print("777")
        
class E(Q):
    def r(self):
        print("888")
        
def t(y):
    y.r()
t(Q())
t(W())
t(E())
>
>
666
777
888
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值