文章目录
目标
- 面向对象三大特性
- 类属性和实例属性
- 类方法和静态方法
一、面向对象三大特性
- 封装
- 将属性和方法书写到类的里面的操作即为封装
- 封装可以为属性和方法添加私有权限
- 继承 (实现代码的重用,相同的代码不需要重复的编写)
- 子类默认继承父类的所有属性和方法
- 子类可以重写父类属性和方法
- 多态
- 不同的 子类对象 调用相同的 父类方法,产生不同的执行结果
- 传入不同的对象,产生不同的结果
二、类结构
2.1 术语—实例
- 使用面相对象开发,第 1 步 是设计 类
- 使用 类名() 创建对象,创建对象 的动作有两步:
-
- 在内存中为对象 分配空间
-
- 调用初始化方法
__init__
为 对象初始化
- 调用初始化方法
-
3.对象创建后,内存 中就有了一个对象的 实实在在 的存在 —— 实例
因此,通常也会把:
- 创建出来的 对象 叫做 类 的 实例
- 创建对象的 动作 叫做 实例化
- 对象的属性 叫做 实例属性
- 对象调用的方法 叫做 实例方法
在程序执行时:
- 对象各自拥有自己的 实例属性
- 调用对象方法,可以通过
self.
- 访问自己的属性
- 调用自己的方法
结论
- 每一个对象 都有自己 独立的内存空间,保存各自不同的属性
- 多个对象的方法,在内存中只有一份,在调用方法时,需要把对象的引用 传递到方法内部
2.2 类是一个特殊的对象
Python
中 一切皆对象:
class A:
定义的类属于 类对象obj = A()
属于 实例对象
-
在程序运行时,类 同样 会被加载到内存
-
在
Python
中,类 是一个特殊的对象 —— 类对象 -
在程序运行时,类对象 在内存中 只有一份,使用 一个类 可以创建出 很多个对象实例
-
除了封装 实例 的 属性 和 方法外,类对象 还可以拥有自己的 属性 和 方法
- 类属性
- 类方法
-
通过 类名. 的方式可以 访问类的属性 或者 调用类的方法
三、类属性和实例属性
3.1 类属性(两种访问方式)
- 类属性 就是给 类对象 中定义的 属性
- 通常用来记录 与这个类相关 的特征
- 类属性 不会用于记录 具体对象的特征
3.1.1 设置和访问类属性
1)设置类属性
- 类属性就是 类对象 所拥有的属性,它被 该类的所有实例对象 所共有。
属性 = 值
2)访问类属性
-
类属性可以使用 类对象 或 实例对象 访问。
-
类名.类属性
-
对象.类属性 (不推荐)
-
注意
- 如果使用
对象.类属性 = 值
赋值语句,只会 给对象添加一个属性,而不会影响到 类属性的值
# 1. 定义类,定义类属性
class Dog(object):
tooth = 10 # 设置类属性
# 2. 创建对象
wangcai = Dog()
xiaohei = Dog()
# 3. 访问类属性(两种方法): 类和对象
print(Dog.tooth) # 10
print(wangcai.tooth) # 10
print(xiaohei.tooth) # 10
类属性的优点
- 记录的某项数据 始终保持一致时,则定义类属性。
- 实例属性 要求 每个对象 为其 单独开辟一份内存空间 来记录数据,而 类属性 为全类所共有 ,仅占用一份内存,更加节省内存空间。
3.1.2 修改类属性(一种修改方式)
类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了一个实例属性。
- 在类外部修改类属性
类名.类属性 = 值 # 修改类属性
class Dog(object):
tooth = 10
wangcai = Dog()
xiaohei = Dog()
# 修改类属性
Dog.tooth = 12
print(Dog.tooth) # 12
print(wangcai.tooth) # 12
print(xiaohei.tooth) # 12
# 不能通过对象修改属性,如果这样操作,实则是创建了一个实例属性
wangcai.tooth = 20
print(Dog.tooth) # 12
print(wangcai.tooth) # 20
print(xiaohei.tooth) # 12
3.2 实例属性
实例属性:描述事物的特征。
class Dog(object):
def __init__(self):
self.age = 5
def info_print(self):
print(self.age)
wangcai = Dog()
print(wangcai.age) # 5
# print(Dog.age) # 报错:实例属性不能通过类访问
wangcai.info_print() # 5
四、类方法和静态方法
4.1 类方法(两种访问方式)
4.1.1 类方法语法
- 类方法 就是针对 类对象 定义的方法
- 在 类方法 内部可以直接访问 类属性 或者调用其他的 类方法
语法如下
@classmethod
def 类方法名(cls):
pass
- 类方法需要用 修饰器
@classmethod
来标识,告诉解释器这是一个类方法 - 类方法的 第一个参数 应该是
cls
- 由 哪一个类 调用的方法,方法内的
cls
就是 哪一个类的引用 - 这个参数和 实例方法 的第一个参数是
self
类似 - 提示 使用其他名称也可以,不过习惯使用
cls
- 由 哪一个类 调用的方法,方法内的
4.1.2 类方法特点
-
需要用装饰器
@classmethod
来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls
作为第一个参数。 -
在方法内部
- 可以通过
cls.
访问类的属性 - 也可以通过
cls.
调用其他的类方法
- 可以通过
4.1.3 类方法使用场景
-
当方法中 需要使用类对象 (如访问私有类属性等)时,定义类方法
-
类方法一般和类属性配合使用
-
调用类方法(两种)
-
类名.类方法() # 不需要传递 cls 参数
-
对象名.类方法()
-
# 1. 定义类:私有类属性,类方法获取这个私有类属性
class Dog(object):
__tooth = 10 # 定义私有类属性
# 定义类方法
@classmethod
def get_tooth(cls): # cls指代Dog这个类
return cls.__tooth
# 2. 创建对象,调用类方法
wangcai = Dog()
result = wangcai.get_tooth()
print(result) # 10
result = Dog.get_tooth()
print(result) # 10
4.2 静态方法(两种访问方式)
4.2.1 静态方法语法
- 在开发时,如果需要在 类 中封装一个方法,这个方法:
- 既 不需要 访问 实例属性 或者调用 实例方法
- 也 不需要 访问 类属性 或者调用 类方法
- 这个时候,可以把这个方法封装成一个 静态方法
语法如下
@staticmethod
def 静态方法名():
pass
- 静态方法 需要用 修饰器
@staticmethod
来标识,告诉解释器这是一个静态方法 - 通过 类名. 调用 静态方法
4.2.2 静态方法特点
-
需要通过装饰器
@staticmethod
来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)。 -
静态方法 也能够通过 实例对象 和 类对象 去访问。
-
类名.静态方法名()
-
对象名.静态方法名()
-
4.2.3 静态方法使用场景
- 当方法中 既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象 (如类属性、类方法、创建实例等)时,定义静态方法
- 取消不需要的参数传递,有利于 减少不必要的内存占用和性能消耗
# 1. 定义类,定义静态方法
class Dog(object):
@staticmethod
def info_print():
print('这是一个静态方法')
# 2. 创建对象
wangcai = Dog()
# 3. 调用静态方法:类 和 对象
wangcai.info_print() # 这是一个静态方法
Dog.info_print() # 这是一个静态方法
五、总结
- 面向对象三大特性
- 封装
- 继承
- 多态
- 类属性
- 归属于类对象的属性,所有对象共有的属性
- 实例属性
- 类方法
@classmethod
def xx():
代码
- 静态方法
@staticmethod
def xx():
代码