面向对象编程(Object-Oriented Programming, OOP)是一种广泛使用的程序设计范式,它将程序视为一组相互协作的对象。Python作为一门典型的面向对象语言,使用类(class)和对象(object)来封装数据和操作,让代码结构更清晰、更易维护和复用。
1. 面向对象编程简介
面向对象编程的核心思想是:万物皆对象。每个对象都包含自己的状态(数据,称为属性)和行为(操作,称为方法)。对象是根据某个蓝图或模板创建出来的,这个模板就是“类”。
- 类:是创建对象的模板,它定义了该类所有对象共有的属性和方法。你可以把它想象成一张汽车设计图纸。
- 对象:是类的具体实例,拥有类所定义的属性和方法,并且每个对象的属性值可以独立不同。这就是根据那张图纸生产出来的一辆辆具体的汽车。
一个简单的类比:
“狗”可以看作一个类,它定义了所有狗共有的属性(如name, age)和行为(如bark, run)。而一只名叫“旺财”、2岁的小狗,就是“狗”类的一个对象。
| 概念 |
本质 |
类比 |
关键点 |
| 类(Class) |
蓝图/模板(定义对象的结构) |
汽车设计图纸 |
是抽象概念,不占用内存,仅描述规则 |
| 对象(Object) |
具体实例(类的运行时实体) |
一辆具体生产的汽车 |
是具体实现,每个对象独立存在,占用内存 |
关键洞察:
- 类是抽象的说明书,对象是按说明书造出的实物。
- 通过理解类与对象的关系,是掌握面向对象编程思想的第一步。
2. 类的定义
2.1 语法结构
在 Python 中,使用 class 关键字来定义一个类。
class ClassName:
# 类体:定义属性和方法
关键语法:
class:定义类的关键词。
类名:必须是合法的 Python 标识符,通常采用驼峰命名法(每个单词首字母大写,例如 MyClass)。
类体:必须缩进(通常为 4 个空格),内部用于定义这个类的属性和方法。
2.2 类的定义示例
class Dog:
"""一个简单的Dog类,表示狗的属性和行为"""
# 类体(暂时为空)
3. 对象的创建:实例化
定义了类之后,就可以用它来创建具体的对象了,这个过程称为“实例化”。
3.1 语法
通过调用类名后加括号 () 来创建一个该类的实例(对象)。
object_name = ClassName(arguments)
关键语法:
类名后加括号 ():表示进行实例化操作。
括号内参数:这些参数会传递给类的 __init__ 方法(构造函数),用于初始化对象的属性。
3.2 对象创建示例
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
# 创建两个Dog对象:
my_dog = Dog("Buddy", "Golden Retriever") # 实例化对象
your_dog = Dog("Max", "Labrador") # 另一个对象
my_dog 和 your_dog 是两个独立的 Dog 对象,每个对象有自己的 name 和 breed 属性。
- 每次实例化都会得到一个全新的、独立的对象,它们在内存中拥有不同的地址。
4. 构造函数 __init__()
通常,我们希望对象在创建时就拥有一些初始属性。在 Python 中,这通过定义 __init__() 方法来实现。
__init__() 是一个特殊方法,也称为构造函数。它在对象创建后自动调用,专门用于初始化对象的属性。
class Dog:
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age # 实例属性
self 参数指向当前正在被创建的实例对象,它必须是实例方法的第一个参数。
- 通过
self.属性名 = 值 的语法,可以为该实例绑定属性。
创建带初始值的对象:
dog1 = Dog("旺财", 2)
dog2 = Dog("来福", 3)
print(dog1.name) # 输出:旺财
print(dog2.age) # 输出:3
重要提示:
__init__() 方法除了 self 外,可以定义任意多个参数,这些参数在实例化时必须传入对应的值。
__init__ 在每个对象创建时自动调用,且只执行一次。你创建多少个对象,它就独立执行多少次,分别初始化各个对象的属性。
5. 对象创建全过程
当执行 buddy = Dog(“Buddy“, 5) 时,Python 在底层严格按顺序执行以下步骤:
| 步骤 |
操作 |
代码示例 |
说明 |
| 1. 创建空对象 |
分配内存空间 |
buddy = Dog(“Buddy“, 5) |
Python 先创建一个“空壳”对象,但尚未初始化。 |
2. 调用 __new__ |
创建对象实例 |
__new__(cls, *args, **kwargs) |
这是一个静态方法,负责创建并返回一个新的实例。如果类中没有定义 __new__,则会调用父类的 __new__。通常我们不需要自己重写它。 |
3. 调用 __init__ |
初始化对象 |
__init__(self, name, age) |
如果 __new__ 返回了该类的实例,Python 会自动调用 __init__ 来初始化这个新对象,传入 self 以及调用时提供的参数。这是关键步骤! |
| 4. 返回对象 |
将对象赋值给变量 |
buddy = ... |
对象创建并初始化完成,可以赋值给变量使用了。 |
为什么强调“__init__只执行一次”?
这里的“一次”是针对单个对象的。创建 buddy 时,__init__ 为 buddy 执行一次;创建 max 时,__init__ 为 max 再执行一次。每个对象的初始化过程都是独立的。
6. __init__ vs __new__
为了更好地理解这两个特殊方法的执行顺序和分工,我们来看一个同时定义了它们的例子:
class Dog:
species = “Canis familiaris“
def __new__(cls, *args, **kwargs):
print(“1. __new__ 被调用“)
instance = super().__new__(cls)
return instance
def __init__(self, name, age):
print(“2. __init__ 被调用“)
self.name = name
self.age = age
# 创建对象
my_dog = Dog(“Buddy“, 3)
# 输出:
# 1. __new__ 被调用 # 步骤1:调用__new__方法创建实例
# 2. __init__ 被调用 # 步骤2:调用__init__方法初始化实例
# 再次创建对象,两个方法都会再次执行(每个对象独立)
another_dog = Dog(“Lucy“, 5)
# 同样会先打印“1. __new__ 被调用“,再打印“2. __init__ 被调用“
重要提示:
__new__ 负责“创建”对象(底层内存分配),在大多数场景下我们无需修改它。
__init__ 负责“初始化”对象(设置属性),这是我们编写Python类时必须掌握和编写的方法。
7. 一个完整的简单类示例
让我们将以上知识点整合,创建一个功能更丰富的 Dog 类:
class Dog:
“““一个简单的狗类“““
species = “Canis familiaris“ # 类属性 (所有实例共享)
def __init__(self, name, age):
“““构造方法,初始化实例属性“““
self.name = name # 实例属性
self.age = age # 实例属性
def description(self):
“““返回描述信息“““
return f“{self.name} is {self.age} years old“
def bark(self, sound):
“““狗叫方法“““
return f“{self.name} says {sound}“
# 创建两个 Dog 实例
my_dog = Dog(“Buddy“, 3)
your_dog = Dog(“Lucy“, 5)
print(my_dog.description()) # 输出: Buddy is 3 years old
print(your_dog.bark(“Woof“)) # 输出: Lucy says Woof
通过这个示例,你可以看到如何定义一个包含属性(species, name, age)和方法(description, bark)的完整类,并创建出行为各异的对象。希望这篇教程能帮助你扎实地迈入 Python 面向对象编程的大门。如果你在学习过程中有任何疑问,欢迎在云栈社区的技术论坛与更多开发者交流探讨。