Python面向对象编程:类与实例详解
类与实例的核心概念
在面向对象编程(OOP)中,类(Class)和实例(Instance)是基础构建单元。它们的主要用途包括:
- 组织相关函数并共享数据状态
- 按照执行主体分类行为逻辑,提升代码结构清晰度
编程范式对比
程序设计可分为过程式和面向对象两种风格:
- 过程式编程:关注功能的具体执行步骤,通过函数调用组合实现业务逻辑
- 面向对象编程:聚焦于行为发起者及其协作关系,利用类的继承和组合机制构建系统
过程式开发遵循以下模式:
- 分解业务流程为独立步骤
- 编写函数实现各步骤逻辑(支持嵌套和相互调用)
- 在主程序中协调调用各函数完成整体任务
复杂项目可通过模块化和包管理进行组织。示例代码:
def open_fridge():
pass
def put_elephant_inside():
pass
def close_fridge():
pass
# 执行流程
open_fridge()
put_elephant_inside()
close_fridge()
面向对象则依据执行主体划分职责,通过对象间的交互完成任务:
- 识别业务涉及的角色实体,确定所需属性和行为
- 为各类别设计对应的类结构
- 在主流程中实例化对象并通过对象间协作完成业务
同一模块内可整合相关函数并共享对象状态。示例代码:
class Fridge:
def open_door(self):
pass
def close_door(self):
pass
class Elephant:
def enter_fridge(self):
pass
# 对象交互
fridge_obj = Fridge()
elephant_obj = Elephant()
fridge_obj.open_door()
elephant_obj.enter_fridge()
fridge_obj.close_door()
类与实例的关联性
如同函数定义与调用的关系,面向对象也包含定义和使用两个阶段。
类是对具有共同特征事物的抽象描述(如动物、设备等),而实例则是符合此类描述的具体个体(如某只猫、特定型号的冰箱)。
典型的面向对象使用流程:
- 创建类定义,指定对象的数据属性和行为方法
- 通过类构造具体实例,并通过实例执行相应操作
以猫咪类别和具体宠物为例:
class Cat:
def speak(self):
print('Meow!')
pet_cat = Cat()
pet_cat.speak()
对象构造器
Python提供多种特殊方法实现不同功能,其中__init__用于对象初始化,在实例创建时自动触发,常用于:
- 将构造参数绑定至对象属性
- 执行必要的初始化配置
示例:
class Learner:
def __init__(self, full_name, years_old):
print('New student enrolled')
self.full_name = full_name
self.years_old = years_old
创建实例时自动传参并显示提示:
student_one = Learner('Li Lei', 18)
print(student_one.full_name, student_one.years_old)
属性分类
类中存在两类属性:
- 类级别属性:可供类本身或其实例访问
- 实例级别属性:仅能通过实例对象访问
示例:
class Learner:
category = 'Student'
def __init__(self, full_name, years_old):
self.full_name = full_name
self.years_old = years_old
student_one = Learner('Li Lei', 18)
print(student_one.category)
print(student_one.full_name, student_one.years_old)
print(Learner.category)
方法类型区分
根据作用域不同,类中可定义三种方法:
- 实例方法:绑定到具体实例,通过self访问实例状态
- 类方法:绑定到类本身,通过cls访问类状态
- 静态方法:不依赖类或实例状态的通用工具函数
示例:
from datetime import datetime
class Learner:
category = 'Student'
def __init__(self, full_name, years_old):
self.full_name = full_name
self.years_old = years_old
def fetch_name(self):
return self.full_name
@classmethod
def fetch_category(cls):
return cls.category
@staticmethod
def current_time():
return datetime.now().strftime('%Y%m%d %H:%M:%S')
# 实例调用
student_one = Learner('Li Lei', 18)
print(student_one.fetch_name())
print(student_one.fetch_category())
print(student_one.current_time())
# 类调用
print(Learner.fetch_category())
print(Learner.current_time())
理论上类也可调用实例方法,但需显式传入实例:
student_one = Learner('Li Lei', 18)
print(Learner.fetch_name(student_one))
面向对象三大原则
- 封装性:隐藏内部实现细节,通过公共接口暴露必要功能
- 继承性:子类可复用父类的所有成员,实现代码重用
- 多态性:基于继承机制,不同子类可对相同方法提供差异化实现
封装实践
class Learner:
def __init__(self, full_name, years_old):
self._full_name = full_name
self._years_old = years_old
def fetch_name(self):
return self._full_name
def fetch_age(self):
return self._years_old
def self_introduction(self):
print(f'I am {self.fetch_name()}, aged {self.fetch_age()}')
外部通过标准接口访问内部私有数据:
student_one = Learner('Li Lei', 18)
print(student_one.fetch_name(), student_one.fetch_age())
继承机制
class Individual:
def __init__(self, full_name, years_old):
self._full_name = full_name
self._years_old = years_old
def fetch_name(self):
return self._full_name
def fetch_age(self):
return self._years_old
class Learner(Individual):
def self_introduction(self):
print(f'I am {self.fetch_name()}, aged {self.fetch_age()}')
多态表现
class Individual:
def __init__(self, full_name, years_old):
self._full_name = full_name
self._years_old = years_old
def fetch_name(self):
return self._full_name
class Learner(Individual):
def fetch_name(self):
return f'Student: {self._full_name}'
class Employee(Individual):
def fetch_name(self):
return f'Employee: {self._full_name}'
子类重写了父类方法,相同调用产生不同结果:
learner = Learner('Li Lei', 18)
employee = Employee('Han Meimei', 25)
print(learner.fetch_name())
print(employee.fetch_name())