【Python】类的封装、继承 & 多态

类的基本使用

【Python】类的基本使用

类的封装

封装的操作

用于设置对象的私有数据 ( 属性 ) / 行为 ( 方法 ) ,使其不能被修改。

  • 在定义类时,在 数据 ( 属性 ) / 行为 ( 方法 ) 前面加两个下划线,表示对该 属性 / 方法 进行隐藏,只有类的内部成员可以直接调用,一般情况下外部无法访问
  • 在定义类时,这种 __ 数据名 会被转化为 _ 类名 __ 数据名,所以在类的外面,我们还是可以通过 对象名 . _ 类名 __ 数据名 的形式强行访问私有数据,但是一般不推荐这样使用
class Dog():
    def __init__(self, DogName):
        self.__name = DogName  # 定义私有数据

    def set_name(self, name):
        self.__name = name

    def __get_name(self):  # 定义私有函数
        return self.__name

    def get_fun(self):
        return self.__get_name()


dog1 = Dog('中华田园犬')
print(dog1.get_fun())
dog1.set_name('二哈')
print(dog1.get_fun())

print(f'强行调用私有函数输出{dog1._Dog__get_name()}')  # 不推荐强行调用
print(f'强行调用私有数据输出{dog1._Dog__name}')
# ---------- 输出 ----------
# 中华田园犬
# 二哈
# 强行调用私有函数输出二哈
# 强行调用私有数据输出二哈
  • 一般我们会在数据名前加一个下划线,来表示这是一个私有数据。就是说它其实还是一般的数据,只是我们以这种方式来告诉别人这是私有数据,不希望被修改。

装饰器的使用

让我们能以调用数据的方式调用行为函数。方便我们后续的操作。

装饰器 @property

一般用于查询私有数据。我们可以在类的函数前使用 @property ,property装饰器会将行为 ( 方法 ) 转换为同名的数据 ( 属性 ) 。这样我们就可以用访问数据 ( 属性 ) 的形式调用行为 ( 方法 ) 。

class Dog():
    def __init__(self, dogName):
        self.__name = dogName

    @property
    def name(self):
        print('执行property后面的函数', end='   ')
        return self.__name


dog1 = Dog('little_black')
print(dog1.name)
# ---------- 输出 ----------
# 执行property后面的函数   little_black

装饰器 @函数名 . setter

一般用于修改 @property 修饰的函数的值。在进行修改操作的函数前面添加 @函数名 . setter 装饰器,该函数就会转化为同名属性,对该属性进行赋值,就是修改 @property 后面的函数的值。

  • 装饰器修饰的函数名建议保持一致
class Dog():
    def __init__(self, dogName):
        self.__name = dogName

    @property
    def name(self):
        print('执行property后面的函数', end='  ')
        return self.__name

    @name.setter
    def name(self, newName):
        print('执行setter后面的函数')
        self.__name = newName


dog1 = Dog('little_black')
print(dog1.name)
dog1.name = 'big_dog'
print(dog1.name)
# ---------- 输出 ----------
# 执行property后面的函数  little_black
# 执行setter后面的函数
# 执行property后面的函数  big_dog

装饰器@函数名 . deleter

一般用于删除 @property 后面的函数的值。在进行删除操作的函数前面添加 @函数名 . deleter 装饰器,该函数就会转化为同名属性,对该属性进行删除操作,就是删除 @property 后面的函数的值。

  • 装饰器修饰的函数名建议保持一致
class Dog():
    def __init__(self, dogName):
        self.__name = dogName

    @property
    def name(self):
        print('执行property后面的函数', end='  ')
        return self.__name

    @name.deleter
    def name(self):
        print('执行deleter后面的函数')
        del self.__name


dog1 = Dog('little_black')
print(dog1.name)
del dog1.name
# ---------- 输出 ----------
# 执行property后面的函数  little_black
# 执行deleter后面的函数

类的继承

  • 特点:可以提高代码的重复利用率;符合 OCP 原则 (在不修改原代码的情况下,增加功能)。
  • 通过继承,我们可以获取到其他类的属性和方法

继承的操作

  • 在定义类的时候,在类名后面的括号里,填写当前类的父类 ( 超类、基类 )。这样当前类就可以调用父类里面的属性和行为了。
class Animals():
    name = 'animals'
    def run(self):
        print('Animals can run')

class Dog(Animals):
    pass

dog1 = Dog()
print(dog1.name, end=':')
dog1.run()
# ---------- 输出 ----------
# animals:Animals can run
  • 如果当前类与父类都有一样的行为 / 数据,当前类的值会覆盖父类的值
class Animals():
    name = 'animals'
    def run(self):
        print('Animals can run')

class Dog(Animals):
    name = 'dog'
    def run(self):
        print('Dog can run')

dog1 = Dog()
print(dog1.name, end=':')
dog1.run()
# ---------- 输出 ----------
# dog:Dog can run
  • 多重继承,一般不推荐用;因为开发中要求解耦合,即不希望不同的代码之间产生太多的牵连。
    • 子类对象调用的函数,会先在子类里面找;如果没有,就到第一个继承的父类里面找;如果再没有就到下一个继承的父类里面找…
class Father():
    def dancing(self):
        print('dadadada', end='  ')

class Mother():
    def singing(self):
        print('lalalala')

class Son(Father, Mother):
    pass

boy = Son()
boy.dancing()
boy.singing()
# ---------- 输出 ----------
# dadadada  lalalala

issubclass(class1, class2)

用于判断 class1 是否是 class2 的子类;若是则返回 True,否则返回 False

  • 所有类的父类都是 object
class Animals(object):
    pass

class Dog(Animals):
    pass

print(issubclass(Dog, Animals), end='  ')
print(issubclass(Animals, object))

print(issubclass(type, object), end='  ')
print(issubclass(int, object))
# ---------- 输出 ----------
# True  True
# True  True

className . __ bases __

会返回该类的所有父类

class Father(object):
    pass

class Son(Father):
   pass

print(Son.__bases__)
# ---------- 输出 ----------
# (<class '__main__.Father'>,)

super ( Class, self ) 函数

  • Python 3 可以直-接使用 super().xxx 代替 super ( Class, self ) . xxx

单继承

  • 用于在当前类的函数中调用父类中的同名函数
  • super ( ) :找到该类的父类,把该类的对象转换为父类的对象
  • super ( ) 调用的函数不用写 self 形参
class Animals(object):
    def __init__(self, AnimalName):
        print('enter Animals-init')
        self.name = AnimalName
        print('leave Animals-init')

    def run(self, object1):
        print('enter Animals-run')
        print('%s can run' %object1)
        print('leave Animals-run')

        
class Dog(Animals):
    def __init__(self, DogName, DogAge):
        print('enter Dog-init')
        self.age = DogAge
        super(Dog, self).__init__(DogName)
 # 等价于Animals.__init__(self, DogName)
        print('leave Dog-init')

    def run(self, object1):
        print('enter Dog-run')
        super(Dog, self).run(object1)
 # 等价于Animals.run(self, object1)
        print('leave Dog-run')


dog1 = Dog('哈士奇', 5)
print(dog1.name, dog1.age)
dog1.run('二哈')
# ---------- 输出 ----------
# enter Dog-init
# enter Animals-init
# leave Animals-init
# leave Dog-init
# 哈士奇 5
# enter Dog-run
# enter Animals-run
# 二哈 can run
# leave Animals-run
# leave Dog-run

多继承

  • 先继承的父级,先执行;后继承的父级,后执行。
class Grandfather(object):
    def __init__(self):
        print('enter Grandfather')
        print('leave Grandfather')

class Father(Grandfather):
    def __init__(self):
        print('enter Father')
        super(Father, self).__init__()
        print('leave Father')

class Mother(Grandfather):
    def __init__(self):
        print('enter Mother')
        super(Mother, self).__init__()
        print('leave Mother')

class Son(Father, Mother):
    def __init__(self):
        print('enter Son')
        super(Son, self).__init__()
        print('leave Son')

boy = Son()
# ---------- 输出 ----------
# enter Son
# enter Father
# enter Mother
# enter Grandfather
# leave Grandfather
# leave Mother
# leave Father
# leave Son

等价于以下写法,但是这种写法会导致父类被调用多次,而 super ( ) 可以减少这样的开销。

class Grandfather(object):
    def __init__(self):
        print('enter Grandfather')
        print('leave Grandfather')

class Father(Grandfather):
    def __init__(self):
        print('enter Father')
# 等价于super(Father, self).__init__()
        Grandfather.__init__(self)
        print('leave Father')

class Mother(Grandfather):
    def __init__(self):
        print('enter Mother')
# 等价于super(Mother, self).__init__()
        Grandfather.__init__(self)
        print('leave Mother')

class Son(Father, Mother):
    def __init__(self):
        print('enter Son')
        Father.__init__(self)
        Mother.__init__(self)
# 等价于super(Son, self).__init__()
        print('leave Son')
        
boy = Son()
# ---------- 输出 ----------
# enter Son
# enter Father
# enter Grandfather
# leave Grandfather
# leave Father
# enter Mother
# enter Grandfather
# leave Grandfather
# leave Mother
# leave Son

类的多态

具有不同功能的函数,可以使用相同的函数名;这样就可以用一个函数名,调用不同功能的函数。

对象之间没有继承关系的情况

class Dog(object):
    def run(self):
        print('Dog is running')

class Cat(object):
    def run(self):
        print('Cat is running')

class Lion(object):
    def run(self):
        print('Lion is running')

def run(obj):
    obj.run()

dog1 = Dog()
cat1 = Cat()
lion1 = Lion()
run(dog1)
run(cat1)
run(lion1)
# ---------- 输出 ----------
# Dog is running
# Cat is running
# Lion is running

对象之间有继承关系的情况

class Grandfather(object):
    def __init__(self, money):
        self.money = money

class Father(Grandfather):
    def __init__(self, money, job):
        self.job = job
        super(Father, self).__init__(money)

class Mother(Grandfather):
    def __init__(self, money, job):
        self.job = job
        super(Mother, self).__init__(money)

def job(obj):
    print(obj.job, end='   ')

def money(obj):
    print(obj.money, end='   ')

person1 = Grandfather(3000)
person2 = Father(10000, 'programmer')
person3 = Mother(8000, 'teacher')
job(person2)
job(person3)
money(person1)
money(person2)
money(person3)
# ---------- 输出 ----------
# programmer   teacher   3000   10000   8000   
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JS.Huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值