目录
- 概述
- 面向对象的三步骤
- 对象
- 类
- self参数
- 属性
- 方法
- 魔术方法/魔术变量
- 封装
- 继承
- 多态
- 闭包
- 装饰器
面向对象
一.概述
1.面向过程:
- 面向过程:自顶向下,逐步细化,强调过程
2.面向对象:
- 面向对象:不仅将功能封装成函数,更要把对象主体进行封装,使其拥有相关的函数和属性
3.两者区别
-
① 都可以实现代码重用和模块化编程,面向对象的模块化更深,数据也更封闭和安全
-
② 面向对象的思维方式更加贴近现实生活,更容易解决大型的复杂的业务逻辑
-
③ 从前期开发的角度来看,面向对象比面向过程要更复杂,但是从维护和扩展的角度来看,面向对象要远比面向过程简单!
-
④ 面向过程的代码执行效率比面向对象高
二.面向对象三步骤
- 找对象
- 找属性和方法
- 根据业务需求,对象调用属性和方法来实现功能
三.对象
1.概述:
-
Python中一切皆对象(object)
-
对象不能凭空产生,必须由类(class)实例化产生
-
类也可以视为特殊的对象,所以类也存在属性和方法
-
通常情况下的叫法:实例 == 对象 == 成员
2.特点:
-
使用属性(property)保存数据
-
使用方法(method)管理数据
3.语法格式:
# 调用类中的属性和方法
p1.eat()
print(p1.name)
四.类
1.概述:
-
具有相同或相似属性和方法的对象的集合
-
类并不是具体的事物,而是一个抽象的概念
-
在类中封装了对象的属性和方法
2.语法格式:
- 类分为经典类和新式类,目前大多采用新式类的定义方法
# Python中的类名建议采用大驼峰命名法
class Person(object):
pass
- 方法和属性的封装
class Person(object):
# 属性
name = "张三"
# 方法
def eat(self):
print('eat方法')
-
类的实例化:就是通过类来生成一个具体的对象
一个类理论上可以实例化多个对象,但是每个对象的内存地址都不相同
# 类的实例化(产生对象)
p1 = Person()
p2 = Person()
五.self参数详解
- self参数是类的方法中必须保留的参数
- self指向的内存地址和p1指向的内存地址一致,因此self指向了p1对象本身
六.属性
1.属性的定义:
属性的定义 | 语法格式 | 代码书写的位置 | |
---|---|---|---|
类属性 | 属性名 = 值 | 类的内部,方法的外部 | |
对象属性 | self.属性名 = 值 | 类的内部,方法的内部 | 类的外部 |
2.属性的调用:
属性的调用 | 语法格式 | 代码书写的位置 | |
---|---|---|---|
类属性 | 类名.属性 -> 进行操作 | 类的外部 | 类的内部,方法的内部 |
对象属性 | 对象.属性 -> 进行操作 | 类的外部 | 类的内部,方法的内部 |
3.代码演示:
class Person(object):
# 类属性-定义
count = 0
def __init__(self):
# 对象属性-定义1-类的内部方法的内部
self.name = '张三'
# 类属性-调用1-类的内部方法的内部
Person.count += 1
# 对象属性-调用1-类的内部方法的内部(1)
print(self.name)
# 对象属性-调用1-类的内部方法的内部(2)
def eat(self):
print(self.age)
# 实例化对象
p1 = Person()
# 对象属性-定义2-类的外部
p1.age = 18
# 对象属性-调用2-类的外部
print(p1.name)
# 类属性-调用2-类的外部
print(Person.count)
4.注意:
- 对象属性:既可以在类的内部(方法的内部)定义和调用,也可以在类的外部定义和调用
- 类属性:只能在类的内部(方法的外部)定义,但是可以在类的外部和类的内部(方法的内部)调用
- 类属性的意义:保存这个类的某些属性(比如统计这个类产生了多少对象,这个类自身有哪些信息等)
- 对象属性是每个对象拥有的,但是类属性只有一个(无论实例化了多少对象)
- 类属性:
- 可以被继承;
- 可以使用对象.属性进行调用;Python语言很灵活,只在Python中实现,不推荐,因为不符合代码通用性
- 可以设置类属性为私有,但是很少这样做
- 实际开发中,建议在类方法中,对类属性进行调用,或者调用其他方法,避免安全隐患
七.方法
1.方法的定义
方法的定义 | 语法格式 |
---|---|
类方法 | @classmethod def 类方法名(cls): pass |
对象方法 | def 对象方法名(self): pass |
静态方法 | @staticmethod def 静态方法名(): pass |
2.方法的调用
方法的调用 | 语法格式 |
---|---|
类方法 | 类名.方法名() |
对象方法 | 对象名.方法名() |
静态方法 | 类名.静态方法名() |
3.代码演示:
class Tool(object):
count = 0
# 类方法-定义
@classmethod
def get_count(cls):
return Tool.count
# 对象方法-定义
def __init__(self):
Tool.count += 1
# 实例化1,2,3
t1 = Tool()
t2 = Tool()
t3 = Tool()
# 类方法-调用
print(f"一共实例化了{
Tool.get_count()}个对象")
4.注意
-
类方法:
- 可以被继承;
- 可以设置私有;
- 可以通过对象.方法()调用;
- 了解即可不推荐使用
-
静态方法:
- 不需要访问对象属性/方法;不需要访问类属性/方法
- 使用对象.静态方法或者类名.静态方法都可以调用
八.魔术方法和魔术变量
- _ _ xx _ _()叫做魔术方法,指的是具有特殊功能的函数
- _ _ xx _ _ 叫做魔术变量,指的是具有特殊功能的变量
1._ _ init _ _ ()构造方法
- 作用:当实例化对象的瞬间,自动调用该方法,赋予该对象一些属性
- 问题在于:如果不设置参数,那么所有实例化的对象都拥有相同的初始属性;事实上每个对象的属性不一定相同
class Person(object):
def __init__(self, name):
self.name = name
# 实例化p1对象
# 传参给__init__()方法
p1 = Person('张三')
-
当然可以在类的外部获取到该方法里面的属性和值
通过p1.name就可以访问到