☰
封装、继承、多态 —— 面向对象的 “三大招“,老哥用一个愤怒的小鸟项目讲透
2026/11/4 12:06:40 网站建设 项目流程

面向对象有三大特性:封装、继承、多态。老哥逐个讲,最后用一个完整的 "愤怒的小鸟" 项目把它们串起来。

一、封装:把细节藏起来,只留接口

封装就是把属性和方法写进类里,同时隐藏细节,只暴露必要的接口。核心是私有化。

单下划线_var:约定 "非公开 API",只是约定,不强制。

双下划线__var:会触发名称改写,变成_类名__var,类外部访问不到(除非用改写的名字):

class Person: def __init__(self, name): self.__name = name # 私有属性 def get_name(self): return self.__name p = Person("张三") print(p.get_name()) # 张三 通过公有方法访问 print(p._Person__name) # 张三 名称改写后的名字(不推荐) print(p.__name) # 报错!外部访问不到

私有方法同理:def __private_method(self),外部p.__private_method()会报错。

二、property:把方法变成属性

用@property装饰方法,就能像属性一样调用(不加括号)。这通常配合私有属性做只读:

class Person: def __init__(self, name): self.__name = name @property def name(self): # 方法名去掉双下划线 return self.__name p = Person("张三") print(p.name) # 张三 像属性一样读 p.name = "李四" # 报错!只读,没有 setter

加上@name.setter就能读写,还能在里面做校验拦截:

class Person: def __init__(self, name): self.__name = name @property def name(self): return self.__name @name.setter def name(self, name): if name == "李四": print("不许叫李四") else: self.__name = name p = Person("张三") p.name = "李四" # 提示 "不许叫李四" print(p.name) # 张三 没改成 p.name = "王五" # 成功 print(p.name) # 王五

⚠️ 大坑:@property的方法名不要和变量重名,否则会无限递归报RecursionError。

三、继承:子类复用父类,还能改造

子类(派生类)继承父类(基类)的属性和方法,实现代码重用,还能新增、重写方法。注意:子类继承不到父类的私有成员(名称改写所致)。

单继承,在类名括号里写父类:

class Person: home = "earth" def __init__(self, name): self.name = name def eat(self): print("eating...") class YellowRace(Person): # 继承 Person color = "yellow" y1 = YellowRace("张三") print(y1.home, y1.color, y1.name) # earth yellow 张三 y1.eat() # eating... 继承来的方法

多继承,父类从左到右查找方法:

class ChineseStudent(Student, YellowRace): # 继承两个父类 country = "中国" y1 = ChineseStudent("张三", "三年级") y1.eat() # 来自 Person y1.run() # 来自 YellowRace y1.study() # 来自 Student

复用父类方法:用super().方法名()或父类名.方法名(self):

class Student(Person): def study(self): print("先吃再学") super().eat() # 调用父类 Person 的 eat() print("studying...")

方法解析顺序 MRO:用类名.__mro__看继承链,决定方法查找顺序:

print(ChineseStudent.__mro__) # (ChineseStudent, Student, YellowRace, Person, object)

方法重写:子类定义同名方法,调用时就用自己的。注意:重写__init__后父类的__init__不会自动执行,需要手动super().__init__():

class Chinese(Person): def __init__(self, name, area): super().__init__(name) # 手动调父类初始化 self.area = area

四、多态:同一接口,不同表现

同一事物在不同场景下呈现不同状态。同一个go()方法,不同动物跑出不同效果:

class Animal: def go(self): pass class Dog(Animal): def go(self): print("跑") class Fish(Animal): def go(self): print("游") class Bird(Animal): def go(self): print("飞") def go(animal): animal.go() # 传入不同实例,执行不同方法 go(Dog()); go(Fish()); go(Bird()) # 跑 / 游 / 飞

五、综合实战:愤怒的小鸟

把三大特性全用上。基类Birds(抽象 + 封装),子类红黄蓝鸟(继承 + 重写 → 多态),Obstacle类负责和小鸟交互:

# 鸟类基类 class Birds: def __init__(self, name, color, skill_description): self.name = name self.color = color self.skill_description = skill_description def fly(self): print(f"{self.name} 正在飞行...") def call(self): print(f"{self.name} 发出叫声...") def use_skill(self): print(f"{self.name} 使用了技能:{self.skill_description}") # 红鸟 class RedBirds(Birds): def __init__(self): super().__init__("红火", "红色", "撞击前方障碍物,造成大量伤害") def fly(self): print("红火以稳定的速度向前飞行...") def call(self): print("红火发出 'wei呀....' 的叫声") # 黄鸟 class YellowBirds(Birds): def __init__(self): super().__init__("小黄", "黄色", "瞬间加速,穿透薄障碍物") def fly(self): print("小黄快速向前飞行...") def call(self): print("小黄发出 '啾啾啾....' 的叫声") # 蓝鸟 class BlueBirds(Birds): def __init__(self): super().__init__("小蓝", "蓝色", "分裂成三只小鸟,分散攻击") def fly(self): print("小蓝优雅地向前飞行...") def call(self): print("小蓝发出 '叽叽叽....' 的叫声") # 障碍物类 class Obstacle: def __init__(self, name, strength): self.name = name self.strength = strength def be_attacked(self, bird): print(f"{bird.name} 冲向了 {self.name}") bird.use_skill() # 多态:不同鸟用不同技能 if isinstance(bird, RedBirds): damage = 80 elif isinstance(bird, YellowBirds): damage = 50 elif isinstance(bird, BlueBirds): damage = 30 * 3 # 分裂成三只 self.strength -= damage if self.strength <= 0: print(f"{self.name} 被摧毁了!") else: print(f"{self.name} 还剩余 {self.strength} 点强度") # 模拟游戏 if __name__ == "__main__": red_bird = RedBirds() yellow_bird = YellowBirds() blue_bird = BlueBirds() obstacle1 = Obstacle("木头堡垒", 100) obstacle2 = Obstacle("石头塔楼", 200) obstacle1.be_attacked(red_bird) # 红鸟打木头堡垒 obstacle2.be_attacked(yellow_bird) # 黄鸟打石头塔楼 obstacle2.be_attacked(blue_bird) # 蓝鸟打石头塔楼

老哥收尾

三大特性一句话:

封装藏细节(私有 + property 控读写)、继承复用父类(super 调父类、可重写)、多态同接口不同表现(一个 go 方法,跑游飞)。

用 "愤怒的小鸟" 把继承、重写、多态、对象交互全串起来了。下一篇讲错误和异常—— 程序崩了别慌,try-except 帮你兜底。有问题随时回来找老哥。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询