25·模块七:面向对象编程进阶

面向对象编程:类与对象

oopclassesobjects

第25课:面向对象编程:类与对象

1. 学习目标

通过本节课的学习,你将能够:

  • 理解面向对象编程(OOP)中"类"和"对象"的核心概念及其关系。
  • 掌握如何定义一个简单的类,并使用它来创建对象。
  • 理解并区分对象的"属性"和"方法"。
  • 掌握 self 参数在类的方法中的基本作用。
  • 能够为对象动态地添加和修改属性。

2. 核心概念

类(Class) 可以理解为一张"图纸"或"蓝图"。它描述了一类事物共有的特征(属性)和行为(方法)。例如,"汽车"这个类定义了所有汽车都应该有颜色、品牌等特征,以及启动、行驶等行为。

对象(Object) 是根据"类"这张图纸制造出来的具体"产品"或"实例"。每一辆根据"汽车"图纸制造出来的具体车(如"我的那辆红色特斯拉"),都是一个对象。对象拥有类中定义的属性和方法。

简而言之:类是模板,对象是实例。

属性(Attribute) 是描述对象状态的数据,通常以变量的形式存在。例如,汽车的颜色品牌当前速度

方法(Method) 是描述对象可以执行的操作,通常以函数的形式存在。例如,汽车的启动()加速()刹车()

3. 代码示例

# 定义一个名为 `Dog` 的类
class Dog:
    # 这是一个类属性,所有 `Dog` 类的对象共享这个属性
    species = "Canis familiaris"

    # 定义一个方法:所有狗都会"汪汪叫"
    # 注意:每个方法的第一个参数都是 `self`,它代表调用这个方法的对象实例本身
    def bark(self):
        return "汪汪!"

# 现在,我们根据 `Dog` 类这个蓝图,来创建两个具体的"对象"(实例)
my_dog = Dog()
your_dog = Dog()

# 为 `my_dog` 这个对象添加实例属性(每个对象独有的属性)
my_dog.name = "旺财"
my_dog.age = 3

# 为 `your_dog` 这个对象添加实例属性
your_dog.name = "来福"
your_dog.age = 2

# 访问对象的属性
print(f"我的狗叫 {my_dog.name},它{my_dog.age}岁了。")
print(f"你的狗叫 {your_dog.name},它{your_dog.age}岁了。")

# 访问类属性(通过类名或任意一个对象访问)
print(f"所有狗的物种都是:{Dog.species}")
print(f"我的狗的物种也是:{my_dog.species}")

# 调用对象的方法
print(f"{my_dog.name} 说:{my_dog.bark()}")
print(f"{your_dog.name} 说:{your_dog.bark()}")

运行结果:

我的狗叫 旺财,它3岁了。
你的狗叫 来福,它2岁了。
所有狗的物种都是:Canis familiaris
我的狗的物种也是:Canis familiaris
旺财 说:汪汪!
来福 说:汪汪!

self 参数解释:bark(self) 方法中,self 是一个约定俗成的参数名,它指向调用该方法的对象实例。当你调用 my_dog.bark() 时,Python 解释器会自动将 my_dog 对象作为第一个参数传递给 bark 方法,这就是 self。通过 self,方法内部可以访问该对象自己的属性和其他方法。

4. 实践练习

练习1:创建你的第一个类

  • 定义一个名为 Car 的类。
  • 给这个类添加一个类属性 wheels,值为 4
  • 创建一个 Car 类的对象 my_car
  • my_car 对象添加实例属性 brand (例如 "Toyota") 和 color (例如 "Blue")。
  • 打印出 my_carbrandcolorwheels 属性。
  • 预期输出示例
    我的车是蓝色的丰田,它有4个轮子。
    

练习2:添加方法

  • 在练习1的 Car 类中,添加一个方法 describe()
  • 这个方法应该使用 self 参数来访问对象的 brandcolor 属性,并返回一个描述字符串,例如 "这是一辆蓝色的丰田。"。
  • 创建一个新对象 your_car,并为其设置属性。
  • 分别调用 my_caryour_cardescribe() 方法并打印结果。

练习3:动态修改属性

  • 接续练习2,将 my_carcolor 属性从 "Blue" 修改为 "Red"。
  • 再次调用 my_car.describe() 方法,观察输出的变化。
  • 预期输出示例
    这是一辆蓝色的丰田。
    这是一辆白色的本田。
    这是一辆红色的丰田。 # 颜色已改变
    

5. 常见错误

  1. 忘记 self 参数:在定义类的方法时,忘记在参数列表中加上 self。这会导致在调用方法时出现 TypeError: 方法名() takes 0 positional arguments but 1 was given 错误,因为 Python 会自动传入实例作为第一个参数。

    # 错误示例
    class MyClass:
        def say_hello(): # 缺少 self
            print("Hello")
    
    obj = MyClass()
    obj.say_hello() # 报错
    
  2. 混淆类属性和实例属性:试图通过对象去修改一个类属性,这通常不会修改类本身,而是会为这个对象创建一个同名的实例属性,从而"遮蔽"了类属性。

    class Dog:
        species = "Canis familiaris"
    
    dog1 = Dog()
    dog1.species = "Wolf" # 这为dog1创建了一个新的实例属性 `species`
    print(dog1.species)   # 输出: Wolf (访问的是实例属性)
    print(Dog.species)    # 输出: Canis familiaris (类属性未改变)
    dog2 = Dog()
    print(dog2.species)   # 输出: Canis familiaris (dog2没有实例属性,所以访问类属性)
    
  3. 误用类名调用实例方法:实例方法必须通过对象来调用,不能直接用类名调用,除非该方法被明确声明为静态方法或类方法(后续课程会讲)。

    class MyClass:
        def instance_method(self):
            return "I am an instance method."
    
    # MyClass.instance_method() # 错误!缺少实例参数
    obj = MyClass()
    obj.instance_method() # 正确
    

6. 小结

  • 是创建对象的模板,定义了对象应有的属性和行为。
  • 对象是类的实例,是具体存在的实体。
  • 属性用于存储对象的状态数据,分为所有实例共享的类属性和每个实例独有的实例属性
  • 方法定义了对象可以执行的操作,本质上是定义在类中的函数。
  • self 是类的方法中必备的第一个参数,它代表方法被调用时的实例对象本身,通过它才能访问该对象的属性和其它方法。
  • 对象的属性可以在创建后动态地添加或修改。

理解了类和对象的基本概念,我们就能以一种更结构化、更贴近现实世界建模的方式来组织代码。下一课,我们将学习一个特殊的方法 __init__,它能让我们在创建对象时,就自动地为其属性进行初始化,使代码更加整洁和强大。

练习编辑器

python
Loading...

继续学习

完成本课后,建议继续学习下一课「__init__ 方法与对象初始化」 以巩固所学知识。