python面向对象-三大特性

封装

使用起来更加方便:把很多相关的功能封装成一个整体
保证数据安全:私有属性 只读 拦截写操作
利于代码维护:功能代码需要维护,直接修改类内部的代码即可 只要保证接口名称不变,外界不需要做出任何代码修改

继承

一个类拥有另一个类资源使用权 不是资源的复制

  • 语法格式
# 2、继承:一个类用户另一个类的资源方式之一,不是复制资源而是资源使用权,资源是指非私有的属性和方法
#          单继承/多继承
class Animal:
    # 设置不同权限的属性和方法,看子类能否访问
    a = 1
    _b = 2
    __c = 3
    def t1(self):
        print("t1")

    def _t2(self):
        print("t2")
    def __t3(self):
        print("t3")
    def __init__(self):  # 内置方法
        print("init,animal")
    pass
class xxxx:
    pass

class Dog(Animal, xxxx):
    pass
print(Dog.__bases__)  # 查看父类 (, )
print(Animal.__bases__)  # 查看父类(,)
# type是创建实例化的顶端和object是继承关系
# object是type实例化出来的
# type是继承object
print(Dog.__class__)  # 元类
print(object.__class__)  # 元类
print(int.__bases__)  # (,)
print(float.__bases__)  # (,)
print(bool.__bases__)  # (,)

python面向对象-三大特性_第1张图片
对资源的影响

# 继承-资源
# 私有属性和方法不可以访问
class Animal:
    # 设置不同权限的属性和方法,看子类能否访问
    a = 1
    _b = 2
    __c = 3
    def t1(self):
        print("t1")
    def _t2(self):
        print("t2")
    def __t3(self):
        print("t3")
    def __init__(self):  # 内置方法
        print("init,animal")
class Person(Animal):
    def test(self):
        print(self.a)
        print(self._b)
        # print(self.__c)

        self.t1()
        self._t2()
        # self.__t3()
        self.__init__()
p = Person()
p.test()

常见的形态

# 三种不同继承形态,资源调用标准
# 单继承:先自己找,再往继承的顺序上找
class C:
    age = "C"
    pass
class B(C):
    age = "B"
    pass
class A(B):
    age = "A"
    pass
import inspect
print(inspect.getmro(A))
# A->B->C
print(A.age)

# 不重叠多继承:先自己找,先左侧继承找,再沿着右侧继承链找
class E:
    age = "E"
    pass
class D:
    age = "D"
    pass
class C(E):
    age = "C"
    pass
class B(D):
    age = "B"
    pass
class A(B, C):
    age = "A"
    pass
import inspect
print(inspect.getmro(A))
# A->B->D->C->E
print(A.age)

# 有重叠的多继承:先自己找,先左侧,再右侧找,再去父类找,从上往下,遵循重写可用原则
class D:
    age = "D"
    pass
class C(D):
    age = "C"
    pass
class B(D):
    age = "B"
    pass
class A(B, C):
    age = "A"
    pass
import inspect
print(inspect.getmro(A))
# A->B->C->D
print(A.age)

方法解析顺序

  • MRO
    经典类 原则 深度优先(从左往右) 在有重叠多继承,违背重写可用原则
    python面向对象-三大特性_第2张图片
    顺序:A->B->D ->C但是 C的run()不可用
    新式类:在深度优先优化了一部分 但有可能会违背局部优先原则
  • C3 A->B ->C->D
# 新式类:C3算法
class D:
    age = "D"
    pass
class C(D):
    age = "C"
    pass
class B(D):
    age = "B"
    pass
class A(B, C):
    age = "A"
    pass
import inspect
print(inspect.getmro(A))
# A->B->C->D
print(A.age)

资源的累加

子类相比父类多一些特有资源

# 资源的累加
# 类里面资源:属性(类属性和实例属性) 方法(类方法、实例方法、静态方法)
class B:
    a = 1  # 类属性
    def __init__(self):  # 实例属性
        self.b = 2
    def t1(self):   # 实例方法
        print("t1")
    @classmethod  # 类方法
    def t2(cls):
        print("t2")
    @staticmethod  # 静态方法
    def t3():
        print("t3")
class A(B):
    c = 3
    def __init__(self):  # 实例属性
        self.e = 2
    def tt1(self):   # 实例方法
        print("t1")
    @classmethod  # 类方法
    def tt2(cls):
        print("t2")
    @staticmethod  # 静态方法
    def tt3():
        print("t3")
    pass
# 访问类资源通过类访问,访问实例资源通过实例访问
a_obj = A()
print(A.a)
print(A.c)
# print(a_obj.b)  # 自己定义了实例初始化方法,不会再调用B的方法,也没有b资源会报错,如果自己没有实例初始化方法不会报错
a_obj.t1()
A.t2()
a_obj.tt1()
a_obj.tt1()
A.tt2()
a_obj.tt1()

# super:起着代理的作用,帮助我们沿着MRO链条找到下一级节点,去调用相应的方法(不代表父类 菱形继承)
# super(参数1,[,参数2])
# 沿着参数2的MRO链条,找到参数1的下一个节点
# 方法使用参数2进行传参调用

# A->B->Object
class B:
    a = 1  # 类属性
    def __init__(self):  # 实例属性
        self.b = 2
    def t1(self):   # 实例方法
        print("t1")
    @classmethod  # 类方法
    def t2(cls):
        print("t2")
    @staticmethod  # 静态方法
    def t3():
        print("t3")
class A(B):
    c = 3
    def __init__(self):  # 实例属性
        # super(A, self).__init__()  # 字典里面既包含b也包含e
        super().__init__() # 简化
        self.e = 2

    def tt1(self):   # 实例方法
        print("t1")
    @classmethod  # 类方法
    def tt2(cls):
        print("t2")
    @staticmethod  # 静态方法
    def tt3():
        print("t3")
    pass
a = A()
print(a.__dict__)

多态

关注点在于对象的行为和属性而不是类型

# 在python当中,没有真正意义上的多态,也不需要多态
# 抽象类:一个抽象出来的类,不能直接创建实例的类,创建会报错
# 抽象方法,抽象出来的方法,不具备具体实现,不能直接调用
# python中实现,import abc
# 设置类的元类为:abc.ABCMeta
# 使用装饰器修饰抽象方法
import abc
class Animal(object, metaclass=abc.ABCMeta):  # 抽象方法必须在继承的类中实现
    @abc.abstractclassmethod
    def jiao(self):
        pass
class Dog(Animal):
    def jiao(self):  # 实现抽象方法
        print("汪汪汪")
    pass

d = Dog()
d.jiao()

综合案列

# 综合案例
# 定义三个类:人、小狗、小猫
class Dog:
    # 实例属性,创建一个小狗
    def __init__(self, name, age=1):
        self.name = name
        self.age = age
    def eat(self):
        print("%s在吃饭" % self)

    def play(self):
        print("%s在玩" % self)

    def sleep(self):
        print("%s在睡觉" % self)

    def work(self):
        print("%s在看家" % self)

    def __str__(self):  # self对象本身字符串描述
        return "名字是{},年龄{}岁的小狗".format(self.name, self.age)

class Cat:
    # 实例属性,创建一个小狗
    def __init__(self, name, age=1):
        self.name = name
        self.age = age
    def eat(self):
        print("%s在吃饭" % self)

    def play(self):
        print("%s在玩" % self)

    def sleep(self):
        print("%s在睡觉" % self)

    def work(self):
        print("%s在捉老鼠" % self)

    def __str__(self):  # self对象本身字符串描述
        return "名字是{},年龄{}岁的小猫".format(self.name, self.age)

class Person:
    # 实例属性,创建一个小狗
    def __init__(self, name, pets, age=1):  # 一般情况把有默认值的参数放在最后,防止参数错位
        self.name = name
        self.age = age
        self.pets = pets
    def eat(self):
        print("%s在吃饭" % self)

    def play(self):
        print("%s在玩" % self)

    def sleep(self):
        print("%s在睡觉" % self)

    def yangPets(self):
        for pet in self.pets:
            pet.eat()
            pet.play()
            pet.sleep()
    def make_pet_work(self):
        for pet in self.pets:
            pet.work()

    def __str__(self):  # self对象本身字符串描述
        return "名字是{},年龄{}岁的人".format(self.name, self.age)

# d1 = Dog("小黑")
# d2 = Dog("小白", 18)
# c = Cat("小红")
# p = Person("杨柳", [d1, c], 22)
# p.yangPets()
# p.make_pet_work()


# 使用继承特性
class Animal:
    def __init__(self, name, age=1):
        self.name = name
        self.age = age
    def eat(self):
        print("%s在吃饭" % self)

    def play(self):
        print("%s在玩" % self)

    def sleep(self):
        print("%s在睡觉" % self)


class Dog(Animal):
    def work(self):
        print("%s在看家" % self)

    def __str__(self):  # self对象本身字符串描述
        return "名字是{},年龄{}岁的小狗".format(self.name, self.age)

class Cat(Animal):
    def work(self):
        print("%s在捉老鼠" % self)

    def __str__(self):  # self对象本身字符串描述
        return "名字是{},年龄{}岁的小猫".format(self.name, self.age)

class Person(Animal):
    def __init__(self, name, pets, age=1):  # 在子类里面使用父类的某些资源使用super
        super().__init__(name, age)  # 先调用Person的下一个节点Animal的
        self.pets = pets
    def yangPets(self):
        for pet in self.pets:
            pet.eat()
            pet.play()
            pet.sleep()
    def make_pet_work(self):
        for pet in self.pets:
            pet.work()

    def __str__(self):  # self对象本身字符串描述
        return "名字是{},年龄{}岁的人".format(self.name, self.age)

d1 = Dog("小黑")
d2 = Dog("小白", 18)
c = Cat("小红")
p = Person("yl", [d1, c], 22)
p.yangPets()
p.make_pet_work()



你可能感兴趣的:(python学习)