(D19)Python-封装、多态、多继承、重写

版权声明:转载请声明 https://blog.csdn.net/dirckes8813/article/details/83615988


封装 enclosure

  • 封装是指隐藏类的实现细节,让使用者不用关心这些细节
  • 封装的目的是让使用者通过尽可能少的方法(或属性)操作对象

私有属性和方法:

  • python类中以双下划线(’__’)开头,不以双下划线结尾的标识符为私有成员,私有成员只能用此类的方法进行访问和修改

示例1:


# 此示例示意用私有属性和私有方法来进行封装
class A:
    def __init__(self):
        self.__p1 = 100  # 创建私有属性,此属性在类外无法访问
 
    def __m1(self):  # 私有方法
        print("__m1 私有方法被调用")
 
    def infos(self):
        print("A类的infos访问的__p1属性是:", self.__p1)
        self.__m1()  # 调用自己的私有方法
    
a = A()
# print(a.__p1)  # 出错
a.infos()
# a.__m1()  # 当前主模块不能调用A类的私有方法


多态 polymorphic

  • 什么是多态:

    • 字面意思: 多种状态
  • 状态:

    • 静态(编译时状态)
    • 动态(运行时状态)
  • 多态是指在有继承/派生关系的类中,调用基类对象的方法,调用基类对象的方法,实际能调用子类的覆盖方法的现象叫多态

  • 说明:

    • 多态调用的方法与对象相关,不与类型相关
    • python全部对象都只有运行时状态(动态)
    • 没有"c++语言"里编译时状态(静态)

示例2:


# 此示例示意python的多态(动态)
class Shape:
    '''图形'''
    def draw(self):
        print("Shape的draw() 被调用")
 
class Point(Shape):
    def draw(self):
        print("正在画一个点")
 
class Circle(Point):
    def draw(self):
        print("正在画一个圆")
        
def my_draw(s):
    s.draw()  # s.draw调用谁是在运行时由s的类型动态决定
              # 此处显示出运行时状态
 
shape1 = Circle()
shape2 = Point()
my_draw(shape1)
my_draw(shape2)
 
L = [Point(), Circle(), Point(), Point(), Circle()]
 
for s in L:

面向对象的编程语言的特征

封装
继承/派生
多态

多继承 multiple inheritance

  • 多继承是指一个子类继承自两个或两个以上的基类

语法:
- class 类名(基类名1,基类名2,…)
说明:

  • 一个子类同时继承自多个父类,父类中的方法可以同时被继承下来
    如果两个父类中有同名的方法,则在子类中又没有覆盖此方法时,
    调用结果难以确定
    示例3:

# 此示例示意多继承的语法和用法
class Car:
    def run(self, speed):
        print('车正在以', speed, '公里/小时的速度行驶')
 
class Plane:
    def fly(self, height):
        print('飞机以海拔', height, '米的高空飞行')
 
class PlaneCar(Plane, Car):
    '''PlaneCar类同时继承是Plane和 Car类'''
 
p1 = PlaneCar()
p1.fly(10000)

多继承的问题(缺陷)

  • 标识符(名字空间)冲突问题
  • 要谨慎使用多继承

多继承的MRO(Method Resolution Order)等问题

  • 类的__mro__属性:
    • 作用:
      • 用来记录属性(或方法)的查找顺序

函数重写 overwrite

什么是函数重写

  • 在自定义的类内添加相应的方法,让自定义的类生成的对象(实例)
  • 像内建对象一样进行函数操作

对象转字符串函数:

  • repr(x) 返回一个能代表此对象的表达式字符串,通常:
    • eval(repr(obj)) = obj
  • str(obj) 通过给定对象,返回一个字符串(这个字符串通常是给人阅读的)

示例4:

# 此示例示意repr函数和str函数的不同
s = "I'm Teacher"
print(str(s))  
print(repr(s))
 
 
class MyNumber:
    def __init__(self,value):
        self.data = value
    def __str__(self):
        print("正在调用__str__方法,转换为普通字符串")
        s = "自定义数据%d" % self.data
        return s
  
    def __repr__(self):
        return 'MyNumber(%d)' % self.data
 
n1 = MyNumber(100)
print(str(n1))
print(repr(n1))


# 此示例示意自定义的对象转为python内键的数字类型
class MyNumber:
    def __init__(self, v):
        self.data = v
    def __repr__(self):
        return "MyNumber(%d)" % self.data
    def __int__(self):
        return int(self.data)
 
n1 = MyNumber(100.5)
n = int(n1)  # 自定义类型转为整数, 出错!!!
print(n)

str(obj) 函数调用方法说明:

  1. str(obj) 函数先查找obj.__str__()方法,调用此方法并返回结果
  2. 如果obj.__str__() 方法不存在,则调用obj.__repr__()方法并返回结果
  3. 如果obj.__repr__方法不存在,则调用object类的__repr__实例方法显示
    <__main__.MyNumber object at xxx>格式的字符串

内建函数重写

    __abs__         abs(obj) 函数调用
    __len__         len(obj) 函数调用
    __reversed__   reversed(obj) 函数调用
    __round__       round(obj) 函数调用

示例5


# 此示例示意 abs 和len方法的重写方法
 
class MyInteger:
    def __init__(self, v):
        self.data = v
 
    def __repr__(self):
        return 'MyInteger(%d)' % self.data
 
    def __abs__(self):
        '''此方法用于制定abs(obj) 函数取值时返回的结果'''
        if self.data < 0:
            # 用-self.data 创建一个新的对象返回回去
            t = MyInteger(-self.data)
            return t
        return MyInteger(self.data)
 
i1 = MyInteger(-100)
 
print(i1)  # 等同于print(str(i1)) 
n = abs(i1)
print(n)  # MyInteger(100)
 
i2 = MyInteger(200)
print(abs(i2))  # MyInteger(200)

数值转换函数重写

    __complex__     coplex(obj)  函数调用
    __int__         int(obj)  函数调用
    __float__       float(obj)  函数调用
    __bool__        bool(obj)  函数调用

示例6


# 此示例示意自定义的对象转为python内键的数字类型
class MyNumber:
    def __init__(self, v):
        self.data = v
    def __repr__(self):
        return "MyNumber(%d)" % self.data
    def __int__(self):
        return int(self.data)
 
n1 = MyNumber(100.5)
n = int(n1)  # 自定义类型转为整数, 出错!!!
print(n)

布尔测试函数重写

  • 格式:
    • def bool(self):

作用:

  • 用于bool(obj)函数取值
  • 用于if语句真值表达式中
  • 用于while语句的值表达式中

说明:

  • 1.当自定义类有__bool__(self)方法时,以此方法的返回值作为bool(obj)的返回值
    1. 当不存在__bool__(self)方法时,bool(x)返回__len__(self)方法的返回值是否为零来测试布尔值
  • 3.当再不存在__len__(self)方法时,则直接返回True

示例7:

# 此示例示意__bool__方法的重写方法及用法
 
class MyList:
    def __init__(self, iterable=()):
        self.data = [x for x in iterable]
 
    def __repr__(self):
        return "MyList(%s)" % self.data
 
    def __len__(self):
        print("__len__被调用")
        return len(self.data)
    def __bool__(self):
        '''此方法用来制定一个bool(x) 返回的规则'''
        # 如果没有任何元素返回False
        print("__bool__方法被调用")
        if len(self.data) == 0:
            return False
        for x in self.data:
            if x:
                return True
        return False
 
myl = MyList([1, -2, 3, -4])
# myl = MyList()
print(myl)
print(bool(myl))  # False
print(len(myl))
 
myl1 = MyList([0, 0.0, False, None])    
print(bool(myl1))  # False
 
myl2 = MyList([0, 1, 2])
print(bool(myl2))  # True

猜你喜欢

转载自blog.csdn.net/dirckes8813/article/details/83615988