以下是Python基础学习第五课的完整内容,重点讲解面向对象编程(OOP)的核心概念,包括类与对象、继承、封装与多态,带你从“编写代码”迈向“设计程序”:
Python基础学习第五课:面向对象编程(OOP)入门
一、课程目标
1. 理解面向对象编程的核心思想:类、对象、属性、方法
2. 掌握类的定义与实例化,学会使用构造函数(
"__init__")
3. 理解继承、封装与多态的实现方式
4. 通过实际案例掌握OOP的设计方法
二、面向对象编程基础
1. 类与对象:抽象与实例
- 类(Class):对一类事物的抽象描述(如“汽车”),定义属性和方法。
- 对象(Object):类的具体实例(如“我的红色特斯拉”)。
类比:
- 类似“图纸”与“房子”的关系——类是图纸,对象是根据图纸建造的具体房子。
2. 定义类与创建对象
(1) 基础语法
class 类名:
def __init__(self, 参数1, 参数2): # 构造函数(初始化方法)
self.属性1 = 参数1 # 实例属性
self.属性2 = 参数2
def 方法名(self): # 实例方法
print("这是一个方法")
# 创建对象
对象名 = 类名(值1, 值2)
(2) 示例:定义“汽车”类
class Car:
def __init__(self, brand, color):
self.brand = brand # 品牌属性
self.color = color # 颜色属性
def drive(self): # 方法:驾驶
print(f"{self.color}的{self.brand}正在行驶...")
# 创建对象
my_car = Car("特斯拉", "红色")
my_car.drive() # 输出: 红色的特斯拉正在行驶...
三、类的核心特性
1. 构造函数(
"__init__")
- 作用:在创建对象时自动调用,用于初始化对象的属性。
- 注意:
-
"self"代表当前对象(必须作为第一个参数)。
- 可以定义多个参数,通过
"对象名=类名(值1, 值2...)"传入。
示例:带默认参数的构造函数
class Car:
def __init__(self, brand, color="白色"): # color默认为白色
self.brand = brand
self.color = color
my_car1 = Car("宝马") # color使用默认值"白色"
my_car2 = Car("奥迪", "黑色") # color指定为"黑色"
2. 实例属性与实例方法
- 实例属性:属于具体对象的属性(如
"my_car.brand")。
- 实例方法:通过对象调用的方法,操作对象的属性。
示例:添加属性和方法
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
self.speed = 0 # 初始速度为0
def accelerate(self, increment):
self.speed += increment
print(f"加速到{self.speed}km/h")
def brake(self, decrement):
self.speed = max(0, self.speed - decrement) # 速度不低于0
print(f"减速到{self.speed}km/h")
my_car = Car("奔驰", "蓝色")
my_car.accelerate(30) # 输出: 加速到30km/h
my_car.brake(10) # 输出: 减速到20km/h
3. 继承:子类复用父类的功能
- 定义:子类继承父类的属性和方法,并可扩展新功能。
- 语法:
class 子类名(父类名):
def 新增方法(self):
pass
示例:电动车继承汽车
class ElectricCar(Car): # 继承Car类
def __init__(self, brand, color, battery_capacity):
super().__init__(brand, color) # 调用父类的构造函数
self.battery_capacity = battery_capacity # 新增属性
def charge(self): # 新增方法
print("正在充电...")
ev = ElectricCar("特斯拉", "红色", 75)
ev.drive() # 继承自父类的方法
ev.charge() # 子类新增的方法
4. 封装:隐藏内部细节
- 目的:保护数据不被随意修改,通过方法控制访问。
- 实现方式:
- 将属性设为私有(命名前加双下划线
"__"),通过
"getter/setter"方法访问。
示例:封装汽车速度
class Car:
def __init__(self, brand, color):
self.brand = brand
self.__speed = 0 # 私有属性(外部无法直接访问)
def get_speed(self): # getter方法
return self.__speed
def set_speed(self, value): # setter方法
if value >= 0:
self.__speed = value
else:
print("速度不能为负!")
my_car = Car("宝马", "黑色")
my_car.set_speed(50)
print(my_car.get_speed()) # 输出: 50
# print(my_car.__speed) # 报错!私有属性无法直接访问
5. 多态:同一方法不同行为
- 定义:不同子类对同一方法有不同的实现。
- 示例:动物叫声的多态
class Animal:
def speak(self):
print("动物发出声音")
class Dog(Animal):
def speak(self): # 重写父类方法
print("汪汪汪!")
class Cat(Animal):
def speak(self):
print("喵喵喵!")
def animal_sound(animal): # 接收任意Animal子类对象
animal.speak()
dog = Dog()
cat = Cat()
animal_sound(dog) # 输出: 汪汪汪!
animal_sound(cat) # 输出: 喵喵喵!
四、综合案例:游戏角色系统
设计一个简单的游戏角色系统,演示OOP的综合应用:
class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hp
def attack(self, target):
print(f"{self.name}攻击了{target.name}!")
def show_status(self):
print(f"{self.name}的生命值: {self.hp}")
class Warrior(Character): # 战士类
def __init__(self, name, hp, strength):
super().__init__(name, hp)
self.strength = strength
def attack(self, target): # 重写攻击方法
damage = self.strength * 2
target.hp -= damage
print(f"{self.name}用剑砍向{target.name},造成{damage}点伤害!")
class Mage(Character): # 法师类
def __init__(self, name, hp, magic_power):
super().__init__(name, hp)
self.magic_power = magic_power
def attack(self, target): # 重写攻击方法
damage = self.magic_power * 3
target.hp -= damage
print(f"{self.name}释放火球术,{target.name}受到{damage}点伤害!")
# 创建角色并战斗
warrior = Warrior("战士", 100, 10)
mage = Mage("法师", 80, 15)
warrior.attack(mage)
mage.show_status() # 输出法师剩余生命值
五、课后练习
1. 基础题:
- 定义一个
"Book"类,包含属性
"title"(书名)、
"author"(作者),方法
"show_info()"打印书籍信息。
- 创建两个
"Book"对象,调用
"show_info()"方法。
2. 进阶题:
- 设计一个
"BankAccount"类,包含属性
"balance"(余额),方法
"deposit()"(存款)和
"withdraw()"(取款,需检查余额是否足够)。
- 创建子类
"CreditCard",新增属性
"credit_limit"(信用额度),重写
"withdraw()"方法支持透支。
六、常见问题解答
1. Q:类名和对象名的命名规范是什么?A:类名通常用大驼峰命名法(如
"MyClass"),对象名用小写字母+下划线(如
"my_object")。
2. Q:继承时,子类一定能访问父类的所有属性和方法吗?A:不能!若父类属性/方法被封装(如定义为私有),子类需通过父类提供的
"getter/setter"方法访问。
3. Q:多态一定需要继承吗?A:不一定!Python支持“鸭子类型”(Duck Typing),只要对象实现了相同的方法名,即可实现多态(不依赖继承关系)。
通过本课,你已掌握Python面向对象编程的核心技能!下一步将学习文件与异常的高级应用或常用标准库的使用,进一步提升项目开发能力。