类与对象
一、什么是类?什么是对象?
类(class):是模板,描述具有相同属性和行为的事物(比如:学生、人、汽车)。类定义了对象的结构和行为,是创建对象的蓝图。
对象(object):是根据类创建出来的具体实例。每个对象都有自己的属性值,但共享类定义的方法。
例子:类 = 学生模板(有名字、年龄、会学习)对象 = 小樊、小明、小红(一个个具体的学生)
为什么需要类和对象?
- 提高代码复用性:定义一次模板,创建多个实例。
- 模拟现实世界:事物有属性(特征)和方法(行为)。
- 组织代码:将相关数据和操作封装在一起。
二、定义一个类
语法:
class 类名:
# 构造方法(创建对象时自动执行)
def __init__(self, 参数1, 参数2...):
self.属性1 = 参数1
self.属性2 = 参数2
# 方法(行为)
def 方法名(self):
执行代码
注意事项:
- 类名通常使用 PascalCase(首字母大写)。
- __init__ 是特殊方法,称为构造函数,用于初始化对象的属性。
- self 是必须的参数,代表实例本身。
- 类可以有多个方法,每个方法定义对象的行为。
三、最简单的类示例
# 定义学生类
class Student:
# 构造函数:初始化属性
def __init__(self, name, age):
self.name = name # 姓名属性
self.age = age # 年龄属性
# 方法:学习
def study(self):
print(f"{self.name} 今年 {self.age} 岁,正在学习Python")
# 创建对象
s1 = Student("小樊童鞋", 20)
s1.study()
运行结果:
小樊童鞋 今年 20 岁,正在学习Python
扩展示例:添加更多方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def study(self):
print(f"{self.name} 正在学习")
def introduce(self):
print(f"大家好,我是 {self.name},今年 {self.age} 岁")
s1 = Student("小明", 21)
s1.introduce()
s1.study()
四、类的核心概念
-
init 构造方法
创建对象时自动调用
用于给对象初始化属性
可以有默认参数:def init(self, name="未知", age=0): -
self 是什么?
代表当前对象自己
用来访问对象的属性和方法
在方法定义中是必须的第一个参数,但在调用时不需要传入。 -
属性 = 特征
self.name
self.age
- 实例属性:每个对象独有,通过 self.属性名 访问。
- 类属性:所有对象共享,通过 类名.属性名 或 self.属性名 访问(但推荐类名)。
- 方法 = 行为
def study(self): ...
def run(self): ...
- 实例方法:操作实例属性,需要 self。
- 类方法:使用 @classmethod 装饰器,第一个参数是 cls,用于操作类属性。
- 静态方法:使用 @staticmethod 装饰器,不需要 self 或 cls,用于工具函数。
五、创建多个对象
s1 = Student("小樊", 20)
s2 = Student("张三", 19)
s1.study()
s2.study()
每个对象都是独立的实例,有自己的属性值。
可以创建对象列表或字典来管理多个对象:
students = [Student("小樊", 20), Student("张三", 19), Student("李四", 18)]
for s in students:
s.study()
六、访问与修改对象属性
s = Student("小樊", 20)
print(s.name) # 获取属性
s.age = 21 # 修改属性
属性可以动态添加:s.grade = "A"
但推荐在 __init__ 中初始化所有属性。
使用 hasattr(), getattr(), setattr() 函数来动态操作属性。
七、本篇小结
类是模板,对象是实例
class 类名: 定义类
__init__(self) 构造函数初始化属性
self 代表当前对象
对象。属性 / 对象。方法 () 进行使用
面向对象编程的三大特性:封装(将数据和方法封装在类中)、继承(子类继承父类特性)、多态(同一方法不同行为)。
八、练习题
- 创建一个 Car 类,有 brand 和 speed 属性,以及 drive() 方法。
- 创建多个 Car 对象,并修改它们的属性。
- 尝试添加一个类属性,如 total_cars 来计数创建的对象数量。
九、进阶概念和示例
- 私有属性和方法
Python 中使用双下划线 __ 开头的属性或方法为私有,外部无法直接访问。
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age # 私有属性
def get_age(self):
return self.__age
def set_age(self, age):
if age > 0:
self.__age = age
s = Student("小明", 20)
print(s.name) # 可访问
# print(s.__age) # 错误,无法直接访问
print(s.get_age()) # 通过方法访问
- 魔术方法(特殊方法)
str 方法定义对象的字符串表示,当使用 print(对象) 时调用。
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"学生:{self.name},年龄:{self.age}"
s = Student("小明", 20)
print(s) # 输出:学生:小明,年龄:20
- 类方法和静态方法的示例
class Student:
school = "XX大学" # 类属性
def __init__(self, name):
self.name = name
@classmethod
def change_school(cls, new_school):
cls.school = new_school
@staticmethod
def is_adult(age):
return age >= 18
# 类方法
Student.change_school("YY大学")
print(Student.school) # YY大学
# 静态方法
print(Student.is_adult(20)) # True
-
封装的概念
封装是将数据和操作数据的方法绑定在一起,对外部隐藏内部实现细节。通过私有属性和方法实现。 -
对象的相等性和身份
- == 比较值相等
- is 比较身份(内存地址)
s1 = Student("小明", 20)
s2 = Student("小明", 20)
print(s1 == s2) # False(除非重写 __eq__)
print(s1 is s2) # False,不同对象
十、常见错误和调试提示
- 忘记 self:在方法中访问属性时必须用 self.
- 类名错误:类名应大写开头。
- 属性未初始化:使用前确保在 init 中赋值。
- 调试:使用 print(self.dict) 查看对象的所有属性。
十一、进一步阅读
- Python 官方文档:https://docs.python.org/3/tutorial/classes.html
- 书籍:《Python 编程:从入门到实践》
- 在线教程:Codecademy 或 freeCodeCamp 的 Python OOP 部分。
浙公网安备 33010602011771号