news 2026/10/31 6:32:09

Python 面向对象编程:方法、属性、继承与多态详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 面向对象编程:方法、属性、继承与多态详解

一、为什么需要面向对象

面向对象程序设计(OOP)的核心思想是把数据和操作数据的行为封装在一起,用“对象”来模拟现实世界中的实体。Python 是一门支持多范式编程的语言,但它的面向对象特性非常自然、灵活,几乎一切皆对象。

二、类与对象:一切的起点

在讲方法之前,先明确类(class)和对象(object)的关系:类是对一类事物的抽象描述,对象是类的具体实例。

class Dog: """一个最简单的类""" def __init__(self, name, age): self.name = name self.age = age 创建对象(实例化) d = Dog("旺财", 3) print(d.name, d.age) # 旺财 3

其中__init__是构造方法,在创建对象时自动调用,用于初始化属性。

三、属性:实例属性与类属性

3.1 实例属性

实例属性定义在__init__中,通过self.xxx赋值,每个对象各自独立。

class Student: def __init__(self, name, score): self.name = name # 实例属性 self.score = score # 实例属性 s1 = Student("小明", 90) s2 = Student("小红", 85) s1.score = 95 print(s1.score, s2.score) # 95 85,互不影响

3.2 类属性

类属性定义在类体中、方法之外,被所有实例共享,适合存放常量或全局统计信息。

class Student: school = "第一中学" # 类属性 count = 0 # 类属性,用于统计实例数量 def __init__(self, name): self.name = name Student.count += 1 a = Student("小明") b = Student("小红") print(Student.school) # 第一中学 print(Student.count) # 2

注意:通过实例修改类属性只会创建同名实例属性,不会影响类本身。修改类属性应使用类名.属性名。

3.3 私有属性与 property

Python 用下划线约定表示访问级别:_name表示受保护,__name表示私有(名称改写)。配合@property可以实现受控的属性访问。

class Account: def __init__(self, balance): self.__balance = balance # 私有属性 @property def balance(self): """只读属性""" return self.__balance @balance.setter def balance(self, value): if value < 0: raise ValueError("余额不能为负") self.__balance = value acc = Account(100) acc.balance = 200 print(acc.balance) # 200 acc.balance = -1 # 抛出 ValueError

四、方法:实例方法、类方法与静态方法

4.1 实例方法

最常见的类型,第一个参数是self,可以访问实例属性和类属性。

class Circle: def __init__(self, r): self.r = r def area(self): # 实例方法 return 3.14159 * self.r ** 2 c = Circle(2) print(c.area()) # 12.56636

4.2 类方法

用@classmethod装饰,第一个参数是cls,常用于提供替代构造器。

class Person: def __init__(self, name, age): self.name = name self.age = age @classmethod def from_string(cls, info): """从 'name-age' 字符串创建对象""" name, age = info.split("-") return cls(name, int(age)) p = Person.from_string("张三-20") print(p.name, p.age) # 张三 20

4.3 静态方法

用@staticmethod装饰,既不需要self也不需要cls,本质上是放在类命名空间里的普通函数。

class MathUtil: @staticmethod def is_even(n): return n % 2 == 0 print(MathUtil.is_even(10)) # True

4.4 三种方法对比

类型装饰器第一个参数典型用途
实例方法无self操作实例数据
类方法@classmethodcls替代构造器、操作类状态
静态方法@staticmethod无工具函数、与实例无关的逻辑

五、继承:复用与扩展

5.1 基本继承

子类继承父类的属性和方法,并可在此基础上扩展或重写。

class Animal: def __init__(self, name): self.name = name def speak(self): return "……" class Cat(Animal): def speak(self): # 重写父类方法 return f"{self.name}:喵喵喵" class Dog(Animal): def speak(self): return f"{self.name}:汪汪汪" print(Cat("咪咪").speak()) # 咪咪:喵喵喵 print(Dog("旺财").speak()) # 旺财:汪汪汪

5.2 使用 super() 调用父类

子类重写__init__时,通常需要调用super().__init__()完成父类初始化。

class Animal: def __init__(self, name): self.name = name class Bird(Animal): def init(self, name, can_fly): super().init(name) # 调用父类构造方法 self.can_fly = can_fly b = Bird("麻雀", True) print(b.name, b.can_fly) # 麻雀 True

5.3 多重继承与 MRO

Python 支持多重继承,方法查找顺序由 MRO(方法解析顺序)决定,可用类名.__mro__查看。

class A: def hello(self): return "A" class B(A): def hello(self): return "B" class C(A): def hello(self): return "C" class D(B, C): pass print(D().hello()) # B print([c.name for c in D.mro]) # ['D', 'B', 'C', 'A', 'object']

六、多态:同一接口,不同实现

多态指不同类的对象对同一方法调用做出不同响应。Python 是动态类型语言,天然支持“鸭子类型”:只要对象有对应方法即可调用,不要求继承关系。

class Cat: def speak(self): return "喵" class Dog: def speak(self): return "汪" class Duck: def speak(self): return "嘎" def make_sound(animal): print(animal.speak()) for a in [Cat(), Dog(), Duck()]: make_sound(a) 喵 汪 嘎

可以看到,make_sound并不关心传入对象的具体类型,只关心它是否有speak方法。这正是多态带来的灵活性。

6.1 基于继承的多态

class Shape: def area(self): raise NotImplementedError class Rectangle(Shape): def init(self, w, h): self.w, self.h = w, h def area(self): return self.w * self.h class Circle(Shape): def init(self, r): self.r = r def area(self): return 3.14159 * self.r ** 2 shapes = [Rectangle(3, 4), Circle(2)] for s in shapes: print(f"{type(s).name} 面积:{s.area():.2f}") Rectangle 面积:12.00 Circle 面积:12.57

七、综合实例:一个简单的员工管理系统

下面把方法、属性、继承与多态综合起来,实现一个可运行的示例。

class Employee: """员工基类""" company = "示例科技" # 类属性 def __init__(self, name, base_salary): self.name = name # 实例属性 self.base_salary = base_salary def salary(self): # 实例方法,供子类重写 return self.base_salary def __str__(self): return f"{self.name}({type(self).__name__})月薪:{self.salary():.2f}" class Engineer(Employee): def init(self, name, base_salary, bonus): super().init(name, base_salary) self.bonus = bonus def salary(self): return self.base_salary + self.bonus class Manager(Employee): def init(self, name, base_salary, team_size): super().init(name, base_salary) self.team_size = team_size def salary(self): return self.base_salary + self.team_size * 500 class Intern(Employee): @classmethod def create(cls, name): """类方法作为替代构造器""" return cls(name, 3000) @staticmethod def is_valid_days(days): """静态方法:校验实习天数""" return 0 < days <= 180 employees = [ Engineer("张三", 15000, 3000), Manager("李四", 20000, 3), Intern.create("王五"), ] total = 0 for e in employees: print(e) # 多态:调用各自的 salary() total += e.salary() print(f"公司:{Employee.company},总人力成本:{total:.2f}") print("实习天数合法:", Intern.is_valid_days(90))

运行结果:

张三(Engineer)月薪:18000.00 李四(Manager)月薪:21500.00 王五(Intern)月薪:3000.00 公司:示例科技,总人力成本:42500.00 实习天数合法: True

八、常见误区与最佳实践

  • 不要滥用多重继承:优先使用组合(has-a)代替继承(is-a),结构更清晰。
  • 类属性不要用可变对象:如list、dict作为类属性会被所有实例共享,容易踩坑。
  • 私有属性只是约定:Python 没有真正的访问控制,__x会被改名为_类名__x。
  • 优先使用鸭子类型:不必为了多态强行设计继承体系,接口一致即可。
  • 善用@property:在需要校验或计算属性时,比直接暴露字段更安全。

九、总结

本文从类与对象出发,依次讲解了实例属性与类属性、三种方法类型、单继承与多重继承、以及基于继承和鸭子类型的多态。掌握这些概念后,就能用 Python 写出结构清晰、易于扩展的面向对象代码。

建议读者把文中的综合实例动手敲一遍,并尝试新增一个Sales类,体会多态带来的扩展便利。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 6:31:28

FCN.tensorflow 项目使用教程

FCN.tensorflow 项目使用教程 【免费下载链接】FCN.tensorflow Tensorflow implementation of Fully Convolutional Networks for Semantic Segmentation (http://fcn.berkeleyvision.org) 项目地址: https://gitcode.com/gh_mirrors/fc/FCN.tensorflow 项目介绍 FCN.t…

作者头像 李华
网站建设 2026/10/31 6:30:31

@Autowired 和@Resource的区别

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/31 6:30:08

事务的失效场景

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/31 6:28:37

嵌入式Linux LCD调试:从DTS配置到中文显示的系统性排错

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/31 6:28:16

wechaty 微信群聊机器人实战:自动回复、防撤回与多群管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/31 6:27:13

高速光模块迭代中的射频测试:从眼图到S参数的关键支撑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华