1 面向对象进阶
1.1 继承
1.1.1 类的继承
继承是一种关系,类与类之间描述什么是什么的关系。
继承父类,则可以使用父类的所有属性和方法。
class ParentClass1():
pass
class ParentClass2():
pass
class SubClass(ParentClass1,ParentClass2):
pass
1.1.2 类的派生
子类继承父类的同时,拥有自己的init方法。
也就是子类中出现了父类中不存在的内容。
class ParentClass1():
def __init__(self,name):
pass
class SubClass(ParentClass):
def __init__(self,age):
# 1. ParentClass1.__init__(self,name)
# 2. super(SubClass,self).__init__(name)
self.age = age
如果子类中出现了与父类一模一样的名字,则会优先使用子类的名字,就出现了覆盖的问题。
1.1.3 类的组合
类或者对象可以引用/当做参数传入/当做返回值/当做容器元素,类似于函数对象。
也是一种关系,描述什么有什么的关系。
class ParentClass1():
count = 0
def __init__(self,name):
pass
class SubClass(ParentClass):
def __init__(self,age):
self.age = age
pc = ParentClass1()
sc = SubClass()
sc.parent_class = pc # 组合
sc.parent_class.count # 0
组合和继承都是为了提高代码的复用性。
1.1.4 菱形继承问题
新式类:
继承object的类,python3中全是新式类
经典类:
没有继承object的类,只有python2中有
在菱形继承的时候,
新式类是广度优先(老祖宗最后找);
经典类深度优先(一路找到底,再找旁边的)
可以使用mro方法来查看类的继承顺序。
1.5 多态与多态性
多态:
一种事物具备多种形态,并且多个不同类型的对象可以响应同一个方法调用。
多态性:
不是一种特殊的语法,只要实现了多个不同类型的对象可以响应同一个方法调用,那就称之为多态性。
其实就是面向对象对于扩展性的体现。
# 多态
import abc
class Animal(metaclass=abc.ABCmeta):
@abc.abstractmethod
def eat():
print('eat')
class People(Animal):
def eat():
pass
class Pig(Animal):
def eat():
pass
def run():
pass
class Dog(Animal): # 报错
def run():
pass
# 多态性
peo = People()
peo.eat()
peo1 = People()
peo1.eat()
pig = Pig()
pig.eat()
def func(obj):
obj.eat()
class Cat(Animal):
def eat():
pass
cat = Cat()
func(cat)
鸭子类型:
只要长得像鸭子,叫的像鸭子,游泳像鸭子,就是鸭子.
大家默认都实现相同的方法,不需要从语法上去限制。
1.2 封装
1.2.1 类的封装
封装:
对外部隐藏内部实现细节,提供调用的接口。
目的:
- 保证数据安全
- 隔离复杂度
原理: 在读取类中的代码时,会将带有双下划线的名字换成_类名__属性 这样的格式
class Foo():
__count = 0
def get_count(self):
return self.__count
f = Foo()
f.__count # 报错
f._Foo__count # 不能这样做
1.2.2 类的property特性
@property把方法变成属性引用。需要注意的是属性名必须和@property装饰的名称一致。
@属性名.setter 对属性进行修改
@属性名.deleter 对属性进行删除
@属性名.getter 相当于@property
class People():
def __init__(self,height,weight):
self.height = height
self.weight = weight
@property
def bmi(self):
return weight/(height**2)
@bmi.setter
def bmi(self,value)
print('setter')
@bmi.deleter
def bmi(self):
print('delter')
peo = People
peo.bmi
1.2.3 类与对象的绑定方法和非绑定方法
对象的绑定方法:
没有任何装饰器装饰的方法就是对象的绑定方法, 类能调用, 但是必须得手动传参给self
类的绑定方法:
被 @classmethod 装饰器装饰的方法是类的绑定方法,参数写成cls, cls是类本身, 对象也能调用, 参数cls还是类本身
非绑定方法:
被 @staticmethod 装饰器装饰的方法就是非绑定方法, 就是一个普通的函数