← 返回主页

第6课: 面向对象编程

类与对象

面向对象编程(OOP)是一种编程范式,将数据和操作数据的方法封装在一起。

定义类

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        print(f"{self.name}在叫:汪汪汪!")

    def get_info(self):
        return f"{self.name}今年{self.age}岁"

# 创建对象
my_dog = Dog("旺财", 3)
print(my_dog.name)      # 旺财
print(my_dog.get_info()) # 旺财今年3岁
my_dog.bark()           # 旺财在叫:汪汪汪!

构造函数 __init__

class Person:
    def __init__(self, name, age):
        self.name = name    # 实例属性
        self.age = age
        print(f"创建了一个Person对象: {name}")

    def introduce(self):
        print(f"我叫{self.name},今年{self.age}岁")

person = Person("张三", 25)
person.introduce()

类属性与实例属性

class Student:
    school = "清华大学"  # 类属性,所有实例共享

    def __init__(self, name, grade):
        self.name = name      # 实例属性,每个实例独有
        self.grade = grade

s1 = Student("张三", "大一")
s2 = Student("李四", "大二")

print(s1.school)  # 清华大学
print(s2.school)  # 清华大学

# 修改类属性
Student.school = "北京大学"
print(s1.school)  # 北京大学
print(s2.school)  # 北京大学

继承

继承允许创建新类来扩展现有类的功能。

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print(f"{self.name}发出声音")

class Dog(Animal):
    def speak(self):
        print(f"{self.name}说:汪汪汪!")

class Cat(Animal):
    def speak(self):
        print(f"{self.name}说:喵喵喵!")

dog = Dog("旺财")
cat = Cat("咪咪")

dog.speak()  # 旺财说:汪汪汪!
cat.speak()  # 咪咪说:喵喵喵!

super()函数

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

class Student(Person):
    def __init__(self, name, age, student_id):
        super().__init__(name, age)  # 调用父类构造函数
        self.student_id = student_id

    def get_info(self):
        return f"学生{self.name},{self.age}岁,学号{self.student_id}"

student = Student("张三", 20, "2024001")
print(student.get_info())

封装

使用私有属性和方法来隐藏内部实现细节。

class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner
        self.__balance = balance  # 私有属性(双下划线开头)

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            print(f"存入{amount}元,余额{self.__balance}元")

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            print(f"取出{amount}元,余额{self.__balance}元")
        else:
            print("余额不足")

    def get_balance(self):
        return self.__balance

account = BankAccount("张三", 1000)
account.deposit(500)
account.withdraw(300)
print(f"当前余额: {account.get_balance()}")
# print(account.__balance)  # 错误:无法直接访问私有属性

多态

不同类的对象可以通过相同的接口进行操作。

class Shape:
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

# 多态:不同对象调用相同方法
shapes = [Rectangle(5, 3), Circle(4)]

for shape in shapes:
    print(f"面积: {shape.area()}")

特殊方法

Python提供了许多特殊方法(魔术方法)来定制类的行为。

class Book:
    def __init__(self, title, author, pages):
        self.title = title
        self.author = author
        self.pages = pages

    def __str__(self):
        return f"《{self.title}》- {self.author}"

    def __repr__(self):
        return f"Book('{self.title}', '{self.author}', {self.pages})"

    def __len__(self):
        return self.pages

    def __eq__(self, other):
        return self.title == other.title

book1 = Book("Python编程", "张三", 300)
book2 = Book("Python编程", "李四", 300)

print(book1)           # 《Python编程》- 张三
print(len(book1))      # 300
print(book1 == book2)  # True

类方法和静态方法

class MathUtils:
    pi = 3.14159

    @classmethod
    def circle_area(cls, radius):
        return cls.pi * radius ** 2

    @staticmethod
    def add(a, b):
        return a + b

# 调用类方法
print(MathUtils.circle_area(5))  # 78.53975

# 调用静态方法
print(MathUtils.add(10, 20))     # 30

属性装饰器

class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius

    @property
    def celsius(self):
        return self._celsius

    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("温度不能低于绝对零度")
        self._celsius = value

    @property
    def fahrenheit(self):
        return self._celsius * 9/5 + 32

temp = Temperature(25)
print(temp.celsius)      # 25
print(temp.fahrenheit)   # 77.0

temp.celsius = 30
print(temp.fahrenheit)   # 86.0

练习

  1. 创建一个Car类,包含品牌、型号、价格属性和启动、停止方法
  2. 创建一个Rectangle类和Circle类,都继承自Shape类,实现计算面积和周长的方法
  3. 创建一个Student类,使用私有属性存储成绩,提供添加成绩和计算平均分的方法
  4. 实现一个简单的图书管理系统,包含Book类和Library类
练习答案:
# 练习1:Car类
class Car:
    def __init__(self, brand, model, price):
        self.brand = brand
        self.model = model
        self.price = price
        self.is_running = False

    def start(self):
        self.is_running = True
        print(f"{self.brand} {self.model}已启动")

    def stop(self):
        self.is_running = False
        print(f"{self.brand} {self.model}已停止")

car = Car("特斯拉", "Model 3", 299000)
car.start()

# 练习3:Student类
class Student:
    def __init__(self, name):
        self.name = name
        self.__scores = []

    def add_score(self, score):
        if 0 <= score <= 100:
            self.__scores.append(score)

    def get_average(self):
        if self.__scores:
            return sum(self.__scores) / len(self.__scores)
        return 0

student = Student("张三")
student.add_score(85)
student.add_score(90)
student.add_score(88)
print(f"平均分: {student.get_average()}")