Python 面向对象详解!

简介: 本文详细介绍了Python中的面向对象编程(OOP),包括类、对象、继承、封装、多态和抽象等核心概念。通过具体示例,解释了如何使用类定义对象的属性和方法,以及如何通过继承实现代码重用。文章还探讨了封装和多态的重要性,并介绍了私有属性和抽象类的使用方法。最后,总结了OOP的四大支柱:封装、抽象、继承和多态,强调了这些概念在Python编程中的应用。适合Java程序员扩展Python编程知识。

嗨,你好啊,我是猿java

作为一名 Java程序员,对面向对象编程肯定不陌生,那么,在 Python 语言中,面向对象是什么?它有什么作用?这篇文章我们就来讲一讲。

什么是 Python OOP?

在 Python中,面向对象编程(Object-Oriented Programming,简称OOP)是一种使用对象和类进行编程的编程范式。它旨在实现现实世界中的实体,如继承、多态、封装等。在编程中,面向对象编程的主要概念是将数据和与之相关的函数绑定为一个单元,以便代码的其他部分无法访问这些数据。

Python中的OOP包含以下概念:

  • Python类
  • Python对象
  • Python多态
  • Python封装
  • Python继承
  • Python数据抽象

接下来,我们对上面的概念一一讲解。

Python类

类是对象的集合。类包含创建对象的蓝图或原型。它是一个包含一些属性和方法的逻辑实体。

为了理解创建类的需求,让我们考虑一个例子,假设你想跟踪具有不同属性的狗,如品种和年龄。如果使用列表,第一个元素可能是狗的品种,而第二个元素可能代表其年龄。假设有 100只不同的狗,那么你怎么知道哪个元素代表哪个属性呢?如果你想为这些狗添加其他属性呢?这就缺乏组织性,这正是需要类的原因。

关于 Python类的一些要点:

  • 类是由关键字class创建的。
  • 属性是属于类的变量。
  • 属性总是公开的,可以使用点(.)操作符访问。例子:Myclass.Myattribute

类定义语法:

class ClassName:
   # 语句-1

   # 语句-N

创建一个空类

在下面的例子中,我们使用 class关键字创建了一个名为 Dog的空类。

class Dog:
    pass

输出:无输出

Python对象

在面向对象编程中,对象是具有状态和行为的实体。它可以是任何现实世界的对象,如鼠标、键盘、椅子、桌子、笔等。整数、字符串、浮点数,甚至数组和字典,都是对象。更具体地说,任何单个整数或字符串都是对象。数字 12是一个对象,字符串“Hello, world”是一个对象,列表是一个可以包含其他对象的对象,等等。你一直在使用对象,可能甚至没有意识到。

一个对象包括:

  • 状态:由对象的属性表示。它也反映了对象的属性。
  • 行为:由对象的方法表示。它也反映了对象对其他对象的响应。
  • 身份:赋予对象一个唯一的名称,并使一个对象能够与其他对象交互。

为了理解状态、行为和身份,让我们以狗类为例(上面解释过)。

  • 身份可以被认为是狗的名字。
  • 状态或属性可以被认为是狗的品种、年龄或颜色。
  • 行为可以被认为是狗是否在吃东西或睡觉。

创建一个对象

下面的示例创建了一个名为 obj的 Dog类的对象。在深入研究对象和类之前,让我们了解一些在处理对象和类时会用到的基本关键字。

obj = Dog()

Python中的self

类方法在方法定义中必须有一个额外的第一个参数self。当我们调用方法时,不需要为这个参数提供值,Python会自动提供。

如果我们有一个不带参数的方法,那么我们仍然需要有一个参数。 这类似于 C++中的 this指针和 Java中的 this引用。

当我们调用一个对象的方法,如myobject.method(arg1, arg2)时,Python会自动将其转换为MyClass.method(myobject, arg1, arg2),这就是特殊的 self的作用。

Python中的init方法

init方法类似于 C++和 Java中的构造函数,它在类的对象实例化时自动运行。这个方法对于初始化对象非常有用。下面我们定义一个类,并使用 self 和 init方法创建一些对象。

创建带有类和实例属性的类和对象:

class Dog:

    # 类属性
    attr1 = "mammal"

    # 实例属性
    def __init__(self, name):
        self.name = name

# 主代码
# 对象实例化
Rodger = Dog("Rodger")
Tommy = Dog("Tommy")

# 访问类属性
print("Rodger is a {}".format(Rodger.__class__.attr1))
print("Tommy is also a {}".format(Tommy.__class__.attr1))

# 访问实例属性
print("My name is {}".format(Rodger.name))
print("My name is {}".format(Tommy.name))

输出:

Rodger is a mammal
Tommy is also a mammal
My name is Rodger
My name is Tommy

创建带有方法的类和对象:

这里,Dog类定义了两个属性:

  • attr1是一个类属性,值为“mammal”。类属性由类的所有实例共享。
  • init是一个特殊方法(构造函数),用于初始化Dog类的实例。它接收两个参数:self(指代被创建的实例)和name(代表狗的名字)。name参数用于为每个Dog实例分配一个name属性。
  • speak方法在Dog类中定义。该方法打印一个包含狗实例名字的字符串。
    主代码首先创建了两个Dog类的实例:Rodger和Tommy。init方法被调用以初始化它们的name属性。speak方法在两个实例中调用(Rodger.speak()和Tommy.speak()),使每只狗打印出带有其名字的声明。
    ```python
    class Dog:

    类属性

    attr1 = "mammal"

    实例属性

    def init(self, name):

      self.name = name
    

    def speak(self):

      print("My name is {}".format(self.name))
    

主代码

对象实例化

Rodger = Dog("Rodger")
Tommy = Dog("Tommy")

访问类方法

Rodger.speak()
Tommy.speak()

输出:

My name is Rodger
My name is Tommy


# Python继承

在Python面向对象编程中,继承是一个类从另一个类派生或继承属性的能力。派生属性的类称为派生类或子类,从中派生属性的类称为基类或父类。继承的好处包括:

- 它很好地表示现实世界的关系。
- 它提供代码的重用性。我们不必一遍又一遍地编写相同的代码。此外,它允许我们在不修改类的情况下为其添加更多功能。
- 它具有传递性,这意味着如果类B继承自类A,那么类B的所有子类将自动继承自类A。

## 继承的类型

- 单继承:单级继承使派生类能够从单个父类继承特性。
- 多级继承:多级继承使派生类能够从直接父类继承属性,而父类又继承自其父类。
- 层次继承:层次级继承使多个派生类能够从一个父类继承属性。
- 多重继承:多重继承使一个派生类能够从多个基类继承属性。

在上面的文章中,我们创建了两个类:Person(父类)和Employee(子类)。Employee类继承自Person类。我们可以通过Employee类使用Person类的方法,如上面的display函数所示。子类还可以修改父类的行为,如details()方法所示。
```python
# Python代码演示如何调用父类构造函数。

# 父类
class Person(object):

    # __init__被称为构造函数
    def __init__(self, name, idnumber):
        self.name = name
        self.idnumber = idnumber

    def display(self):
        print(self.name)
        print(self.idnumber)

    def details(self):
        print("My name is {}".format(self.name))
        print("IdNumber: {}".format(self.idnumber))

# 子类
class Employee(Person):
    def __init__(self, name, idnumber, salary, post):
        self.salary = salary
        self.post = post

        # 调用父类的__init__方法
        Person.__init__(self, name, idnumber)

    def details(self):
        print("My name is {}".format(self.name))
        print("IdNumber: {}".format(self.idnumber))
        print("Post: {}".format(self.post))

# 创建对象变量或实例
a = Employee('Rahul', 886012, 200000, "Intern")

# 使用实例调用Person类的方法
a.display()
a.details()

输出:

Rahul
886012
My name is Rahul
IdNumber: 886012
Post: Intern

Python多态

在Python面向对象编程中,多态简单来说就是具有多种形式。例如,我们需要确定给定的鸟类是否会飞,使用多态,我们可以用一个函数来完成这个任务。

此代码演示了Python类中的继承和方法重写概念。它展示了子类如何重写父类中定义的方法以提供特定行为,同时仍然继承父类的其他方法。

class Bird:

    def intro(self):
        print("There are many types of birds.")

    def flight(self):
        print("Most of the birds can fly but some cannot.")

class Sparrow(Bird):

    def flight(self):
        print("Sparrows can fly.")

class Ostrich(Bird):

    def flight(self):
        print("Ostriches cannot fly.")

obj_bird = Bird()
obj_spr = Sparrow()
obj_ost = Ostrich()

obj_bird.intro()
obj_bird.flight()

obj_spr.intro()
obj_spr.flight()

obj_ost.intro()
obj_ost.flight()

输出:

There are many types of birds.
Most of the birds can fly but some cannot.
There are many types of birds.
Sparrows can fly.
There are many types of birds.
Ostriches cannot fly.

Python封装

在Python面向对象编程中,封装是OOP的基本概念之一。它描述了将数据和操作数据的方法封装在一个单元中的想法。这对直接访问变量和方法进行了限制,防止数据的意外修改。为了防止意外更改,对象的变量只能通过对象的方法更改。这类变量称为私有变量。

类是封装的一个例子,因为它封装了所有的数据,包括成员函数、变量等。

在上面的例子中,我们创建了 c变量作为私有属性,我们不能直接访问这个属性,也不能更改其值。

# Python程序演示私有成员
# "__"双下划线表示私有属性。
# 私有属性以"__"开头。

# 创建基类
class Base:
    def __init__(self):
        self.a = "猿java"
        self.__c = "猿java" 

# 创建派生类
class Derived(Base):
    def __init__(self):

        # 调用基类的构造函数
        Base.__init__(self)
        print("调用基类的私有成员:")
        print(self.__c)

# 主代码
obj1 = Base()
print(obj1.a)

# 取消注释print(obj1.c)会引发AttributeError

# 取消注释obj2 = Derived()也会引发AttributeError,因为
# 基类的私有成员在派生类中被调用

输出:

猿java

Python数据抽象

数据抽象隐藏了用户不需要的代码细节。同时,当我们不想暴露代码实现的敏感部分时,数据抽象就派上用场了。

在Python中,数据抽象可以通过创建抽象类来实现。

class Rectangle:
    def __init__(self, length, width):
        self.__length = length  # 私有属性
        self.__width = width    # 私有属性

    def area(self):
        return self.__length * self.__width

    def perimeter(self):
        return 2 * (self.__length + self.__width)

rect = Rectangle(5, 3)
print(f"Area: {rect.area()}")          # 输出: Area: 15
print(f"Perimeter: {rect.perimeter()}")  # 输出: Perimeter: 16

# print(rect.__length)  # 这将引发AttributeError,因为length和width是私有属性

输出:

Area: 15
Perimeter: 16

常见问题

Python面向对象编程的四大支柱是什么?

面向对象编程(OOP)的四大支柱是:

  • 封装:将数据(属性)和操作数据的方法(函数)捆绑在一个单元(类)中。
  • 抽象:隐藏复杂的实现细节,并提供简化的接口。
  • 继承:允许一个类从另一个类继承属性和方法,促进代码重用。
  • 多态:使用单一接口表示不同的数据类型或对象。

Python使用OOP吗?

是的,Python完全支持面向对象编程(OOP)概念。类、对象、继承、封装和多态是 Python的基本特性。

Python是100%面向对象吗?

Python是一种多范式编程语言,这意味着它支持包括过程式、函数式和面向对象编程在内的多种编程范式。虽然 Python主要是面向对象的,但它也允许过程式和函数式编程风格。

Python的init是什么?

__init__是Python类中的一个特殊方法(构造函数)。当类的新实例(对象)被创建时,它会自动调用。它的主要目的是初始化对象的属性或执行对象所需的任何设置。

class MyClass:
    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2

Python中的super()是什么?

super()用于从子类(派生类)调用超类(父类)的方法。它返回一个代理对象,将方法调用委托给超类。这对于访问在子类中被重写的继承方法非常有用。

class ChildClass(ParentClass):
    def __init__(self, arg1, arg2):
        super().__init__(arg1)  # 调用ParentClass的__init__()方法
        self.arg2 = arg2

为什么 Python有self?

self是Python中的一种约定,用于引用类的实例(对象)本身。它是实例方法的第一个参数,指代调用方法的对象。它允许方法访问和操作属于实例的属性(变量)。

class MyClass:
    def __init__(self, name):
        self.name = name

    def greet(self):
        return f"Hello, {self.name}!"

obj = MyClass("Python")
print(obj.greet())  # 输出: Hello, Python!

总结

如果你是Java程序员,对面向对象编程肯定不陌生,面向对象编程也是 Python中的一种编程范式,通过使用类和对象来实现代码的模块化、可维护性和可扩展性。OOP的核心概念包括类、对象、继承、封装、多态和抽象。

  • 类是对象的蓝图,定义了对象的属性和方法;
  • 对象是类的实例,具有状态和行为。
  • 继承允许子类从父类继承属性和方法,促进代码重用;
  • 封装将数据和方法封装在一个单元中,限制直接访问;
  • 多态允许不同对象通过相同接口进行操作;
  • 抽象隐藏实现细节,提供简化接口。

学习交流

如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注:猿java,持续输出硬核文章。

目录
相关文章
|
23天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
16天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
20天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2574 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
18天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
3天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
2天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
159 2
|
20天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1575 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
22天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
962 14
|
3天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
204 2
|
17天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
727 10