一.继承
类相关的内置函数
- isinstance() # 判断对象所属类型,包括继承关系
- issubclass() # 判断类与类之间的继承关系
1.单继承
- 实现代码的重用,相同的代码不需要重复的编写
- 继承的概念:子类拥有父类的所有方法和属性
继承的语法:
class 类名(父类名):
pass
特点:
- 子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发
- 子类中应该编写自己的任务,封装子类特有的属性和方法
- 继承的传递性:
- 子类拥有父类以及父类的父类中封装的所有属性和方法
专业术语:
子类 | 父类 | 继承 |
派生类 | 基类 | 派生 |
2.多继承
- 子类 可以拥有 多个父类,并且具有 所有父类 的 属性 和 方法
- 语法:
class 子类名(父类名1,父类名2....):
pass
注意:如果 不同的父类 中存在 同名的方法,子类对象 在调用方法时,会调用哪一个父类中的方法呢?开发时,应该尽量避免这种容易产生混淆的情况! —— 如果 父类之间 存在 同名的属性或者方法,应该 尽量避免 使用多继承。
3.方法的重写
- 子类拥有父类的所有方法和属性
- 子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发
- 当父类的方法不能满足子类的需求时,可以对方法进行重写
重写的方法:
- 覆盖父类的方法:在子类中定义一个和父类同名的方法并且实现
- 对父类进行扩展
- 父类原本封装的方法实现 是 子类方法的一部分,就可以使用扩展的方式
- 在子类中重写父类的方法
- 在需要的位置使用 super().父类方法 来调用父类方法的执行
- 代码其他的位置针对子类的需求,编写子类特有的代码实现
调用父类方法的另外一种方式: 父类名.方法(self)
4.父类的 私有属性和私有方法
- 私有属性、方法 是对象的隐私,不对外公开,外界以及子类都不能直接访问 __属性名\方法
- 私有属性、方法通常用于做一些内部的事情
- 子类对象 不能 在自己的方法内部,直接 访问 父类的 私有属性 或 私有方法
- 子类对象 可以通过 父类 的 公有方法 间接 访问到 私有属性 或 私有方法
5.Python 中的 MRO —— 方法搜索顺序(多继承)
Python 中针对 类 提供了一个 内置属性 __mro__ 可以查看 方法 搜索顺序MRO 是 method resolution order ,主要用于 在多继承时判断 方法、属性的调用路径
- print(C.__mro__)
- 在搜索方法时,是按照 __mro__ 的输出结果 从左至右 的顺序查找的
- 如果在当前类中 找到方法,就直接执行,不再搜索
- 如果 没有找到,就查找下一个类 中是否有对应的方法,如果找到,就直接执行,不再搜索
- 如果找到最后一个类,还没有找到方法,程序报错
6.新式类:以 object 为基类的类,推荐使用 --遵循广度优先
经典类:不以 object 为基类的类,不推荐使用 --遵循深度优先
如果没有父类,建议统一继承自 object
class 类名(object):
pass
这里由于python中木有接口的概念所以制定一个规范抽象类、接口类
二. 多态
python 中处处是多态
- python 不管什么类型,传入函数,封装到对象中都可以
- 定义:父类的同一种动作或者行为,在不同的子类上有不同的实现。
- 作用:
- 1. 继承将相关概念的共性进行抽象,多态在共性的基础上,体现类型的个性化(一个行为有不同的实现)。
- 2. 增强程序扩展性,体现开闭原则。重写子类实现了父类中相同的方法(方法名、参数),在调用该方法时,实 际调用的是子类的方法。
三.封装
- 封装 是面向对象编程的一大特点
- 面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中
- 外界 使用 类 创建 对象,然后 让对象调用方法
- 对象方法的细节 都被 封装 在 类的内部
广义封装:实例化一个对象,给对象空间封装一些属性
狭义的封装:私有化,只能在类的内部访问
私有成员:私有静态字段、私有方法、私有对象属性
代码解释·:
class A:
company_name = 'rose' # 静态变量(静态字段)
__iphone = '179xxxxxxx' # 私有静态变量(私有静态字段)
# 第二部分 方法部分
def __init__(self,name,age): #特殊方法
self.name = name #对象属性(普通字段)
self.__age = age # 私有对象属性(私有普通字段)
def func1(self): # 普通方法
pass
def __func(self): #私有方法
print(666)
@classmethod # 类方法
def class_func(cls):
""" 定义类方法,至少有一个cls参数 """
print('类方法')
@staticmethod # 静态方法 23
def static_func():
""" 定义静态方法 ,无默认参数"""
print('静态方法')
@property # 属性
def prop(self):
pass
1.面向对象的私有与公有
1)对于每一个类的成员而言都有两种形式
- 公有成员,在任何地方都能访问
- 私有成员,只有在类的内部才能方法
2)私有成员和公有成员的访问限制不同:
静态字段(静态变量)
- 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
- 私有静态字段:仅类内部可以访问;
例子:
1.
class Ke:
name = "公有静态字段"
def keke(self):
print(Ke.name)
class Tou(Ke):
def show(self):
print(Ke.name)
a=Ke()
a.keke()
a_1=Tou()
a_1.show()
公有静态字段
公有静态字段
2.
class Ke:
__name = "私有静态字段"
def keke(self):
print(Ke.__name)
class Tou(Ke):
def show(self):
print(Ke.__name)
a=Ke()
a.keke()
a_1=Tou()
a_1.show()
私有静态字段
然后报错:私有静态字段不可在派生类中可以访问
当然:
print(a._Ke__name)
非要访问私有成员的话,可以通过 对象._类__属性名,但是绝对不允许!!!
(为什么可以通过._类__私有成员名访问呢?因为类在创建时,如果遇到了私有成员(包括私有静态字段,私有普通字段,私有方法)它会将其保存在内存时自动在前面加上_类名.)
3.注意:普通字段:
- 公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问
- 私有普通字段:仅类内部可以访问;
- 公有方法:对象可以访问;类内部可以访问;派生类中可以访问
- 私有方法:仅类内部可以访问;
2面向对象的成员
字段
- 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存位置不同,
- 普通字段属于对象
- 静态字段属于类
代码:
class Province:
# 静态字段
country = '中国'
def __init__(self, name):
# 普通字段
self.name = name
#直接访问普通字段
obj = Province('山西省')
print (obj.name)
#直接访问静态字段
print(Province.country)
注意:
- 静态字段在内存中只保存一份
- 普通字段在每个对象中都要保存一份
- 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段