python基础复习-面向对象
什么是面向对象
相较于面向过程, 我们为什么去选择面向对象, 而不是继续是用面向过程
对于面向过程来说, 给人的感觉更像是一个一个事务的罗列, 我们要完成一件事之后, 去到下个地方再去完成下一件事, 每件事情都要亲历亲为
而对于面对象来说, 可以理解为我们划分了一部分空间去完成一系列事情, 将这些事情封装到一个类中, 我们不需要去考虑类中是如何实现的, 只需要会调用就可以了
关于类的定义
类对于我们可以说是一个虚拟的, 没有实体的存在, 只有在进行过实例化之后得到的对象
才是我们可以进行操作的, 摸得到的; 一个类可以有多个对象
创建, 例:
class Demo(object):
pass
具体组成
class 类名(继承的父类): # 可以简写为 class 类名 : , 继承多个父类使用`,`隔开
类的内容
对象创建
对象就通过类进行实例化而创建出的实体数据, 可以进行调用, 执行, 是一个我们摸得到的存在
class Demo(object):
pass
demo = Demo() # 使用类名()来创建一个类
面向对象的三大特性, 封装、继承、多态
封装
封装就是由一个类对能够实现一个个功能的代码块进行包装, 使其成为一个整体, 只为外界调用提供一个接口, 让外界能够去调用封装后的代码, 可以降低代码的耦合, 让我们更好的去实现细节
继承
在python中类和类之间可以进行继承, 子类可以去调用父类的方法, 降低代码的重写概率, 提高编写代码的效率, 也可以同时继承多个父类, 来获得更多的方法.
class A:
def play(self):
print("play")
class B:
def eat(self):
pass
class C(A, B):
def play(self):
pass
# super().play()
c = C() # 创建c类的对象
c.play()
这里有类A, B, C, 其中A类拥有play
方法, B类拥有eat
方法, 而C类同时继承了A类和B类, 这个时候C类的对象是可是去调用父类的方法的, 如c.eat()
这个时候就是子类调用父类的方法了, 但是我们发现这里的子类C和父类A都拥有一个方法play
, 而这个时候则会因为子类重写父类同名方法的特性从而调用自己的play
方法
多态
python中的多态的体现不是很明显, 它是体现在拥有继承关系的两个类, 如上面的A类和C类, 两着都拥有play
方法, 而要调用那个类的play
方法我们是可以通过像是子类重写父类的特性调用父类, 也可以使用super().play()
去调用父类的play
方法, 我们把这种可以灵活多变的调用方式称之为多态
实例方法
class Demo(object):
def __init__(self, name):
"""魔法方法"""
self.name = name
def instance(self):
"""实例方法"""
pass
@staticmethod
def static():
""""静态方法"""
pass
@classmethod
def class_m(cls):
"""类方法"""
pass
在上图Demo类中, 像instance
这种不添加staticmethod
和classmethod
装饰器的方法就是实例方法, 实例方法在调用时, 会将调用的对象当作参数传递进函数, 由self
来接收, 这样就可以知道是那个实例在调用这个方法.
类方法
在上图Demo类中, 像class_m
这种使用classmethod
装饰过的方法称为类方法, 类方法在调用时, 会将调用它的类, 或者实例化这个对象的类当作参数传入函数, 由cls
来接收.
静态方法
再上图Demo类中, 像static
这种使用staticmethod
装饰过的方法称为静态方法, 静态方法再调用时, 不会在乎是谁调用的它, 因此不需要去定义一个额外参数
魔法方法&魔法属性
我们发现, 除了上述的几种方法外, 还有一个以__
开头和结尾的方法, 它也没有被特殊装饰过, 那它是不是实例方法呢, 答案肯定是否定的, 因为这样的方法都是python的内置的特殊方法, 我们称之为魔法方法, 这些魔法方法能够实现的功能大不相同, 我这这里只举几个简单常见的例子
__init__(self)
方法, 像上述类中的__init__
方法为构造函数, 用来初始化对象, 对对象的属性进行赋值, 必须要有一个self
函数, 用来接收__new__
方法返回的实例__new__(cls)
方法, 在上述提到,__new__
方法可以返回实例, 其实在python中, 要把__init__
方法和__new__
方法一起看才能实现C语言的构造函数的功能, 在每次创建一个新对象的时候, 系统都会去自动调用__new__
方法来创建一个新的实例, 使用时候要注意,__new__
方法必须要有返回值, 来返回创建好的实例对象, 常用于构建元类和单例.
# 用法示例-单例
class A(object):
# 定义一个类属性, 用来判断有没有创建过对象
__a = None
def __new__(cls):
if cls.__a: # 如果没有创建过就调用父类的方法创建
return super().__new__(cls)
return cls.__a
# 使用id验证
a1 = A()
a2 = A()
print(id(a1)==id(a2))
# 结果为:True 的确只创建了一个wei对象
__del__(self)
方法, 为python中的析构方法, 在对象运行结束进行垃圾回收时, 自动调用的方法, 可以用来进行一些收尾工作, 如, 关闭文件, 断开连接之类的, 也可以通过del
对象来触发__class__
方法, 获取当前对象的类对象, 也可以连写两个用来找到父类, 一般多用来调用类属性__str__(self)
方法, 当你在执行一个打印对象的操作时, 会自动调用, 用来描述一个对象或打印信息, 要有return
来返回想要展示的信息, 返回内容格式必须为str
.
class B(object):
def __str__(self):
return "我是__str__方法"
b = B()
print(b)
结果为
我是__str__方法