各位CSDN的小伙伴们大家好,我是唐叔。今天我将用最接地气的方式,带大家系统掌握Python面向对象编程的核心要点,从基础概念到高级封装技巧一网打尽。
文章目录
一、为什么需要类和对象?
类和对象就像乐高积木的设计图纸和具体积木。在实际开发中,它们能帮助我们:
- 封装复杂逻辑:数据与操作打包
- 代码复用:通过继承减少重复
- 提高可维护性:组织结构更清晰
二、类和对象基础操作
1. 定义类和创建对象
# 定义一个简单的类
class Dog:
# 类属性(所有实例共享)
species = "Canis familiaris"
# 初始化方法(构造函数)
def __init__(self, name, age):
# 实例属性
self.name = name
self.age = age
# 实例方法
def bark(self):
print(f"{self.name} says: Woof!")
# 创建对象(实例化)
my_dog = Dog("Buddy", 3)
your_dog = Dog("Lucy", 5)
# 访问属性和调用方法
print(my_dog.name) # 输出: Buddy
my_dog.bark() # 输出: Buddy says: Woof!
关键点:
__init__
是构造函数self
代表当前实例- 类属性共享,实例属性独立
2. 使用场景
- 电商系统:Product/User类
- 游戏开发:Player/Enemy类
- GUI编程:Button/Window类
三、类的进阶特性
1. 动态属性操作
除了可以使用类自身已定义的属性,也可以在操作对象时,动态添加属性。
class DynamicClass:
pass
obj = DynamicClass()
# 动态添加属性
obj.new_attr = "动态添加的值"
print(obj.new_attr) # 输出: 动态添加的值
# 动态删除属性
del obj.new_attr
注意:如果不希望使用对象时,可以添加动态属性,可以在定义类时使用 __slots__
魔法来约束。
class DynamicClass:
__slots__ = ('old_attr')
def __init__(self, old_attr):
self.old_attr = old_attr
obj = DynamicClass('old_attr')
# 动态添加属性
obj.new_attr = "动态添加的值" # AttributeError
2. 静态方法和类方法
方法类型 | 装饰器 | 第一个参数 | 访问权限 |
---|---|---|---|
实例方法 | 无 | self | 实例和类属性 |
类方法 | @classmethod | cls | 仅类属性 |
静态方法 | @staticmethod | 无 | 无属性访问 |
代码示例:
class MyClass:
@staticmethod
def static_method():
print("这是静态方法,不需要self/cls参数")
@classmethod
def class_method(cls):
print(f"这是类方法,可以访问类属性 {cls.__name__}")
# 调用方式
MyClass.static_method()
MyClass.class_method()
四、面向对象高级特性
1. 继承与多态
# 父类(基类)
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("子类必须实现这个方法")
# 子类(派生类)
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
# 多态演示
animals = [Cat("Kitty"), Dog("Buddy")]
for animal in animals:
print(animal.speak())
2. 方法重写
子类可以重写父类已经声明的方法,当然,也可以在重写时,通过 super()
调用父类的方法。
class Parent:
def __init__(self, value):
self.value = value
def show(self):
print(f"Value: {self.value}")
class Child(Parent):
def __init__(self, value, extra):
super().__init__(value) # 调用父类初始化
self.extra = extra
def show(self): # 方法重写
super().show() # 调用父类方法
print(f"Extra: {self.extra}")
child = Child(10, "额外信息")
child.show()
五、类的封装与属性可见性
1. 三种可见性级别
命名方式 | 示例 | 说明 |
---|---|---|
无下划线 | public_attr | 完全公开 |
单下划线前缀 | _protected | 约定保护,不建议外部访问 |
双下划线前缀 | __private | 名称修饰,不能直接访问 |
代码示例
class BankAccount:
def __init__(self, account_holder, balance):
self.account_holder = account_holder # 公开属性
self._balance = balance # 受保护属性(单下划线约定)
self.__secret_code = 1234 # 名称修饰(双下划线)
def get_balance(self):
return self._balance
def __internal_check(self):
print("执行内部检查...")
# 使用示例
account = BankAccount("唐叔", 10000)
print(account.account_holder) # 可以访问
print(account._balance) # 可以访问但不建议(约定)
# print(account.__secret_code) # 报错:AttributeError
print(account._BankAccount__secret_code) # 可以访问(名称修饰后)
注意:Python没有真正的"私有"概念,它遵循"我们都是成年人"(We are all consenting adults here)原则,成年人可以为自己的行为负责,而不是通过Python语言进行约束。
所以,实际上私有需求,也是可以通过类似account._BankAccount__secret_code
进行访问的。
2. @property实现安全访问
通过 @property
可以将方法转换为对象的属性进行使用。
class Temperature:
def __init__(self, celsius):
self._celsius = celsius # 受保护属性
@property
def celsius(self):
"""Getter方法"""
return self._celsius
@celsius.setter
def celsius(self, value):
"""Setter方法"""
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
temp.celsius = 30 # 通过setter
print(temp.fahrenheit) # 86.0
# temp.fahrenheit = 100 # 报错:AttributeError
六、总结
今天唐叔带大家系统学习了Python类和对象的方方面面。记住几个核心要点:
- 类就像设计图纸,对象是根据图纸制造的具体产品。
- 继承实现代码复用,多态提高扩展性。
- 类方法操作类属性,静态方法不依赖实例。
- 单下划线是约定保护,双下划线会触发名称修饰。
@property
可以创建优雅的属性访问接口。- Python的封装更多依赖约定而非强制。
好啦,本期的分享就到这里了。欢迎在评论区交流!觉得有帮助请点赞收藏,关注唐叔获取更多Python干货!
往期文章推荐:
- 【Python入门】Python 入门,轻松踏上编程之旅
- 【Python入门】轻松掌握Python语法:从零开始编写你的第一个程序
- 【Python入门】掌握Python函数:从基础到实战邮件发送
- 【Python入门】别再乱import了!Python模块指南来了,从导入到实战,一文搞懂核心用法
更多内容可以关注 《唐叔学Python》专栏。