Python 面向对象编程基础
理解面向对象编程
在开始深入代码之前,我们需要先理解什么是面向对象(Object-Oriented Programming, OOP)。为了便于理解,我们可以将其与面向过程编程进行对比。
场景示例:肚子饿了,想吃饭
- 面向过程:去超市—买菜—卖肉—买米—回家—洗菜—切肉—炒菜—煮米饭—盛饭—开吃。这个过程关注的是具体的步骤和细节,每一步都需要手动执行。
- 面向对象:点外卖。用户只需要告诉系统'我要吃饭',系统内部会自动处理下单、配送、烹饪等复杂流程。用户无需关心内部实现,只需使用结果。
总结:面向对象就是将编程当成是一个事物,对外界来说,事物是直接使用的,不用去管它内部的情况。而编程就是设置事物能够做什么事。这种思想提高了代码的复用性、可维护性和扩展性。
类和对象
思考与定义
思考:打电话需要用手机,这个手机就是一个对象,这个对象哪来的呢? 答:它是制造出来的。 思考:怎么制造的? 答:先构思图纸,再生产。
在面向对象编程过程中,有两个重要组成部分:类和对象。
- 类和对象的关系:用类去创建一个对象。
1. 类(Class)
类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物。
- 特征即是属性:例如手机的屏幕大小、颜色、重量。
- 行为即是方法:例如打电话、玩游戏、拍照。
类好比是制造手机时要用到的图纸,也就是说类是用来创建对象的模板。
2. 对象(Object)
对象是类创建出来的真实存在的事物,例如:你手中的那部 iPhone 或华为手机。
注意:开发中,先有类,再有对象。类是蓝图,对象是实体。
面向对象实现方法
语法结构
class ClassName:
# 代码块
pass
注意:类名要满足标识符命名规则,同时遵循驼峰命名习惯(CamelCase),例如
MyPhone。
快速体验:
class MyProject:
print("我是第一个类")
创建对象
语法:
# 变量名 = 类名()
快速体验:
class MyPhone:
def call_tel(self):
print("正在打电话")
def play_game(self):
print("正在打游戏")
# 创建对象
apple = MyPhone()
print(apple)
# 调用对象的实例方法
apple.play_game()
创建对象的过程也叫实例化对象。
self 关键字
self 代表类的实例。
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,按照惯例它的名称是 self。
当调用 apple.play_game() 时,Python 解释器会自动将 apple 对象作为第一个参数传递给 play_game 方法,即相当于 MyPhone.play_game(apple)。
添加和获取对象属性
属性即是特征,比如:手机的颜色,大小,重量… 对象属性既可以在类外面添加和获取,也能在类里面添加和获取。
类外面添加对象属性
语法:
对象名。属性名 = 值
快速体验:
class MyPhone:
def main(self):
pass
apple = MyPhone()
apple.width = 10
apple.height = 15
print(apple.width)
print(apple.height)
类里面获取对象属性
语法:
self.属性名
快速体验:
class MyPhone:
def main(self):
print(self.width)
print(self.height)
apple = MyPhone()
apple.width = 10
apple.height = 15
apple.main()
魔术方法(Magic Methods)
在 Python 中,__xx__() 的函数叫做魔法方法,指的是具有特殊功能的函数。这些方法通常在特定事件发生时自动触发。
init() 初始化方法
问题:手机的尺寸大小生来就有,那么能不能在生产之前就赋予属性呢?
init():初始化对象。当创建对象时,该方法会被自动调用。
class MyPhone:
def __init__(self):
self.width = 10
self.height = 15
def main(self):
print(self.width)
print(self.height)
apple = MyPhone()
init() 方法,在创建一个对象时默认被调用,不需要手动调用。 init(self) 中的 self 参数,不需要开发者传递,python 解释器会自动把当前的对象引用传递过去。
带参数的 init
一个类可以创建多个对象,如何对不同的对象设置不同的初始化属性呢?传参即可。
class MyPhone:
def __init__(self, width, height):
self.width = width
self.height = height
def apple_phone(self):
print("苹果手机的宽为:", self.width)
print("苹果手机的高为:", self.height)
def huawei_phone(self):
print("华为手机的宽为:", self.width)
print("华为手机的高为:", self.height)
apple = MyPhone(10, 20)
apple.apple_phone()
str() 字符串表示
当使用 print 输出对象的时候,默认打印对象的内存地址。如果类定义了 str 方法,那么就会打印从在这个方法中 return 的数据。
解释类的属性或作用:
class Demo:
def __init__(self, width, height):
self.width = width
self.height = height
def __str__(self):
return f"你这个手机的宽是{self.width},高度是{self.height}"
a = Demo(10, 20)
print(a)
其他常用魔术方法
除了 __init__ 和 __str__,还有其他常用的魔术方法:
- repr():用于调试,通常返回一个能重新创建对象的字符串。
- len():定义对象长度,配合 len() 函数使用。
- call():使对象可调用,像函数一样使用。
- del():析构方法,对象销毁前调用。
类属性与方法
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。
class Demo:
__num = 0 # 私有属性
result = 0 # 公开属性
def count(self):
self.__num += 1
self.result += 1
print(self.__num)
run = Demo()
run.count()
run.count()
print(run.result)
print(run.__num) # 报错,实例不能访问私有变量
类变量与实例变量
- 实例变量:属于特定的对象,每个对象都有独立的副本。
- 类变量:属于类本身,所有对象共享同一个副本。
class Counter:
class_count = 0 # 类变量
def __init__(self):
self.instance_count = 0 # 实例变量
def increment(self):
self.instance_count += 1
Counter.class_count += 1
c1 = Counter()
c2 = Counter()
c1.increment()
c2.increment()
print(c1.instance_count) # 1
print(c2.instance_count) # 1
print(Counter.class_count) # 2 (共享)
静态方法与类方法
- @staticmethod:静态方法,不需要 self 或 cls 参数,不依赖对象状态。
- @classmethod:类方法,第一个参数是 cls,可以访问类变量。
class MathUtils:
@staticmethod
def add(x, y):
return x + y
@classmethod
def get_name(cls):
return cls.__name__
print(MathUtils.add(1, 2))
print(MathUtils.get_name())
继承与多态
继承(Inheritance)
继承允许我们定义一个子类,它继承父类的属性和方法,并可以添加新的功能。
class Animal:
def speak(self):
print("动物发出声音")
class Dog(Animal):
def speak(self):
print("汪汪叫")
dog = Dog()
dog.speak() # 输出:汪汪叫
多态(Polymorphism)
多态是指不同类的对象可以对同一消息做出响应。通过继承,子类可以重写父类的方法。
def make_sound(animal):
animal.speak()
make_sound(Dog())
综合应用 - 烤地瓜
需求涉及一个事物:地瓜,故案例涉及一个类:地瓜类。
- 地瓜的属性:被烤的时间、地瓜的状态、添加的调料。
- 地瓜的方法:被烤、添加调料、显示对象信息。
需求
-
被烤的时间和对应的地瓜状态:
- 0 - 5 分钟:生的
- 5 - 10 分钟:半生不熟
- 10-12 分钟:烤熟了
- 超过 12 分钟:烤糊了
-
添加调料:支持多种调料。
代码实现
class Potato:
def __init__(self):
# 烤的时间
self.cook_time = 0
# 烤的状态
self.cook_status = "生的"
# 放的调料
self.cook_seasoning = []
def cook(self, time):
self.cook_time += time
if 0 <= self.cook_time < 5:
self.cook_status = "生的"
elif 5 <= self.cook_time < 10:
self.cook_status = "半生半熟"
elif 10 <= self.cook_time <= 12:
self.cook_status = "熟了"
else:
self.cook_status = "烤糊了"
def add_seasoning(self, *seasoning):
self.cook_seasoning.extend(seasoning)
def __str__(self):
return f"当前地瓜考了--{self.cook_time}--分钟,他的状态是--{self.cook_status}--,添加的调料是--{self.cook_seasoning}"
if __name__ == '__main__':
potato = Potato()
potato.cook(11)
potato.add_seasoning("辣椒", "花生", "孜然")
print(potato)
进阶实践 - 银行账户系统
为了更好地掌握面向对象,我们构建一个简单的银行账户系统。
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.__balance = balance # 私有余额
def deposit(self, amount):
if amount > 0:
self.__balance += amount
print(f"存款成功,当前余额:{self.__balance}")
else:
print("存款金额必须大于 0")
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
print(f"取款成功,当前余额:{self.__balance}")
else:
print("余额不足或金额无效")
def get_balance(self):
return self.__balance
account = BankAccount("张三", 1000)
account.deposit(500)
account.withdraw(200)
print(account.get_balance())
总结
本文详细讲解了 Python 面向对象编程的核心概念,包括类与对象的定义及关系、实例属性与方法的使用、魔法方法的功能与应用。内容涵盖私有属性的封装机制、类的继承与多态特性,并通过烤地瓜和银行账户等案例演示了实际编码技巧。此外还补充了类变量与实例变量的区别、静态方法与类方法的用法,帮助读者系统掌握 Python 面向对象的设计思想与最佳实践。

