封装
使用起来更加方便:把很多相关的功能封装成一个整体
保证数据安全:私有属性 只读 拦截写操作
利于代码维护:功能代码需要维护,直接修改类内部的代码即可 只要保证接口名称不变,外界不需要做出任何代码修改
继承
一个类拥有另一个类资源使用权 不是资源的复制
# 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__) # (,)
# 继承-资源
# 私有属性和方法不可以访问
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)
方法解析顺序
# 新式类: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()