面向对象特性

130 阅读4分钟

面向对象特性

  • 封装
  • 继承
  • 多态

封装

  • 将属性和⽅法书写到类的⾥⾯的操作即为封装
  • 封装可以为属性和⽅法添加私有权限

继承

  • 在生活中,继承指的是子女继承父辈的财产
  • 在python面向对象中的继承指的是多个类之间的所属关系,指子类默认继承父类的所有属性和方法。
# 例:
class Father(object):
    def __init__(self):
        self.color = "red"

    def demo(self):
        print(self.color)


class Son(Father):
    pass

son = Son()
print(son.color)
son.demo()

在python中所有类默认继承object类,object类是顶级类或基类,其他类称为派生类。

单继承

场景:枯荣大师只有一个弟子叫张三,他马上要与世长辞,现在,他想把自己的功夫传授给自己唯一的关门弟子

class Kurong(object):
    def __init__(self):
        self.kurong_kongfu = "一阳指"
    
    def demo(self):
        print("枯荣大师的功夫:{}".format(self.kurong_kongfu))

class Zhangsan(Kurong):
    pass

zhangsan = Zhangsan()
print(zhangsan.kurong_kongfu)
zhangsan.demo()
多继承
  • 一个类可以继承多个父类。

场景:张三不满足枯荣大师的功夫,现在他又拜在了张三丰的门下,想学太极**

class Kurong(object):
    def __init__(self):
        self.kurong_kongfu = "一阳指"

    def demo1(self):
        print(f"枯荣大师的功夫:{self.kurong_kongfu}")


class Zhangsanfeng(object):
    def __init__(self):
        self.sanfeng_kongfu = "太极"

    def demo2(self):
        print(f"张三丰的功夫:{self.sanfeng_kongfu}")


class Zhanfsan(Kurong, Zhangsanfeng):
    def __init__(self):
        Kurong.__init__(self)
        Zhangsanfeng.__init__(self)

    def demo3(self):
        print(f"张三的功夫:{self.kurong_kongfu},{self.sanfeng_kongfu}")


zs = Zhanfsan()
zs.demo3()
子类重写父类的方法和属性

场景:张三觉得师傅的功夫都有一定的不足,决定改善师傅的功夫

class Kurong(object):
    def __init__(self):
        self.kongfu_kr = "一阳指"

    def demo1(self):
        print(f"枯荣大师的功夫:{self.kongfu_kr}")


class Sanfeng(object):
    def __init__(self):
        self.kongfu_sanfeng = "太极"

    def demo2(self):
        print(f"张三丰的功夫:{self.kongfu_sanfeng}")


class Zhangsan(Kurong, Sanfeng):
    def __init__(self):
        Sanfeng.__init__(self)
        Kurong.__init__(self)
        self.kongfu_sanfeng = "狮子吼"  # 修改属性。
        self.kongfu_kr = "六脉神剑"

    def demo1(self):  # 修改枯荣大师的功夫
        print(f"张三修改师傅枯荣大师的功夫为:{self.kongfu_kr}")

    def demo2(self):  # 修改张三丰的方法
        self.kongfu_sanfeng = "狮子吼"
        print(f"张三修改师傅张三丰的功夫为:{self.kongfu_sanfeng}")


zs = Zhangsan()
print(zs.kongfu_sanfeng)
print(zs.kongfu_kr)
zs.demo1()
zs.demo2()
子类调用父类的方法和属性。
  • 同名的情况下,只能使用子类里面的方法
class Kr(object):
    def __init__(self):
        self.kf_kr = "一阳指"

    def demo_kr(self):
        print(f"枯荣大师的功夫:{self.kf_kr}")


class Zsf(object):
    def __init__(self):
        self.kf_zsf = "太极"

    def demo_zsf(self):
        print(f"张三丰的功夫为:{self.kf_zsf}")


class Zs(Zsf, Kr):
    def __init__(self):
        """修改父类属性"""
        self.kf_zsf = "狮子吼"
        self.kf_kr = "六脉神剑"

    def demo_zs(self):
        print(f"张三修改师傅的功夫为:{self.kf_kr},{self.kf_zsf}")

    """子类调用父类的方法需要在括号写入 self ."""

    def kr_zs(self):
        Kr.__init__(self)
        Kr.demo_kr(self)

    def zsf_zs(self):
        Zsf.__init__(self)
        Zsf.demo_zsf(self)


zs = Zs()
zs.demo_zs()
zs.kr_zs()
zs.zsf_zs()
多层继承

场景:多年之后,张三老了,想把自己的毕生所学,传给李四

class Lisi(Zs):
    def __init__(self):
        Zs.__init__(self)

    def demo_zs(self):
        print(f"李四的功夫为:{self.kf_kr} {self.kf_zsf}")


li = Lisi()
li.demo_zs()

super():调用父类方法

class Kr(object):
    def __init__(self):
        self.kongfu_kr = "一阳指"

    def kongfu_kr(self):
        print(f"枯荣大师的功夫:{self.kongfu_kr}")


class Zsf(object):
    def __init__(self):
        self.kongfu_zsf = "太极"

    def kongfu_zsf(self):
        print(f"张三丰的功夫:{self.kongfu_zsf}")


class Zs(Kr, Zsf):
    def __init__(self):
        super().__init__()
        self.kongfu_zsf = "狮吼功"
        self.kongfu_kr = "六脉神剑"

    def oldkongfu_zs(self):
        super().kongfu_zsf()
        super().kongfu_kr()

    def new_konggu_zs(self):
        print(f"张三自创的功夫:{self.kongfu_zsf},{self.kongfu_kr}")


zs = Zs()
zs.new_konggu_zs()
zs.oldkongfu_zs()

私有属性和方法

  • 私有属性只能在类中进行访问和调用。
class Kr(object):
    def __init__(self):
        self.kr_kongfu = "一阳指"
        self.__kr_age = "100"

    def __demo_age(self):
        print(f"枯荣大师的年龄为:{self.__kr_age}")

    def kongfu(self):
        print(f"枯荣大师的功夫:{self.kr_kongfu}")

kr = Kr()
# print(kr.__kr_age)  # 报错
print(kr.kr_kongfu)
kr.kongfu()
# kr.__demo_age()  # 报错

获取和修改私有属性和方法

  • 一般来说用get_XX()来获取私有属性,用set_XX()来修改私有属性
class Zsf(object):
    def __init__(self):
        self.zsf_kongfu = "太极"
        self.__zsf_age = "200"

    def get_zsf_age(self):
        return self.__zsf_age

    def set_zsf_age(self):
        self.__zsf_age = "100"

zsf = Zsf()
print(zsf.get_zsf_age())
zsf.set_zsf_age()
print(zsf.get_zsf_age())

多态

  • 多态是⼀种使⽤对象的⽅式,⼦类重写⽗类⽅法,调⽤不同⼦类对象的相同⽗类⽅法,可以产⽣不同的执⾏结果。
class Father(object):
    def func(self):
        print("下达命令,出兵剿匪。")


class Son1(Father):
    def func(self):
        print("正面进攻")


class Son2(Father):
    def func(self):
        print("背后偷袭")

father = Father()
son1 = Son1()
son2 = Son2()
father.func()
son1.func()
son2.func()

类属性和实例属性

  • 类属性就是类对象所拥有的属性,它被 该类的所有实例对象 所共有。
  • 实例属性就是__init__()中定义的属性

类方法和静态方法

  • 需要⽤装饰器 @classmethod 来标识其为类⽅法
  • 当⽅法中 既不需要使⽤实例对象(如实例对象,实例属性),也不需要使⽤类对象 (如类属性、类⽅法、创建实例等)时,定义静态⽅法
类方法

对于类⽅法,第⼀个参数必须是类对象,⼀般以cls 作为第⼀个参数。

class Demo():
    __num = 10
    @classmethod
    def get(cls):
        return cls.__num

f = Demo()
print(f.get())
静态方法
class Demo(object):

    @staticmethod
    def get_info():
        print("我是一个静态方法")

func = Demo()
func.get_info()