本文最后更新于 22 天前,其中的信息可能已经有所发展或是发生改变。
用实例来介绍面向对象
类(Class)
事物的“模板”
假设你是家具设计师,设计了一款“沙发”。在生产前,你需要创建一份设计图纸,这份图纸定义了沙发的结构(如尺寸、材质、颜色)和功能(如可坐、可躺、可收纳)。
代码中的类(Python版):
class Sofa:
def __init__(self, color, material, seats):
self.color = color
self.material = material
self.__seats = seats # 使用双下划线隐藏属性(私有属性)
def get_seats(self): # 提供公共方法访问私有属性
return self.__seats
def sit(self):
print(f"坐在{self.color}的{self.material}沙发上")
def lie_down(self):
if self.get_seats() >= 2:
print("可以躺下")
else:
print("单人沙发无法躺下")
关键点:
- 类是抽象的:它不是具体的沙发,而是描述沙发“长什么样”和“能做什么”。
- 属性(Attribute):类的“特征”(如颜色、材质)。
- 方法(Method):类的“行为”(如坐、躺)。
对象(Object)
类的“实例”
根据设计图纸,工厂生产出具体的沙发。比如:
- 沙发A:红色、皮质、3座位
- 沙发B:蓝色、布质、1座位
创建对象:
# 创建两个沙发对象
sofa_a = Sofa(color="红色", material="皮质", seats=3)
sofa_b = Sofa(color="蓝色", material="布质", seats=1)
# 调用对象的方法
sofa_a.sit() # 输出:坐在红色的皮质沙发上
sofa_a.lie_down() # 输出:可以躺下
sofa_b.sit() # 输出:坐在蓝色的布质沙发上
sofa_b.lie_down() # 输出:单人沙发无法躺下
关键点:
- 对象是具体的:每个对象有自己的属性值(如沙发A是红色,沙发B是蓝色)。
- 实例化:从类创建对象的过程(如
Sofa()
)。
封装(Encapsulation)
信息隐藏
沙发的内部结构(如弹簧、填充物)被包裹在布料或皮革下,用户只需知道如何使用沙发(坐、躺),而无需了解内部工作原理。
代码中的封装:
class Sofa:
def __init__(self, color, material, seats):
self.color = color
self.material = material
self.__seats = seats # 使用双下划线隐藏属性(私有属性)
def get_seats(self): # 提供公共方法访问私有属性
return self.__seats
def sit(self):
print(f"坐在{self.color}的{self.material}沙发上")
def lie_down(self):
if self.get_seats() >= 2:
print("可以躺下")
else:
print("单人沙发无法躺下")
关键点:
- 隐藏内部细节:通过私有属性(如
__seats
)和公共方法(如get_seats()
)控制访问。 - 保护数据:避免外部直接修改内部状态,保证数据安全。
继承(Inheritance)
复用与扩展
你基于“沙发”图纸设计了一款多功能沙发床,它保留了沙发的所有特性(颜色、材质、坐的功能),并新增了展开成床的功能。
代码中的继承:
class SofaBed(Sofa): # 继承自 Sofa 类
def __init__(self, color, material, seats):
super().__init__(color, material, seats) # 复用父类的初始化
self.bed_length = 1.8 # 新增属性:床的长度
def unfold(self): # 新增方法:展开成床
print(f"展开沙发,变成{self.bed_length}米的床")
创建和使用子类对象:
sofa_bed = SofaBed("灰色", "亚麻", 2)
sofa_bed.sit() # 继承自父类的方法
# 这一句代码将输出:坐在灰色的亚麻沙发上
sofa_bed.unfold() # 子类新增的方法
# 这一句代码将会输出:展开沙发,变成1.8米的床
关键点:
- 子类复用父类的代码:避免重复编写相同属性和方法。
- 扩展功能:子类可以添加新属性和方法,或修改父类的方法(重写)。
多态(Polymorphism)
同一接口,不同实现
你设计了多种类型的家具(沙发、椅子、桌子),它们都有“清洁”的功能,但清洁方式不同:
- 沙发:用吸尘器吸
- 椅子:用湿布擦
- 桌子:先用清洁剂再擦
代码中的多态:
class Furniture:
def clean(self):
pass # 基类定义通用接口
class Sofa(Furniture):
def clean(self):
print("用吸尘器清洁沙发")
class Chair(Furniture):
def clean(self):
print("用湿布擦拭椅子")
class Table(Furniture):
def clean(self):
print("先用清洁剂喷洒,再用干布擦拭桌子")
统一调用不同对象的方法:
furniture_list = [Sofa(), Chair(), Table()]
for item in furniture_list:
item.clean() # 同一接口,根据对象类型执行不同实现
以上代码将会输出:
用吸尘器清洁沙发
用湿布擦拭椅子
先用清洁剂喷洒,再用干布擦拭桌子
关键点:
- 接口统一:不同类实现相同方法名(如
clean()
)。 - 行为不同:根据对象的实际类型调用对应的实现。
总结
通过这个家具的例子,希望可以帮助理解面向对象编程的核心思想:
用类组织代码, 用对象表示具体事物, 通过继承扩展功能, 通过多态统一接口。
调用sofa a和sofa b为什么一个用sit,一个用liedown
用来举个例子,后面会把完整的示例补上,对a和b都进行sit和liedown的调用
示例补完啦,有问题请继续提问噢