返回博客

15. 类与实例:面向对象编程基础

15. 类与实例:面向对象编程基础

第十五篇:类与实例:面向对象编程基础

前言

面向对象的编程(OOP)是 Python 最重要的编程范式之一。本文讲解类的定义、实例的创建、构造方法 __init__、实例属性与方法绑定,以及 self 参数的含义。

什么是类和实例?

核心概念

class Dog:
    pass

my_dog = Dog()   # my_dog 是一个实例
your_dog = Dog() # another instance
# 类比:类 = 建筑设计图,实例 = 具体房屋

定义类的基本结构

class Dog:
    """表示一只狗"""
    
    def __init__(self, name, age):
        self.name = name   # 实例属性
        self.age = age
    
    def bark(self):        # 实例方法
        print(f"{self.name} 汪汪叫!")
    
    def info(self):
        return f"{self.name}, {self.age}岁"

dog1 = Dog("旺财", 3)
dog2 = Dog("小花", 5)
print(dog1.info())     # 旺财,3 岁
dog1.bark()            # 旺财汪汪叫!

self 参数详解

self 是什么?

self 代表实例本身,让你可以在方法中访问该实例的属性和其他方法。

class Person:
    def __init__(self, name):
        self.name = name
    
    def greet(self):
        print(f"你好,我是{self.name}")
    
    def compare(self, other):
        if self.name == other.name:
            print(f"{self.name} 和 {other.name} 同名")
        else:
            print(f"{self.name} ≠ {other.name}")

alice = Person("Alice")
bob = Person("Bob")
alice.greet()              # 你好,我是 Alice
alice.compare(bob)         # Alice ≠ Bob

关键点:

  • self 不是关键字,只是惯例
  • Python 自动传递 self,无需显式传入
  • self 指向调用该方法的实例

实例属性 vs 类属性

class Student:
    school = "阳光中学"  # 类属性 - 所有实例共享
    
    def __init__(self, name, score):
        self.name = name      # 实例属性 - 每个实例独立
        self.score = score

s1 = Student("张三", 95)
s2 = Student("李四", 88)

print(s1.school)   # 阳光中学
Student.school = "新阳光中学"  # 修改影响所有实例
s1.score = 100       # 只影响 s1

动态添加/删除属性

cat = Cat("咪咪")
cat.color = "白色"     # 动态添加
del cat.weight          # 动态删除

魔术方法(特殊方法)

init 构造方法

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height

rect = Rectangle(10, 5)  # 创建时自动调用
print(rect.area())       # 50

str 和 repr 字符串表示

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):
        return f"点 ({self.x}, {self.y})"  # 用户友好
    
    def __repr__(self):
        return f"Point({self.x}, {self.y})"  # 开发者调试用

p = Point(3, 4)
print(str(p))      # 点 (3, 4)
print(repr(p))     # Point(3, 4)

其他常用魔术方法速查

魔术方法 触发场景 示例
__len__ len(obj) 返回长度
__add__ a + b 加法运算
__eq__ a == b 相等比较
__lt__ a < b 小于比较
__hash__ hash(obj) 哈希值
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
    
    def __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)
    
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
    
    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2)  # Vector(4, 6)
print(v1 * 3)   # Vector(3, 6)
print(v1 == v2) # False

继承入门

代码复用

class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def speak(self):
        raise NotImplementedError("子类必须实现")
    
    def info(self):
        return f"{self.name}, {self.age}岁"

class Dog(Animal):  # Dog 继承自 Animal
    def __init__(self, name, age, breed):
        super().__init__(name, age)  # 调用父类构造
        self.breed = breed
    
    def speak(self):
        return "汪汪汪!"

class Cat(Animal):
    def __init__(self, name, age, color):
        super().__init__(name, age)
        self.color = color
    
    def speak(self):
        return "喵喵喵~"

dog = Dog("旺财", 3, "金毛")
cat = Cat("咪咪", 2, "白色")
print(dog.info())      # 旺财,3 岁
print(dog.speak())     # 汪汪汪!

super() 的作用

class Base:
    def __init__(self, value):
        self.value = value
        print("Base.__init__")

class Child(Base):
    def __init__(self, value, extra):
        super().__init__(value)  # 调用父类构造
        self.extra = extra
        print("Child.__init__")

child = Child(10, "test")
# Base.__init__ → Child.__init__

方法重写

class Vehicle:
    def describe(self):
        return "交通工具"

class Car(Vehicle):
    def describe(self):
        return "汽车 — 有轮子能跑"

class Bicycle(Vehicle):
    def describe(self):
        return "自行车 — 人力驱动"

for v in [Car(), Bicycle()]:
    print(v.describe())

OOP 优势对比

# ❌ 面向过程:数据与逻辑分离
students_data = [{"name": "A", "score": 95}]
def get_avg(data): ...

# ✅ 面向对象:数据与行为绑定
class StudentDatabase:
    def __init__(self, students):
        self.students = students
    def get_average(self): ...
    def sort_by_score(self): ...

实战:学生管理系统

class Student:
    def __init__(self, name, sid):
        self.name = name
        self.sid = sid
        self.grades = {}
    
    def add_grade(self, subject, grade):
        self.grades[subject] = grade
    
    def get_average(self):
        if not self.grades:
            return 0
        return sum(self.grades.values()) / len(self.grades)
    
    def __str__(self):
        avg = self.get_average()
        return f"{self.name} ({self.sid}) — 平均分:{avg:.1f}"

school = School("阳光中学")
s1 = Student("张三", "001")
s1.add_grade("数学", 95)
s1.add_grade("英语", 88)
school.add_student(s1)
school.display_all()

总结

  1. 类和实例 — 类是蓝图,实例是具体对象
  2. self 参数 — 指向实例本身的引用,用于访问属性和方法
  3. 实例属性 vs 类属性 — 实例属性独立,类属性共享
  4. 魔术方法 — __init__ 构造、__str__/__repr__ 字符串表示
  5. 继承 — 子类扩展父类功能,使用 super() 调用父类方法
  6. 方法重写 — 子类覆盖父类方法实现定制行为
  7. OOP 优势 — 数据与行为封装,提高代码复用性和可维护性
  8. 实战应用 — 学生管理系统的完整实现

下一篇文章将深入讲解访问限制:私有属性、封装机制与 getter/setter。


本文是 Python 教程系列的第十五篇。