Python面向对象编程(小白入门)
说明:本文兼顾有C++/Java背景的程序员和零基础小白,用最通俗的语言配合详细的代码和运行结果,帮助你彻底理解面向对象编程。
第一章:为什么要学面向对象?
1.1 故事版解释:什么是"对象"?
想象一下,你在玩一款游戏,比如《王者荣耀》或者《原神》。
游戏里面有很多"英雄"或者"角色",每个角色都有:
- 属性(数据):比如生命值、攻击力、防御力、等级、装备
- 技能(行为/方法):比如普通攻击、必杀技、闪现、治疗
在面向对象编程(OOP)里,我们把每一个游戏角色看作一个对象(Object)。
通俗理解:对象就像是一个"东西",它有自己的"特征"(属性)和"能力"(方法)。
1.2 对比:过程式 vs 面向对象
让我用一个具体的例子来说明两者的区别。
场景:计算圆的面积
过程式写法(像C语言那样):
# 这就是过程式编程:数据和函数是分开的
# 第1步:定义数据
radius = 5 # 圆的半径
pi = 3.14159 # 圆周率
# 第2步:定义函数(操作数据)
def calculate_circle_area(r):
"""计算圆的面积"""
return pi * r * r
# 第3步:调用函数
area = calculate_circle_area(radius)
print("圆的面积是:", area)
运行结果:
圆的面积是: 78.53975
面向对象写法:
# 面向对象:把数据和操作封装在一起
class Circle:
"""这是一个"圆"类"""
# 初始化方法,创建对象时会自动调用
def __init__(self, radius):
# self.radius 是对象的属性(特征)
self.radius = radius
self.pi = 3.14159
# 这是对象的方法(能力)
def calculate_area(self):
"""计算圆的面积"""
return self.pi * self.radius * self.radius
# 创建(实例化)一个Circle对象
my_circle = Circle(5) # 创建一个半径为5的圆
# 调用对象的方法
area = my_circle.calculate_area()
print("圆的面积是:", area)
运行结果:
圆的面积是: 78.53975
两种写法有什么区别?
| 对比项 | 过程式 | 面向对象 |
|---|---|---|
| 数据在哪里? | 分散的变量 | 封装在对象里 |
| 函数在哪里? | 独立的函数 | 对象的方法 |
| 好处 | 简单直接 | 更好管理、更像现实世界 |
通俗比喻:
- 过程式就像去菜市场买菜,老板把白菜、土豆、萝卜分别放在不同的摊位上,你得自己去取
- 面向对象就像去超市买菜,已经被分类包装好了,你需要什么直接拿对应的袋子
第二章:Python类和对象基础
2.1 什么是类(Class)?
类就像是一个"模板"或者"模具"。
举例说明:
- 类 = "人类"的概念(抽象的)
- 对象 = 张三、李四、王五(具体的实例)
一句话理解:类定义了一个"种类"的事物有什么特征和行为,但类本身不是具体的东西。具体的东西叫做"对象"或"实例"。
2.2 第一个类:学生类
让我们从一个最简单的例子开始:
# 定义一个"学生"类
class Student:
"""这是一个学生类"""
# __init__ 是初始化方法,创建对象时自动调用
# self 代表创建出来的那个对象本身
def __init__(self, name, age):
# 给对象添加属性(特征)
self.name = name # 学生姓名
self.age = age # 学生年龄
# 定义一个方法(行为)
def introduce(self):
"""自我介绍"""
print(f"大家好,我叫{self.name},今年{self.age}岁")
# ========== 这里是使用类的代码 ==========
# 创建(实例化)一个学生对象
student1 = Student("张三", 18)
student2 = Student("李四", 19)
# 调用对象的方法
student1.introduce()
student2.introduce()
运行结果:
大家好,我叫张三,今年18岁
大家好,我叫李四,今年19岁
代码解释
第1行:class Student:
class是Python的关键字,表示要定义一个类Student是类的名字(可以自己取,一般首字母大写)
**第2行:"""这是一个学生类"""
- 这是类的文档字符串,说明这个类是干什么的
第4-6行:def __init__(self, name, age):
__init__是"初始化方法"的特殊名字- 当我们创建对象时(比如
Student("张三", 18)),这个方法会自动被调用 self是必须的参数,它代表"这个对象本身"name和age是创建对象时传入的参数
第8-9行:self.name = name
- 把传入的
name赋值给对象的name属性 self.name中的self.表示"这个对象的"
第12-13行:定义 introduce 方法
- 方法就是"函数",但它是属于对象的
- 方法的第一个参数必须是
self
第18-19行:创建对象
Student("张三", 18)这行代码会:- 调用
__init__方法 - 创建一个新的对象
- 把 “张三” 传给 name 参数,18 传给 age 参数
- 返回这个对象
- 调用
2.3 self 到底是什么?
self 是初学者最容易困惑的地方。让我详细解释:
class Dog:
"""狗类"""
def __init__(self, name, breed):
# self 就是正在创建的这个对象
# self.name 给这个对象添加了一个叫 name 的属性
self.name = name
self.breed = breed
def bark(self):
# 在方法内部使用 self.name,表示"这个对象的 name 属性"
print(f"{self.name} 汪汪叫!")
# ========== 测试 ==========
# 创建两个狗对象
dog1 = Dog("旺财", "土狗")
dog2 = Dog("小白", "萨摩耶")
# 调用方法
dog1.bark()
dog2.bark()
运行结果:
旺财 汪汪叫!
小白 汪汪叫!
self 的本质
想象一下,当你调用 dog1.bark() 时,Python 内部其实是这样执行的:
# 这只是 Python 内部的原理,实际不需要这样写
Dog.bark(dog1) # 把 dog1 对象传给 bark 方法
所以:
self就是"当前调用这个方法的那个对象"self.name就是"当前对象的 name 属性"
第三章:属性和方法的深入理解
3.1 对象的属性(数据)
属性就是对象保存的数据。每个对象都可以有自己的属性。
class Person:
"""人类"""
def __init__(self, name, age, gender):
# 这些都是实例属性:每个对象独立的属性
self.name = name # 姓名
self.age = age # 年龄
self.gender = gender # 性别
self.height = 170 # 身高(有默认值)
self.weight = 65 # 体重(有默认值)
def show_info(self):
"""显示个人信息"""
print("=" * 30)
print(f"姓名: {self.name}")
print(f"年龄: {self.age} 岁")
print(f"性别: {self.gender}")
print(f"身高: {self.height} cm")
print(f"体重: {self.weight} kg")
print("=" * 30)
# ========== 使用 ==========
# 创建两个person对象
p1 = Person("小明", 25, "男")
p2 = Person("小红", 22, "女")
# 修改 p1 的属性
p1.age = 26 # 过了生日,长大一岁
p1.height = 175 # 长高了
# 修改 p2 的属性
p2.weight = 55 # 减肥了
# 显示信息
p1.show_info()
p2.show_info()
运行结果:
==============================
姓名: 小明
年龄: 26 岁
性别: 男
身高: 175 cm
体重: 65 kg
==============================
==============================
姓名: 小红
年龄: 22 岁
性别: 女
身高: 170 cm
体重: 55 kg
==============================
重要说明:每个对象是独立的
class Dog:
def __init__(self, name):
self.name = name
# 创建两个狗
dog1 = Dog("旺财")
dog2 = Dog("小白")
# 修改 dog1 的名字
dog1.name = "大黄"
# 验证:dog1 和 dog2 是独立的
print(f"dog1.name = {dog1.name}") # 变成了 "大黄"
print(f"dog2.name = {dog2.name}") # 还是 "小白"
运行结果:
dog1.name = 大黄
dog2.name = 小白
3.2 对象的方法(行为)
方法是对象可以执行的操作。
普通方法:最常见
class Calculator:
"""计算器类"""
def __init__(self):
# 结果会保存这个属性里
self.result = 0
def add(self, x, y):
"""加法"""
self.result = x + y
return self.result
def subtract(self, x, y):
"""减法"""
self.result = x - y
return self.result
def show_result(self):
"""显示结果"""
print(f"计算结果是: {self.result}")
# ========== 使用 ==========
calc = Calculator()
# 调用加法
r = calc.add(10, 5)
print(f"10 + 5 = {r}")
# 调用减法
calc.subtract(20, 8)
calc.show_result()
运行结果:
10 + 5 = 15
计算结果是: 12
类变量 vs 实例变量
这是另一个容易混淆的概念:
class Student:
# 这是类变量:在类里面直接定义的变量
school_name = "阳光中学" # 所有学生都在这个学校
total_students = 0 # 学生总数
def __init__(self, name, age):
# 这是实例变量:在__init__里,用self.定义的变量
self.name = name # 每个学生有自己的名字
self.age = age # 每个学生有自己的年龄
# 修改类变量(学生数量+1)
Student.total_students += 1
def show_info(self):
"""显示学生信息"""
print(f"{self.name},{self.age}岁,就读于{self.school_name}")
# ========== 使用 ==========
# 创建学生对象
s1 = Student("张三", 15)
s2 = Student("李四", 16)
s3 = Student("王五", 15)
# 查看类变量
print(f"学校名称: {Student.school_name}")
print(f"学生总数: {Student.total_students}")
# 显示学生信息
s1.show_info()
s2.show_info()
运行结果:
学校名称: 阳光中学
学生总数: 3
张三,15岁,就读于阳光中学
李四,16岁,就读于阳光中学
王五,15岁,就读于阳光中学
类变量和实例变量的区别
| 特性 | 类变量 | 实例变量 |
|---|---|---|
| 定义位置 | 类里面,直接定义 | __init__ 方法里,用 self. |
| 归属 | 类本身 | 各个对象 |
| 共享 | 所有对象共享一份 | 每个对象独立一份 |
| 访问方式 | 类名.变量名 或 对象.变量名 |
只能通过 对象.变量名 |
第四章:面向对象的三大特性
面向对象有三大特性:封装、继承、多态。这是OOP的核心!
4.1 封装:把东西包装起来
封装就是把数据和操作封装在一起,隐藏内部细节,只暴露必要的接口。
为什么需要封装?
举例:你每天开车,不需要知道发动机是怎么工作的,只需要知道:
- 踩油门车会前进
- 踩刹车车会停下
- 方向盘控制方向
这就是"封装"的思想:把复杂的内部细节隐藏起来,只提供简单的接口。
Python中如何实现封装?
Python用"私有属性"来实现封装:
class BankAccount:
"""银行账户类"""
def __init__(self, owner, balance):
# self.__balance 中的 __ 表示"私有"
# Python 会把它变成 _BankAccount__balance
# 外部不能直接访问
self.owner = owner
self.__balance = balance # 私有属性:余额
self.__password = "123456" # 私有属性:密码
def deposit(self, amount):
"""存款:公共方法,外部可以调用"""
if amount > 0:
self.__balance += amount
print(f"存款成功!当前余额: {self.__balance}")
else:
print("存款金额必须大于0")
def withdraw(self, amount):
"""取款"""
if amount > self.__balance:
print("余额不足!")
elif amount > 0:
self.__balance -= amount
print(f"取款成功!当前余额: {self.__balance}")
else:
print("取款金额必须大于0")
def get_balance(self):
"""查看余额(受保护的方法)"""
return self.__balance
# ========== 使用 ==========
# 创建账户
account = BankAccount("张三", 1000)
# 正常的操作:通过公共方法
account.deposit(500) # 存款
account.withdraw(200) # 取款
# 查看余额
print(f"余额: {account.get_balance()}")
# 尝试直接访问私有属性(会报错)
print(f"尝试直接访问: {account.__balance}")
运行结果:
存款成功!当前余额: 1500
取款成功!当前余额: 1300
余额: 1300
Traceback (most recent call last):
File "xxx", line xxx, in <module>
print(f"尝试直接访问: {account.__balance}")
AttributeError: 'BankAccount' object has no attribute '__balance'
封装的优点
- 保护数据:防止外部随意修改重要数据
- 简化接口:用户只需要调用简单的方法
- 便于维护:内部实现可以随时改变,不影响外部
4.2 继承:像遗传一样
继承就是"子类"继承"父类"的属性和方法。
生活中的继承例子
- 儿子继承父亲的财产
- 狗继承"动物"的特性
- 汽车继承"交通工具"的特性
Python中如何实现继承?
# ========== 第1步:定义父类(基类)==========
class Animal:
"""动物类:父类/基类"""
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
"""吃东西"""
print(f"{self.name} 正在吃东西")
def sleep(self):
"""睡觉"""
print(f"{self.name} 正在睡觉")
def speak(self):
"""发出声音(父类不知道具体什么声音)"""
print(f"{self.name} 发出了声音")
# ========== 第2步:定义子类(继承父类)==========
class Dog(Animal):
"""狗类:继承自动物类"""
def __init__(self, name, age, breed):
# 调用父类的 __init__ 方法
super().__init__(name, age)
self.breed = breed # 狗特有的属性:品种
# 重写父类的方法
def speak(self):
"""重写发出声音的方法"""
print(f"{self.name} 汪汪叫!")
# 狗特有的方法
def fetch_ball(self):
"""捡球"""
print(f"{self.name} 跑去捡球了!")
class Cat(Animal):
"""猫类:继承自动物类"""
def __init__(self, name, age, color):
super().__init__(name, age)
self.color = color # 猫特有的属性:颜色
# 重写父类的方法
def speak(self):
"""重写发出声音的方法"""
print(f"{self.name} 喵喵叫!")
# 猫特有的方法
def climb_tree(self):
"""爬树"""
print(f"{self.name} 爬到树上去了!")
# ========== 使用 ==========
print("=== 创建动物 ===")
animal = Animal("小动物", 1)
animal.eat()
animal.sleep()
animal.speak()
print("\n=== 创建狗 ===")
dog = Dog("旺财", 3, "土狗")
dog.eat() # 继承自父类的方法
dog.sleep() # 继承自父类的方法
dog.speak() # 重写后的方法
dog.fetch_ball() # 狗特有的方法
print("\n=== 创建猫 ===")
cat = Cat("咪咪", 2, "橘色")
cat.eat() # 继承自父类
cat.speak() # 重写后的方法
cat.climb_tree() # 猫特有的方法
运行结果:
=== 创建动物 ===
小动物 正在吃东西
小动物 正在睡觉
小动物 发出了声音
=== 创建狗 ===
旺财 正在吃东西
旺财 正在睡觉
旺财 汪汪叫!
旺财 跑去捡球了!
=== 创建猫 ===
咪咪 正在吃东西
咪咪 喵喵叫!
咪咪 爬到树上去了!
继承的概念图
Animal (动物类 - 父类)
/ | \
/ | \
Dog Cat ... (子类)
(狗) (猫)
继承的核心要点
- 子类自动拥有父类的所有属性和方法
- 子类可以添加自己特有的属性和方法
- 子类可以"重写"(override)父类的方法
- 使用
super().__init__()调用父类的方法
4.3 多态:同一个方法,不同的表现
多态就是"同一个方法调用,不同对象有不同表现"。
生活中的多态例子
- "叫"这个动作:
- 人叫:“你好!”
- 狗叫:“汪汪!”
- 猫叫:“喵喵!”
- 鸭子叫:“嘎嘎!”
虽然都是"叫",但不同动物发出的声音不同,这就是多态。
Python中的多态
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} 喵喵叫!")
class Duck(Animal):
def speak(self):
print(f"{self.name} 嘎嘎叫!")
# ========== 多态的威力 ==========
def make_speak(animal):
"""让动物发出声音"""
# 不管传入什么动物,都能正确调用它的 speak 方法
animal.speak()
# 创建各种动物
dog = Dog("旺财")
cat = Cat("咪咪")
duck = Duck("唐老鸭")
# 调用同一个函数,不同对象表现不同
print("=== 多态演示 ===")
make_speak(dog) # 传入狗 -> 汪汪叫
make_speak(cat) # 传入猫 -> 喵喵叫
make_speak(duck) # 传入鸭子 -> 嘎嘎叫
运行结果:
=== 多态演示 ===
旺财 汪汪叫!
咪咪 喵喵叫!
唐老鸭 嘎嘎叫!
多态的好处
- 代码简洁:同一个函数可以处理不同类型的对象
- 易于扩展:添加新动物不需要修改
make_speak函数 - 符合开闭原则:对扩展开放,对修改封闭
第五章:高级特性
5.1 @property:像访问属性一样调用方法
有时候,我们不想让外部直接访问某个属性,但又要提供一个"查看"的方式。这时可以用 @property。
class Temperature:
"""温度类"""
def __init__(self, celsius):
self._celsius = celsius # 用 _ 表示"受保护的"
# @property 使方法可以像属性一样访问
@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(f"当前温度: {temp.celsius}°C")
print(f"华氏温度: {temp.fahrenheit}°F")
# 设置温度
temp.celsius = 30
print(f"修改后: {temp.celsius}°C")
# 设置无效温度(会报错)
try:
temp.celsius = -300
except ValueError as e:
print(f"错误: {e}")
运行结果:
当前温度: 25°C
华氏温度: 77.0°F
修改后: 30°C
错误: 温度不能低于绝对零度!
5.2 魔术方法:让对象支持内置操作
Python有很多以双下划线开头和结尾的方法,叫做"魔术方法"。它们让对象可以支持Python的内置操作。
str 和 repr:对象的字符串表示
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# str() 或 print() 时调用
def __str__(self):
return f"Person({self.name}, {self.name})"
# 直接输入对象名时调用(调试用)
def __repr__(self):
return f"Person(name='{self.name}', age={self.age})"
# ========== 使用 ==========
p = Person("张三", 25)
print(str(p)) # 使用 __str__
print(repr(p)) # 使用 __repr__
print(p) # 默认调用 __str__
运行结果:
Person(张三, 张三)
Person(name='张三', age=25)
Person(张三, 张三)
运算符重载:让对象支持数学运算
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 __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
# 字符串表示
def __str__(self):
return f"Vector({self.x}, {self.y})"
# ========== 使用 ==========
v1 = Vector(1, 2)
v2 = Vector(3, 4)
# 直接用 + 号相加
v3 = v1 + v2
v4 = v1 - v2
print(f"v1 = {v1}")
print(f"v2 = {v2}")
print(f"v1 + v2 = {v3}")
print(f"v1 - v2 = {v4}")
运行结果:
v1 = Vector(1, 2)
v2 = Vector(3, 4)
v1 + v2 = Vector(4, 6)
v1 - v2 = Vector(-2, -2)
5.3 类方法 vs 静态方法
Python中有三种方法:实例方法、类方法、静态方法。
class MathTools:
"""数学工具类"""
# 实例方法:第一个参数是 self
def power(self, base, exponent):
"""实例方法:计算幂"""
return base ** exponent
# 类方法:第一个参数是 cls(类本身)
@classmethod
def circle_area(cls, radius):
"""类方法:计算圆面积"""
return 3.14159 * radius ** 2
# 静态方法:没有 self 或 cls
@staticmethod
def max_value(a, b):
"""静态方法:返回最大值"""
return a if a > b else b
# ========== 使用 ==========
# 实例方法:需要创建对象
obj = MathTools()
print(f"2的10次方: {obj.power(2, 10)}")
# 类方法:直接用类名调用,不需要创建对象
print(f"半径为5的圆面积: {MathTools.circle_area(5)}")
# 静态方法:也可以用类名直接调用
print(f"最大值: {MathTools.max_value(10, 20)}")
print(f"最大值: {obj.max_value(10, 20)}") # 用对象调用也可以
运行结果:
2的10次方: 1024
半径为5的圆面积: 78.53975
最大值: 20
最大值: 20
三种方法的区别
| 类型 | 第一个参数 | 调用方式 | 适用场景 |
|---|---|---|---|
| 实例方法 | self |
对象.方法() |
操作实例数据 |
| 类方法 | cls |
类名.方法() |
操作类数据 |
| 静态方法 | 无 | 类名.方法() |
工具函数 |
第六章:综合实战
6.1 完整的例子:学生管理系统
让我们用面向对象的方式,实现一个简单的学生管理系统:
class Student:
"""学生类"""
def __init__(self, student_id, name, age, gender):
self.student_id = student_id
self.name = name
self.age = age
self.gender = gender
self.scores = {} # 科目:分数
def add_score(self, subject, score):
"""添加成绩"""
if 0 <= score <= 100:
self.scores[subject] = score
print(f"✓ 已添加 {self.name} 的 {subject} 成绩: {score}")
else:
print(f"✗ 成绩必须在0-100之间!")
def get_average(self):
"""获取平均分"""
if not self.scores:
return 0
return sum(self.scores.values()) / len(self.scores)
def show_info(self):
"""显示学生信息"""
print(f"\n{'='*40}")
print(f"学号: {self.student_id}")
print(f"姓名: {self.name}")
print(f"年龄: {self.age}")
print(f"性别: {self.gender}")
print("-" * 40)
print("成绩:")
if self.scores:
for subject, score in self.scores.items():
print(f" {subject}: {score}")
print(f"平均分: {self.get_average():.2f}")
else:
print(" 暂无成绩")
print(f"{'='*40}\n")
class StudentManager:
"""学生管理系统"""
def __init__(self):
self.students = {} # 学号: 学生对象
def add_student(self, student):
"""添加学生"""
if student.student_id in self.students:
print(f"✗ 学号 {student.student_id} 已存在!")
else:
self.students[student.student_id] = student
print(f"✓ 添加学生成功: {student.name}")
def find_student(self, student_id):
"""查找学生"""
return self.students.get(student_id)
def show_all(self):
"""显示所有学生"""
print("\n" + "="*50)
print(f"共有 {len(self.students)} 名学生")
print("="*50)
for student in self.students.values():
student.show_info()
def get_top_student(self):
"""获取成绩最高的学生"""
if not self.students:
return None
top_student = None
top_avg = -1
for student in self.students.values():
avg = student.get_average()
if avg > top_avg:
top_avg = avg
top_student = student
return top_student
# ========== 使用示例 ==========
print("=== 创建学生管理系统 ===")
manager = StudentManager()
# 创建学生
print("\n--- 添加学生 ---")
s1 = Student("001", "张三", 18, "男")
s2 = Student("002", "李四", 17, "女")
s3 = Student("003", "王五", 18, "男")
# 添加成绩
s1.add_score("数学", 85)
s1.add_score("语文", 90)
s1.add_score("英语", 88)
s2.add_score("数学", 92)
s2.add_score("语文", 78)
s2.add_score("英语", 95)
s3.add_score("数学", 70)
s3.add_score("语文", 85)
s3.add_score("英语", 80)
# 添加到管理系统
manager.add_student(s1)
manager.add_student(s2)
manager.add_student(s3)
# 显示所有学生
manager.show_all()
# 查找学生
print("\n--- 查找学生 ---")
student = manager.find_student("002")
if student:
student.show_info()
# 显示最高分学生
print("\n--- 成绩最高的学生 ---")
top = manager.get_top_student()
if top:
print(f"成绩最高的学生是: {top.name},平均分: {top.get_average():.2f}")
运行结果:
=== 创建学生管理系统 ===
--- 添加学生 ---
✓ 已添加 张三 的 数学 成绩: 85
✓ 已添加 张三 的 语文 成绩: 90
✓ 已添加 张三 的 英语 成绩: 88
✓ 已添加 张三 的 历史 成绩: 95
✓ 已添加 李四 的 数学 成绩: 92
✓ 已添加 李四 的 语文 成绩: 78
✓ 已添加 李四 的 英语 成绩: 95
✓ 已添加 王五 的 数学 成绩: 70
✓ 已添加 王五 的 语文 成绩: 85
✓ 已添加 王五 的 英语 成绩: 80
✓ 添加学生成功: 张三
✓ 添加学生成功: 李四
✓ 添加学生成功: 王五
==================================================
共有 3 名学生
==================================================
========================================
学号: 001
姓名: 张三
年龄: 18
性别: 男
----------------------------------------
成绩:
数学: 85
语文: 90
英语: 88
历史: 95
平均分: 89.50
========================================
========================================
学号: 002
姓名: 李四
年龄: 17
性别: 女
----------------------------------------
成绩:
数学: 92
语文: 78
英语: 95
平均分: 88.33
========================================
========================================
学号: 003
姓名: 王五
年龄: 18
性别: 男
----------------------------------------
成绩:
数学: 70
语文: 85
英语: 80
平均分: 78.33
========================================
--- 查找学生 ---
========================================
学号: 002
姓名: 李四
年龄: 17
性别: 女
----------------------------------------
成绩:
数学: 92
语文: 78
英语: 95
平均分: 88.33
========================================
--- 成绩最高的学生 ---
成绩最高的学生是: 张三,平均分: 89.50
第七章:常见问题和解答
Q1: 什么时候用面向对象?
简单原则:
- 如果只是简单的数据处理,函数就够了
- 如果有相关联的数据和行为,或者需要模拟现实世界的事物,用面向对象
Q2: 类变量和实例变量怎么选?
- 如果数据应该被所有对象共享,用类变量(如学校名字)
- 如果数据是每个对象特有的,用实例变量(如学生姓名)
Q3: 继承好还是组合好?
- 继承:"是"的关系(Dog 是 Animal)
- 组合:"有"的关系(Car 有 Engine)
优先使用组合,因为继承的耦合度太高。
Q4: 私有属性真的安全吗?
Python的私有属性只是"约定",不是真正的安全。可以用 _ClassName__attr 访问。但这是"不推荐"的做法。
总结
面向对象的三大核心概念
| 概念 | 通俗理解 | 关键词 |
|---|---|---|
| 封装 | 把数据和操作包装在一起 | 隐藏细节、保护数据 |
| 继承 | 子类拥有父类的特性 | 代码复用、扩展 |
| 多态 | 同一方法,不同表现 | 灵活、扩展性强 |
Python面向对象常用语法
# 定义类
class 类名:
def __init__(self, 参数):
self.属性 = 参数
def 方法(self, 参数):
# 方法代码
# 创建对象
对象 = 类名(参数)
# 调用方法
对象.方法(参数)
# 继承
class 子类(父类):
def __init__(self, 参数):
super().__init__(参数) # 调用父类
# 子类特有属性
def 方法(self): # 重写父类方法
# 新实现
学习面向对象是一个循序渐进的过程。建议:
- 先理解概念(封装、继承、多态)
- 多写代码练习
- 阅读优秀的开源代码
- 在实际项目中应用
掌握了面向对象编程,你就掌握了现代软件开发的核心思维。加油!💪
更多推荐



所有评论(0)