django33全栈班2025年017 面向对象

91 阅读13分钟

前言

同学们,到目前为止,咱们一路携手共进,已经扎实地掌握了 Python 的基础语法,对字典、列表这些常用的数据结构也运用得颇为娴熟,函数相关知识更是不在话下,大家都做得非常棒!现在,咱们即将开启一段全新的、充满挑战与惊喜的学习旅程——是时候深入探索面向对象编程这一关键领域了。它就像是一扇通往更高级编程世界的大门,一旦推开,大家将会领略到 Python 更为强大的魅力,能够以一种全新的思维方式去构建复杂的程序,解决棘手的问题,让我们一起满怀热情地大步迈进吧!

什么是面向对象

面向对象编程(Object-Oriented Programming,简称 OOP)是一种极具影响力的编程范式,它将现实世界中的事物抽象为程序里的对象。每个对象宛如一个独立的 “小世界”,拥有描述自身状态的属性,以及能对外展现行为的方法。 类(Class)则是创建这些对象的蓝图。打个比方,若要制造汽车,汽车的设计图纸就如同类,它详细规定了一辆汽车应具备的部件(属性,如轮胎数量、车身颜色)以及能执行的操作(方法,如启动、刹车、加速)。依据这张图纸,就能生产出众多各具特色的汽车个体,这些汽车就是对象,它们虽基于同一蓝图,却有着不同的属性值,比如有的是红色车身、有的是蓝色,有的轮胎磨损快、有的崭新。 从软件设计视角看,面向对象编程具有三大显著特性:封装、继承与多态,它们好似三把利器,助力开发者打造出结构优良、易于维护与拓展的代码体系。封装把对象的内部数据和操作紧密包裹,仅对外暴露必要接口,恰似给对象穿上一层防护服,防止外部随意篡改,保障数据的完整性与安全性;继承允许子类顺承父类的特性,并能按需拓展,如同子女继承父母的部分基因,再发展出自身独特优势,减少代码重复编写;多态让不同对象对相同指令做出各异反应,就像不同动物听到 “叫一声” 的指令,狗汪汪、猫喵喵,使程序设计更为灵活、富有弹性。

类的定义和使用

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

    def show(self):
        print(self.name, self.age)


zs = User("张三", 18)
zs.show()

类的继承

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

    def show(self):
        print(self.name, self.age)


class Student(User):
    """继承以后自动拥有父类的属性和方法"""

    def __init__(self, name, age, score):
        super().__init__(name, age)
        self.score = score

    def show(self):
        super().show()
        print(self.score)


s = Student("张三", 18, 99)
s.show()

练习一:银行账户类

创建一个 BankAccount 类,具有以下属性和方法:

  • 属性:
    • account_number(账户号码)
    • balance(账户余额)
  • 方法:
    • __init__ 方法:初始化账户号码和账户余额,初始余额为 0。
    • deposit 方法:接受一个金额作为参数,将该金额添加到账户余额中,并打印出存款后的余额。
    • withdraw 方法:接受一个金额作为参数,如果账户余额足够,从账户中取出该金额并打印出取款后的余额;如果余额不足,打印出错误信息。
    • display_balance 方法:打印出当前账户的余额。
class BankAccount:
    def __init__(self, account_number):
        self.account_number = account_number
        self.balance = 0

    def deposit(self, amount):
        self.balance += amount
        print(f"存款成功,当前余额:{self.balance}")

    def withdraw(self, amount):
        if self.balance >= amount:
            self.balance -= amount
            print(f"取款成功,当前余额:{self.balance}")
        else:
            print("余额不足,取款失败")

    def display_balance(self):
        print(f"账户 {self.account_number} 的余额为:{self.balance}")


# 测试代码
account1 = BankAccount("123456789")
account1.deposit(1000)
account1.withdraw(200)
account1.display_balance()

练习二:车辆类和其子类

创建一个 Vehicle 类,具有以下属性和方法:

  • 属性:
    • make(制造商)
    • model(型号)
    • year(制造年份)
  • 方法:
    • __init__ 方法:初始化车辆的属性。
    • display_info 方法:打印车辆的信息(制造商、型号、制造年份)。

创建两个子类 CarMotorcycle,它们继承自 Vehicle 类,并且具有以下额外属性和方法:

  • Car 类:
    • 属性:
      • num_doors(车门数量)
    • 方法:
      • display_info 方法:调用父类的 display_info 方法,并打印车门数量。
  • Motorcycle 类:
    • 属性:
      • has_sidecar(是否有边车)
    • 方法:
      • display_info 方法:调用父类的 display_info 方法,并打印是否有边车。
class Vehicle:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    def display_info(self):
        print(f"制造商:{self.make},型号:{self.model},制造年份:{self.year}")


class Car(Vehicle):
    def __init__(self, make, model, year, num_doors):
        super().__init__(make, model, year)
        self.num_doors = num_doors

    def display_info(self):
        super().display_info()
        print(f"车门数量:{self.num_doors}")


class Motorcycle(Vehicle):
    def __init__(self, make, model, year, has_sidecar):
        super().__init__(make, model, year)
        self.has_sidecar = has_sidecar

    def display_info(self):
        super().display_info()
        print(f"是否有边车:{self.has_sidecar}")


# 测试代码
car = Car("Toyota", "Corolla", 2020, 4)
car.display_info()

motorcycle = Motorcycle("Honda", "CBR500R", 2021, False)
motorcycle.display_info()

练习三:形状类和多态性

创建一个 Shape 类,具有以下属性和方法:

  • 属性:
    • name(形状名称)
  • 方法:
    • __init__ 方法:初始化形状名称。
    • area 方法:打印出该形状的面积,该方法在 Shape 类中可以先不实现具体计算(使用 pass)。

创建两个子类 CircleRectangle,它们继承自 Shape 类,并且具有以下属性和方法:

  • Circle 类:
    • 属性:
      • radius(半径)
    • 方法:
      • area 方法:计算并打印圆形的面积(使用公式 A=πr2A = \pi r^2)。
  • Rectangle 类:
    • 属性:
      • length(长度)
      • width(宽度)
    • 方法:
      • area 方法:计算并打印矩形的面积(使用公式 A=lwA = lw)。
import math


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

    def area(self):
        pass


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

    def area(self):
        area = math.pi * self.radius ** 2
        print(f"{self.name} 的面积是:{area}")


class Rectangle(Shape):
    def __init__(self, name, length, width):
        super().__init__(name)
        self.length = length
        self.width = width

    def area(self):
        area = self.length * self.width
        print(f"{self.name} 的面积是:{area}")


# 测试代码
circle = Circle("Circle", 5)
circle.area()

rectangle = Rectangle("Rectangle", 4, 6)
rectangle.area()

练习四:学生和课程管理类

创建两个类 StudentCourse,具有以下属性和方法:

  • Student 类:
    • 属性:
      • name(学生姓名)
      • student_id(学生 ID)
      • courses(学生选修的课程列表,初始为空)
    • 方法:
      • __init__ 方法:初始化学生姓名和学生 ID。
      • enroll 方法:接受一个 Course 对象作为参数,将该课程添加到 courses 列表中,并打印出选课信息。
      • display_courses 方法:打印出学生选修的所有课程名称。
  • Course 类:
    • 属性:
      • name(课程名称)
      • course_id(课程 ID)
    • 方法:
      • __init__ 方法:初始化课程名称和课程 ID。
class Course:
    def __init__(self, name, course_id):
        self.name = name
        self.course_id = course_id


class Student:
    def __init__(self, name, student_id):
        self.name = name
        self.student_id = student_id
        self.courses = []

    def enroll(self, course):
        self.courses.append(course)
        print(f"{self.name} 选修了课程:{course.name}")

    def display_courses(self):
        print(f"{self.name} 选修的课程:")
        for course in self.courses:
            print(course.name)


# 测试代码
course1 = Course("Python Programming", "CS101")
course2 = Course("Data Structures", "CS201")

student1 = Student("张三", "S001")
student1.enroll(course1)
student1.enroll(course2)
student1.display_courses()

练习五:宠物商店类

创建一个 PetShop 类,具有以下属性和方法:

  • 属性:
    • name(商店名称)
    • pets(宠物列表,初始为空)
  • 方法:
    • __init__ 方法:初始化商店名称。
    • add_pet 方法:接受一个 Pet 对象作为参数,将该宠物添加到 pets 列表中,并打印出添加信息。
    • display_pets 方法:打印出商店中所有宠物的信息。

创建一个 Pet 类,具有以下属性和方法:

  • 属性:
    • name(宠物名称)
    • species(宠物种类)
  • 方法:
    • __init__ 方法:初始化宠物名称和种类。
    • display_info 方法:打印出宠物的名称和种类。
class Pet:
    def __init__(self, name, species):
        self.name = name
        self.species = species

    def display_info(self):
        print(f"宠物名称:{self.name},种类:{self.species}")


class PetShop:
    def __init__(self, name):
        self.name = name
        self.pets = []

    def add_pet(self, pet):
        self.pets.append(pet)
        print(f"宠物 {pet.name} 已添加到 {self.name} 商店。")

    def display_pets(self):
        print(f"{self.name} 商店中的宠物:")
        for pet in self.pets:
            pet.display_info()


# 测试代码
pet1 = Pet("旺财", "狗")
pet2 = Pet("咪咪", "猫")

pet_shop = PetShop("可爱宠物商店")
pet_shop.add_pet(pet1)
pet_shop.add_pet(pet2)
pet_shop.display_pets()

练习六:书籍类和书籍管理类

定义一个 Book 类,包含以下属性和方法:

  • 属性:
    • title(书名)
    • author(作者)
    • price(价格)
  • 方法:
    • __init__ 方法:初始化书籍的属性。
    • display_info 方法:打印书籍的信息,包括书名、作者和价格。
    • discount_price 方法:接受一个折扣率(0 到 1 之间)作为参数,计算并返回打折后的价格。

定义一个 BookManager 类,包含以下属性和方法:

  • 属性:
    • books(书籍列表,初始为空)
  • 方法:
    • __init__ 方法:初始化书籍列表。
    • add_book 方法:接受一个 Book 对象作为参数,将该书籍添加到 books 列表中,并打印添加信息。
    • display_all_books 方法:打印出所有书籍的信息。
class Book:
    def __init__(self, title, author, price):
        self.title = title
        self.author = author
        self.price = price

    def display_info(self):
        print(f"书名:{self.title},作者:{self.author},价格:{self.price}")

    def discount_price(self, discount_rate):
        if 0 <= discount_rate <= 1:
            return self.price * (1 - discount_rate)
        else:
            raise ValueError("折扣率必须在 0 到 1 之间")


class BookManager:
    def __init__(self):
        self.books = []

    def add_book(self, book):
        self.books.append(book)
        print(f"添加书籍:{book.title}")

    def display_all_books(self):
        for book in self.books:
            book.display_info()


# 测试代码
book1 = Book("Python 编程:从入门到实践", "Eric Matthes", 59.0)
book2 = Book("流畅的 Python", "Luciano Ramalho", 89.0)

manager = BookManager()
manager.add_book(book1)
manager.add_book(book2)
manager.display_all_books()

# 测试折扣功能
print(f"打折后的价格:{book1.discount_price(0.2)}")

练习七:员工类和部门类

定义一个 Employee 类,包含以下属性和方法:

  • 属性:
    • name(员工姓名)
    • employee_id(员工编号)
    • salary(员工薪资)
  • 方法:
    • __init__ 方法:初始化员工的属性。
    • raise_salary 方法:接受一个比例(如 0.1 表示 10% 的加薪)作为参数,将薪资按照该比例增加,并打印加薪后的薪资。
    • display_info 方法:打印员工的信息,包括姓名、编号和薪资。

定义一个 Department 类,包含以下属性和方法:

  • 属性:
    • name(部门名称)
    • employees(员工列表,初始为空)
  • 方法:
    • __init__ 方法:初始化部门名称。
    • add_employee 方法:接受一个 Employee 对象作为参数,将该员工添加到 employees 列表中,并打印添加信息。
    • display_all_employees 方法:打印出部门内所有员工的信息。
class Employee:
    def __init__(self, name, employee_id, salary):
        self.name = name
        self.employee_id = employee_id
        self.salary = salary

    def raise_salary(self, raise_percentage):
        self.salary *= (1 + raise_percentage)
        print(f"{self.name} 的新薪资:{self.salary}")

    def display_info(self):
        print(f"姓名:{self.name},编号:{self.employee_id},薪资:{self.salary}")


class Department:
    def __init__(self, name):
        self.name = name
        self.employees = []

    def add_employee(self, employee):
        self.employees.append(employee)
        print(f"添加员工:{employee.name}{self.name} 部门")

    def display_all_employees(self):
        print(f"{self.name} 部门的员工:")
        for employee in self.employees:
            employee.display_info()


# 测试代码
employee1 = Employee("张三", "E001", 5000)
employee2 = Employee("李四", "E002", 6000)

department = Department("研发部")
department.add_employee(employee1)
department.add_employee(employee2)
department.display_all_employees()

# 测试加薪功能
employee1.raise_salary(0.1)

练习八:图形计算器类

定义一个 Shape 类,包含以下属性和方法:

  • 属性:
    • name(图形名称)
  • 方法:
    • __init__ 方法:初始化图形名称。
    • area 方法:计算并返回图形的面积,此方法在 Shape 类中不实现具体计算,仅使用 pass
    • perimeter 方法:计算并返回图形的周长,此方法在 Shape 类中不实现具体计算,仅使用 pass

创建两个子类 TriangleSquare 继承自 Shape 类:

  • Triangle 类:
    • 属性:
      • base(底)
      • height(高)
      • side1
      • side2
      • side3
    • 方法:
      • __init__ 方法:初始化三角形的属性。
      • area 方法:根据公式 A=12bhA=\frac{1}{2}bh 计算并返回三角形的面积。
      • perimeter 方法:计算并返回三角形的周长,即三边之和。
  • Square 类:
    • 属性:
      • side(边长)
    • 方法:
      • __init__ 方法:初始化正方形的属性。
      • area 方法:根据公式 A=s2A = s^2 计算并返回正方形的面积。
      • perimeter 方法:根据公式 P=4sP = 4s 计算并返回正方形的周长。
class Shape:
    def __init__(self, name):
        self.name = name

    def area(self):
        pass

    def perimeter(self):
        pass


class Triangle(Shape):
    def __init__(self, name, base, height, side1, side2, side3):
        super().__init__(name)
        self.base = base
        self.height = height
        self.side1 = side1
        self.side2 = side2
        self.side3 = side3

    def area(self):
        return 0.5 * self.base * self.height

    def perimeter(self):
        return self.side1 + self.side2 + self.side3


class Square(Shape):
    def __init__(self, name, side):
        super().__init__(name)
        self.side = side

    def area(self):
        return self.side ** 2

    def perimeter(self):
        return 4 * self.side


# 测试代码
triangle = Triangle("三角形", 4, 3, 3, 4, 5)
print(f"三角形面积:{triangle.area()},周长:{triangle.perimeter()}")

square = Square("正方形", 5)
print(f"正方形面积:{square.area()},周长:{square.perimeter()}")

练习九:音乐播放列表类

定义一个 Song 类,包含以下属性和方法:

  • 属性:
    • title(歌曲标题)
    • artist(歌手)
    • duration(时长,以秒为单位)
  • 方法:
    • __init__ 方法:初始化歌曲的属性。
    • display_info 方法:打印歌曲的信息,包括标题、歌手和时长(转换为分钟和秒)。

定义一个 Playlist 类,包含以下属性和方法:

  • 属性:
    • name(播放列表名称)
    • songs(歌曲列表,初始为空)
  • 方法:
    • __init__ 方法:初始化播放列表的名称。
    • add_song 方法:接受一个 Song 对象作为参数,将该歌曲添加到 songs 列表中,并打印添加信息。
    • display_all_songs 方法:打印出播放列表中所有歌曲的信息。
    • total_duration 方法:计算并返回播放列表中所有歌曲的总时长(以秒为单位)。
class Song:
    def __init__(self, title, artist, duration):
        self.title = title
        self.artist = artist
        self.duration = duration

    def display_info(self):
        minutes = self.duration // 60
        seconds = self.duration % 60
        print(f"歌曲:{self.title},歌手:{self.artist},时长:{minutes}{seconds} 秒")


class Playlist:
    def __init__(self, name):
        self.name = name
        self.songs = []

    def add_song(self, song):
        self.songs.append(song)
        print(f"添加歌曲:{song.title}{self.name} 播放列表")

    def display_all_songs(self):
        print(f"{self.name} 播放列表中的歌曲:")
        for song in self.songs:
            song.display_info()

    def total_duration(self):
        total = 0
        for song in self.songs:
            total += song.duration
        return total


# 测试代码
song1 = Song("稻香", "周杰伦", 230)
song2 = Song("告白气球", "周杰伦", 200)

playlist = Playlist("周杰伦经典歌曲")
playlist.add_song(song1)
playlist.add_song(song2)
playlist.display_all_songs()
print(f"播放列表总时长:{playlist.total_duration()} 秒")

练习十:在线购物类

定义一个 Product 类,包含以下属性和方法:

  • 属性:
    • name(产品名称)
    • price(价格)
    • stock(库存数量)
  • 方法:
    • __init__ 方法:初始化产品的属性。
    • display_info 方法:打印产品的信息,包括名称、价格和库存。
    • buy 方法:接受一个购买数量作为参数,如果库存足够,减少库存并打印购买信息;如果库存不足,打印错误信息。
  1. 定义一个 ShoppingCart 类,包含以下属性和方法:
    • 属性:
      • products(产品列表,初始为空)
    • 方法:
      • __init__ 方法:初始化产品列表。
      • add_product 方法:接受一个 Product 对象和购买数量作为参数,如果库存足够,将产品添加到 products 列表中,减少产品库存,并打印添加信息;如果库存不足,打印错误信息。
      • display_cart 方法:打印购物车中的所有产品及其购买数量。
      • total_price 方法:计算并返回购物车中所有产品的总价。
class Product:
    def __init__(self, name, price, stock):
        self.name = name
        self.price = price
        self.stock = stock

    def display_info(self):
        print(f"产品:{self.name},价格:{self.price},库存:{self.stock}")

    def buy(self, quantity):
        if self.stock >= quantity:
            self.stock -= quantity
            print(f"购买了 {quantity}{self.name}")
        else:
            print(f"{self.name} 库存不足")


class ShoppingCart:
    def __init__(self):
        self.products = []

    def add_product(self, product, quantity):
        if product.stock >= quantity:
            self.products.append((product, quantity))
            product.stock -= quantity
            print(f"添加 {quantity}{product.name} 到购物车")
        else:
            print(f"{product.name} 库存不足,无法添加到购物车")

    def display_cart(self):
        print("购物车中的产品:")
        for product, quantity in self.products:
            print(f"产品:{product.name},数量:{quantity}")

    def total_price(self):
        total = 0
        for product, quantity in self.products:
            total += product.price * quantity
        return total


# 测试代码
product1 = Product("手机", 2000, 10)
product2 = Product("耳机", 200, 20)

cart = ShoppingCart()
cart.add_product(product1, 2)
cart.add_product(product2, 3)
cart.display_cart()
print(f"购物车总价:{cart.total_price()}")

总结

本节课咱们学习了什么是面向对象, 并做了大量的练习题来巩固.

宝子们,我在 Python 的世界里摸爬滚打十余载,积累了不少心得体会。如今想把这些年的经验和知识毫无保留地分享给有缘的小伙伴。要是你对 Python 学习感兴趣,欢迎来试听一二,也可以随时在评论区留言或者私信我,咱们一起探讨,共同进步,开启 Python 学习的奇妙之旅!

人生苦短, 我用Python, 坚持每天学习, 坚持每天进步一点点...