一、面向对象
核心“对象”就是指特征与技能的结合体,具有上帝思维方式
优点:可扩展性强,缺点:编程的复杂度高于过程
在定义类的阶段会立刻执行类体内的代码,然后将产生的名字存放于类的名称空间中
实例化做了三件事
1、产生一个空对象
2、自动触发类内部__init__函数的执行
3、将空对象,以及调用类括号内传入的参数,一同传给__init__,为对象定制独有的属性
继承一种新建类的方式,在python中支持一个儿子继承多个爹
新建的类称为子类或派生类,父类又可以称为基类或者超类
class ParentClass1:
pass
class ParentClass2:
pass
class Subclass1(ParentClass1):
pass
class Subclass2(ParentClass1,ParentClass2):
pass
# print(Subclass1.__bases__)
print(Subclass2.__bases__)
继承是类与类之间的关系,需要先抽象再继承
派生:子类定义自己新的属性,如果与父类同名,以子类为准
在子类派生出的新方法中重用父类的功能
方式一:指名道姓调用,当函数用
super()的返回值是一个特殊的对象,该对象专门用来调用父类中的属性
新式类:
继承object的类,以及该类的子类,都是新式类
如果一个类没有指定继承的父类,默认就继承object
经典类(只在python2才区分经典类与新式类)
没有继承object的类,以及该类的子类,都是经典类
在菱形继承的背景下,查找属性
1、经典类:深度优先
2、新式类:广度优先
super()会严格按照mro列表从当前查找到的位置继续往后查找
class A:
def test(self):
print('A.test')
super().f1()
class B:
def f1(self):
print('from B')
class C(A,B):
pass
c=C()
print(C.mro()) #C->A->B->object
c.test()
解决类与类之间代码冗余问题两种解决方案:
1继承是描述的是类与类之间,什么是什么的关系
2、组合:描述的是类与类之间的关系,是一种什么有什么关系
一个类产生的对象,该对象拥有一个属性,这个属性的值是来自另一个类的对象
封装就是把一堆属性存起来,封装的概念就把这些属性给隐藏起来
强调:封装单从字面意思去看等同于隐藏,但其实封装绝对不是单纯意义的隐藏
1、其实这种隐藏只是一种语法上的变形,对外不对内
2、这种语法意义上变形,只在类定义阶段发生一次,类定义之后,新增的开头的
属性没有变形
3、如果父类不想让子类覆盖自己的方法,可以在方法名前加_开头
类内部定义的函数,默认就是给对象来用,而且是绑定给对象用的,称为对象的绑定方法
绑定对象的方法特殊之处:
应该由对象来调用,对象来调用,会自动将对象当作第一个参数传入
绑定到类的方法特殊之处:
应该由类来调用,类来调用,会自动将类当作第一个参数传入
多态同一种事物多种形态
用基类创建一套统一规则,强制子类去遵循,这样便可以在不用考虑对象具体类型
的前提下而直接使用对象下的方法
print(isinstance(obj,Foo)) # 推荐使用该函数来判断一个函数的类型