(十一)面向对象程序设计
1. 相关概念
面向对象(Object Oriented)程序设计是一类很重要的思想。要创建一个对象(Object),就需要基于类(class)来完成。类是一批具有相同的属性的对象的抽象,是一种抽象概念。对象是一个具体存在的实体,基于类来创建对象的过程就是类的实例化。
2. 定义类
经典方法(旧式方法)
class ClassName:passclass ClassName():pass
新式方法
class ClassName(object):pass
3. 创建对象
2.1 类对象和实例对象
类对象
class ClassName:pass
实例对象(基于类对象创建,属于类对象的对象)
class ClassName:passtest = ClassName()
4. 类属性和实体属性
3.1 类属性
类中方法外的变量称为类属性,被该类的所有对象共享。
native_var = 20
通过类对象创建的实例对象,都有指向类对象的 类指针,类属性改变则实例对象的属性也会变。
3.2 类属性的调用
# 一ClassName.native_var# 二test = ClassName()test.native_var
3.2 实体属性
5. 方法
4.1 实例方法
直接定义在类里面的方法
def test(self):pass
4.2 静态方法
使用 @staticmethod 修饰静态的方法,通过类名直接访问。
@staticmethoddef m():pass
4.3 类方法
使用 @classmethod 修饰类方法,使用类名直接访问和。
@classmethoddef cm(cls):pass
6. __init__() 方法初始化
self.name 是实例属性,进行了一个赋值操作,将局部变量 name 赋值给实体属性
def __init__(self, a, b):self.a = aself.b = bself.c = 10
7. 调用方法
6.1 通过创建的实例调用
test = ClassName()test.method()
6.2 通过传入实例对象调用
ClassName.method(test)
8. 动态绑定属性和方法
7.1 动态绑定属性
直接使用 test.var = value 进行给实例对象 test 添加一个属性,动态绑定。
7.2 动态绑定方法
在类外定义函数,然后给实例对象动态添加这个函数,成为对象的方法。
def show():passtest.show = show
9. 修改属性的值
4.1 直接修改属性的值
ClassName.attribute = 'xxx'
4.2 通过方法修改
在对象内创建一个方法,然后在方法内修改。
def f(self, name):self.name = nameClassName.f('xxx')
4.3 通过方法对属性的值进行递增
def add(self, x):self.age += xadd(2)
10. 面向对象三大特征
1)封装
提高程序的安全性。
将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象外的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。
在 Python 中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,在属性前面加个
___(双下划线)。
2)继承
提高代码的复用性
使用
super()继承父类class A(object):def __init__(self, a):passclass B(A):def __init__(self, a, b):super()__init__(a)self.b = b
- 多继承
```python
class A(object):
def init(self, a)
class B(object): def init(self, b)self.a =a
self.b = b
class C(A, B): def init(self, a, b): A.init(self, a) B.init(self, b)
-方法重写<br />如果子类对继承自父类的某个属性或方法不满意,可以在字类中对其(方法体)进行重新编写<br />字类重写后的方法中可以通过 `super().xxx()` 调用父类中被重写的方法-Object 类-object类是所有类的父类,因此所有类都有object类的属性和方法。-内置函数 `dir()` 可以查看指定对象所有属性-object类有一个 `__str__()` 方法,用于返回一个对于“对象的描述”,对于内置函数 `str()` 经常用于 `print()` 方法,帮助我们查看对象信息,所以我们经常会对 `__str__()` 进行重写```pythondef __str__(self):pass
3)多态
多态提高程序的可扩展性和可维护性
简单的说,多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定到底调用哪个对象中的方法。
静态语言与动态语言的区别
静态语言实现多态的三个必要条件
- 继承
- 方法重写
- 父类引用指向子类对象
- 动态语言的多态崇尚于“鸭子类型”。当看到一只鸟走起来像鸭子、游泳时像鸭子、收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。
11. 特殊方法和特殊属性
| 名称 | 描述 | |
|---|---|---|
| 特殊属性 | dict |
获得类对象或实例对象所绑定的所有属性和方法的字典 |
| 特殊方法 | __len__() |
通过重写 __len__()方法,让内置函数 len()的参数可以是自定义的 |
__add__() |
通过重写__add__()方法,可使用自定义对象具有 + 功能 |
|
__new__() |
用于创建对象 | |
__init__() |
对创建的对象进行初始化 |
12. __new__() 和 __init__() 创建对象的过程
pass
13.类的浅拷贝与深拷贝
变量的赋值操作
只是形成两个变量,实际上还是指向同一个对象浅拷贝
Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象深拷贝
使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同
14 . __del__ 方法
__del__ 方法会在对象被销毁前自动调用。
这可以联系对象的生命周期理解。
生命周期开始于对象被创建,一个对象的 __del__ 方法一旦被调用,生命周期结束。
在生命周期内,才能访问对象属性和方法。
15. __str__ 方法
- 在python中,使用
print输出对象变量,默认情况下,会输出这个变量引用的对象,是由哪一个类创建的对象,以及内存中的地址(十六进制)。 - 如果在开发中,希望使用
print输出对象变量 打印自定义 的内容,就可以利用__str__这个内置方法了。 __str__方法必须返回一个字符串
16. 私有属性和私有方法
应用场景
私有属性
不希望公开的属性私有方法
不希望公开的方法
定义方式
- 在定义的属性或方法名前,加两个下划线
__就定义了私有属性或方法。
伪私有属性和私有方法
提示:在日常开发中,不要使用这种方式访问对象的私有属性或私有方法
Python 中,并没有真正意义的私有。
- 在给属性、方法命名时,实际上是给名称做了一些特殊处理,使得外界无法访问到。
- 处理方式上,在名称前面加上
_类名=>_类名__名称
