九道门商业数据分析学院提供
介绍
在学习面向对象的编程时。我决定深入了解它的历史,结果令人着迷。术语“面向对象程序设计”(OOP)是艾伦·凯(Alan Kay)在1966年读研究生时提出的。名为Simula的语言是第一种具有面向对象编程功能的编程语言。它是在1967年开发的,用于制作仿真程序,其中最重要的信息称为对象。
尽管OOP从1960年代初开始进入市场,但在1990年代,由于C ++,OOP开始增长。之后,这种编程技术已被包括Python在内的各种编程语言所采用,如今它的应用几乎遍及各个领域,例如实时系统,人工智能和专家系统,客户端服务器系统,面向对象的数据库以及许多其他领域。更多。
因此,在本文中,我将解释Python中的面向对象编程的基本概念。
表中的内容
什么是面向对象的编程?面向对象程序设计(OOP)与面向过程程序设计(POP)OOP的主要概念什么是课程?对象和对象实例化类方法Python类中的继承封装形式多态性数据抽象
什么是面向对象的编程?
面向对象编程(OOP)就是创建“对象”。对象是一组相互关联的变量和函数。这些变量通常称为对象的属性,而功能则称为对象的行为。这些对象为程序提供了更好,更清晰的结构。
例如,汽车可以是物体。如果我们将汽车视为一个对象,那么它的属性就是–它的颜色,模型,价格,品牌等。它的行为/功能将是加速,减速,换档。
另一个例子-如果我们将狗视为对象,那么它的属性将是-他的颜色,他的品种,他的名字,他的体重等。他的行为/功能将是散步,吠叫,嬉戏等。
面向对象编程之所以闻名,是因为它在编程中实现了诸如对象,隐藏,继承等读取世界的实体。由于它接近真实场景,因此使可视化变得更加容易。
面向对象程序设计(OOP)与面向过程程序设计(POP)
OOP和过程编程之间的基本区别是-
例如,思考POP的一种方法就是制作柠檬水。制作柠檬水的过程包括:首先根据需要喝水,然后在水中加糖,然后在混合物中加入柠檬汁,最后将整个溶液混合。并且您的柠檬水准备服务。POP以类似的方式要求一定的步骤程序。程序程序由功能组成。这意味着在POP方法中,程序分为特定于不同任务的功能。这些功能按特定顺序排列,并且程序控制顺序进行。 而OOP程序由对象组成。面向对象的方法将程序划分为多个对象。这些对象是捆绑了真实对象的属性和行为的实体。POP仅适用于小型任务。因为随着程序长度的增加,代码的复杂度也会增加。最终变成了功能网。而且,它变得难以调试。OOP借助更清晰,更简单的结构解决了这个问题。它允许以继承的形式重用代码。另一个重要的事情是,在面向过程的编程中,所有功能都可以访问所有数据,这意味着缺乏安全性。假设您要保护凭据或来自世界各地的任何其他关键信息。然后,程序方法无法为您提供这种安全性。为此,OOP借助其惊人的功能之一“ 封装”帮助您,该功能使我们可以隐藏数据。不用担心,我将在本文的后半部分以及其他面向对象编程的概念中对此进行详细介绍。现在,只需要了解OOP就可以实现安全性,而POP则不能。诸如C,Pascal和BASIC之类的编程语言都使用过程方法,而Java,Python,JavaScript,PHP,Scala和C ++是提供面向对象方法的主要语言。主要的Python OOP概念-
在本节中,我们将深入研究OOP的基本概念。我们将涵盖以下主题-
类目的方法遗产封装形式多态性数据抽象1.什么是班级?
这个问题的直接答案是-类是对象的集合。与原始数据结构不同,类是用户定义的数据结构。它们使代码更易于管理。
让我们看看如何在下面定义一个类-
类class_name: 班级机构
我们在class_name和分号后定义一个带有关键字“ class”的类。我们考虑将缩进作为其主体之后在此基础上编写的所有内容。为了使它更容易理解,我们来看一个例子。
考虑一个汽车展示厅的情况。您要存储每辆车的详细信息。首先定义一个类
车类: 通过
而已!
注意:我使用pass语句代替它的主体,因为主要目的是显示如何定义一个类,而不是它应该包含的内容。
在详细介绍之前,首先要了解对象和实例化。
2.对象和对象实例化
当我们定义一个类时,仅创建对象的描述或蓝图。在创建对象之前没有内存分配。在反对者 实例包含实际数据或信息。
实例化不过是创建类的新对象/实例。让我们创建上面定义的类的对象-
obj1 = Car
完成了!请注意,您可以根据自己的选择更改对象名称。
尝试打印该对象-
打印(obj1)
由于我们的类为空,因此它返回存储对象的地址,即0x7fc5e677b6d8
在继续前进之前,您还需要了解班级指挥。
类构造器
到目前为止,我们有一个空的Car类,是时候用汽车的属性来填充我们的类了。类构造器的工作是在创建类的对象时将值分配给类的数据成员。
汽车可能具有各种属性,例如其名称,颜色,型号,品牌名称,发动机功率,重量,价格等。出于理解目的,我们仅选择其中一些。
车类: def __init __(自身,名称,颜色): self.name =名称 self.color =颜色
因此,汽车或任何其他对象的属性必须在我们称为__init __的方法内。此__init __方法也称为构造方法。每当构造类的对象时,我们都调用构造函数方法。
现在让我们谈谈__init __方法的参数。因此,此方法的第一个参数必须是self。然后,剩下的参数只会出现。
构造函数方法中的两个语句是–
self.name =名称self.color =颜色:这将创建新的属性,即名称和颜色,然后为它们分配相应参数的值。“ self”关键字表示该类的实例。通过使用“ self”关键字,我们可以访问类的属性和方法。它在方法定义和变量初始化中很有用。每当我们定义一个方法时,都会明确使用“自我”。
注意:您也可以在此__init __方法之外创建属性。但是这些属性对于整个类都是通用的,因此您必须为它们分配值。
假设陈列室中的所有汽车都是轿车,而不是一遍又一遍地指定,您可以通过在__init __外部创建一个属性来将car_type的值固定为轿车。
车类: car_type =“轿车” #class属性 def __init __(自身,名称,颜色): self.name =名称#instance属性 self.color =颜色#instance属性
在这里,实例属性指的是构造函数方法中的属性,即self.name和self.color。并且,Class属性是指构造函数方法外部的属性,即car_type。
3.类方法
到目前为止,我们已经添加了汽车的属性。现在是时候添加一些行为了。方法是我们用来描述对象行为的功能。它们也在类内定义。看下面的代码-
车类: car_type =“轿车”def __init __(个人,姓名,里程): self.name =名称 self.mileage =里程def说明(自己):return f“ {self.name}汽车的行驶里程为{self.mileage} km / l” def max_speed(self,speed): 返回f“ {self.name}以{speed} km / hr的最大速度运行”
在类中定义的除构造方法之外的方法称为实例方法。此外,我们有两个实例方法这里- 说明和MAX_SPEED。让我们逐一谈论它们-
description-此方法返回一个字符串,其中包含汽车的描述,例如名称和行驶里程。此方法没有其他参数。此方法使用实例属性。max_speed-此方法有一个附加参数,并返回一个显示汽车名称及其速度的字符串。请注意,附加参数速度未使用“ self”关键字。由于speed不是实例变量,因此我们不使用self关键字作为其前缀。让我们为上述类创建一个对象。
obj2 = Car(“ Honda City”,24.1)打印(obj2.description)打印(obj2.max_speed(150))
我们要做的是创建一个car类的对象,并传递了必需的参数。为了访问实例方法,我们使用object_name.method_name。
方法description没有任何其他参数,因此在调用它时没有传递任何参数。
max_speed方法有一个附加参数,因此我们在调用它时传递了一个参数。
注意:要记住的三件重要事情是:
您可以创建一个类的任意数量的对象。如果该方法需要n个参数,而您没有传递相同数量的参数,则将发生错误。参数的顺序很重要。让我们一一看
创建一个类的多个对象车类: def __init __(个人,姓名,里程): self.name =名称 self.mileage =里程 def max_speed(self,speed): 返回f“ {self.name}以{speed} km / hr的最大速度运行”本田=汽车(“本田城”,21.4) 打印(Honda.max_speed(150)) 斯柯达=汽车(“斯柯达明锐”,13) 打印(Skoda.max_speed(210))
传递了错误数量的参数。车类: def __init __(个人,姓名,里程): self.name =名称 self.mileage =里程本田=汽车(“本田城”) 印刷(本田)
由于我们没有提供第二个参数,因此出现了此错误。
参数顺序车类: def __init __(个人,姓名,里程): self.name =名称 self.mileage =里程 def说明(自己): return f“ {self.name}汽车的行驶里程为{self.mileage} km / l”本田=汽车(24.1,“本田城”) 打印(Honda.description)
弄乱!注意,我们更改了参数的顺序。
现在,有四个面向对象编程的基本概念- 继承,封装,多态和数据抽象。了解所有这些对于理解OOP非常重要。到目前为止,我们已经涵盖了OOP的基础知识,让我们进一步深入。
4. Python类中的继承
继承是一个类继承另一个类的属性和方法的过程。继承其属性和方法的类称为Parent类。从父类继承属性的类是Child类。
有趣的是,连同继承的属性和方法,子类可以具有自己的属性和方法。
如何继承父类?使用以下语法:
class parent_class:父类的主体class child_class(parent_class):儿童班的身体
让我们看一下实现-
车级:#父级 def __init __(个人,姓名,里程): self.name =名称 self.mileage =里程 def说明(自己): return f“ {self.name}汽车的行驶里程为{self.mileage} km / l” 宝马(汽车)级:#儿童级 通过 奥迪(汽车)类:#儿童类 def audi_desc: 返回“这是奥迪类的描述方法。”
obj1 = BMW(“ BMW 7-series”,39.53) 打印(obj1.description) obj2 = Audi(“ Audi A8 L”,14) 打印(obj2.description) 打印(obj2.audi_desc)
我们创建了两个子类“ BMW”和“ Audi”,它们继承了父类“ Car”的方法和属性。在BMW类中,我们没有提供其他功能和方法。而在Audi类中的另一种方法。
注意子类的对象如何在obj1.description和obj2.description的帮助下访问父类的实例方法description。而且,也可以使用obj2.audi_desc访问Audi类的单独方法。
5.封装
正如我在本文的第一部分中提到的,封装是一种确保安全性的方法。基本上,它隐藏了外部人无法访问的数据。例如,如果组织希望保护对象/信息免受客户端或任何未授权人员的有害访问,则封装是确保这一点的方法。
您可以在方法或属性名称之前使用单个下划线(_)声明受保护的方法或属性。如-self._name或def _method; 这两行都表明属性和方法是受保护的,不应在类和子类的访问权限之外使用,而是可以由类方法和对象访问。
尽管Python只是将_用作编码约定,但它告诉您应在类范围内使用这些属性/方法。但是您仍然可以像往常一样访问定义为保护的变量和方法。
现在,实际上是为了防止从类范围之外访问属性/方法,可以使用“ 私有成员 ”。为了将属性/方法声明为私有成员,请在前缀中使用双下划线(__)。如– self .__ name或def __method; 这两行都表明属性和方法是私有的,并且无法从类外部进行访问。
类车: def __init __(个人,姓名,里程): self._name =名称#受保护的变量 self.mileage =里程 def说明(自己): return f“ {self._name}汽车的行驶里程为{self.mileage} km / l”
obj = car(“宝马7系列”,39.53) #通过类方法访问受保护的变量 打印(obj.description) #直接从外部访问受保护的变量 打印(obj._name) 打印(obj.mileage)
注意我们如何访问受保护的变量而没有任何错误。显然,对该变量的访问仍然是公共的。让我们看看封装的工作原理-
车类: def __init __(个人,姓名,里程): self .__ name = name#私有变量 self.mileage =里程 def说明(自己): return f“ {self .__ name}汽车的行驶里程为{self.mileage} km / l”
obj = Car(“ BMW 7-series”,39.53) #通过类方法访问私有变量 打印(obj.description) #直接从外部访问私有变量 打印(obj.mileage) 打印(obj .__ name)
当我们尝试使用description方法访问私有变量时,没有遇到任何错误。但是,当我们尝试直接在类外部访问私有变量时,Python给了我们一个错误说明:car对象没有属性\__name。
您仍然可以使用其变形的名称直接访问此属性。名称修饰 是我们用于从外部访问类成员的一种机制。Python解释器会将带有“ __var”的任何标识符重写为“ _ClassName__var”。使用此方法,您还可以从外部访问该类成员。
车类: def __init __(个人,姓名,里程): self .__ name = name#私有变量 self.mileage =里程 def说明(自己): return f“ {self .__ name}汽车的行驶里程为{self.mileage} km / l”
obj = Car(“ BMW 7-series”,39.53) #通过类方法访问私有变量 打印(obj.description) #直接从外部访问私有变量 打印(obj.mileage) print(obj._car__name)#被缠住的名字
请注意,规则修改的设计主要是避免发生意外。但是仍然可以访问或修改被视为私有的变量。这在特殊情况下(例如在调试器中)甚至很有用。
6.多态性
这是希腊字。如果我们打破“多态”一词,就会得到“多”形和“变形”形。因此,多态性意味着具有多种形式。在OOP中,它是指名称相同但功能不同的功能。
奥迪课程: def说明(自己): print(“这是AUDI类的描述功能。”) 宝马级: def说明(自己): print(“这是BMW类的描述功能。”)
奥迪=奥迪 宝马=宝马 用于(奥迪,宝马)中的汽车: car.description
当使用对象audi调用该函数时,将调用Audi类的函数,而使用对象bmw调用该函数时,将调用BMW类的函数。
7.数据抽象
我们使用抽象来隐藏函数的内部细节或实现并仅显示其功能。这类似于您在不知道背景机制的情况下如何驾驶汽车的方式。或者,您知道如何使用开关打开或关闭电灯,但是您不知道插座后面发生了什么。
具有至少一个抽象功能的任何类都是抽象类。为了首先创建一个抽象类,您需要从abc模块导入ABC类。这使您可以在其中创建抽象方法。ABC代表抽象基类。
从abc导入ABC 类abs_class(ABC): 类的主体
重要的是 –您不能使用abstract方法为abstract类创建对象。例如-
从abc导入ABC,abstractmethod 轿车(ABC): def __init __(self,name): self.name =名称 @abstractmethod 定义价格(自我,x): 通过
obj =汽车(“本田城”)
现在的问题是我们如何准确地使用这种抽象。答案是通过使用继承。
从abc导入ABC,abstractmethod 轿车(ABC): def __init __(self,name): self.name =名称 def说明(自己): print(“这是汽车的描述功能。”) @abstractmethod 定义价格(自我,x): 通过 新车类(汽车): 定义价格(自我,x): print(f“ {self.name}的价格为{x}十万。”)
obj = new(“ Honda City”) obj.description obj.price(25)
Car是从abc模块的ABC类继承的抽象类。请注意,我在抽象类中有一个抽象方法(price)和一个具体方法(description)。这是因为抽象类可以同时包含这两种功能,而普通类则不能。从该抽象类继承的另一个类是new。此方法为抽象方法(price)定义,这是我们使用抽象函数的方式。
用户从new类创建对象并调用price方法后,new类内部的price方法的定义就会起作用。这些定义对用户隐藏。Abstract方法只是提供一个声明。子类需要提供定义。
但是,当为new类(即obj)的对象调用description方法时,将调用Car的description方法,因为它不是抽象方法。
尾注
总而言之,在本文中,我介绍了Python中面向对象编程的基本概念。
希望您了解这些文章中介绍的概念。如果您有任何疑问,请在下面的评论中告诉我。