奥马尔孤独

面向对象的编程(OOP)是一个编程范例,专注于使用对象作为软件构建块。这种范式非常类似于人类如何在现实生活中感知物体,从而降低与软件开发相关的复杂性。必威真人投注

为什么面向对象的编程是有价值的

计算机程序可以用各种程序设计语言编写。这些语言使用不同的概念和范式来构造程序中的代码。在现代软件开发中,面向对象的程序设计语必威真人投注言通常用于编写大型和复杂的软件。面向对象编程是作为一种降低软件开发复杂性的方法而开发的,它使得构建和扩展大型软件程序更加容易必威真人投注

面向对象的分析,设计和编程与UML

最后更新2020年11月

畅销书
  • 126课
  • 各级
4.5 (402)

学习在c++, Java和c# |中使用UML进行OO分析,设计和编程由奥马尔孤独

探索课程

软件开发本质上是复必威真人投注杂的。有助于复杂性的一些因素包括:

旁边是不可能完全解决与软件开发相关的复杂性,但它可以在很大程度上减少。必威真人投注

解决复杂性:算法分解vs面向对象分解

人类以不同的方式解决复杂性。当面临问题时,我们倾向于简化它。调用一个简化过程“划分的et apera”在拉丁语中,意思是“分而治之”。在这个原则下,问题被分解成更小的部分。对于每个部分,我们创建一个解决方案并将它们连接在一起。这和我们解决复杂的算术问题很相似。

这是解决复杂性的常用方法。难怪早期的编程语言,如Cobol、Pascal和C,都是基于这个概念的。解决方案是作为一组算法实现的,其中每个算法由函数或过程表示。这就是为什么这些语言称为程序语言。此类语言使用功能作为程序的基本构建块。这也被称为自顶向下设计

这些语言将问题及其解决方案分解为一组算法。这就是所谓的算法分解.程序语言使用算法分解过程来解决复杂性。

对于大规模的软件开发,算法分解不会很好地缩放。必威真人投注它无法管理发展大型应用程序的复杂性。该应用程序由一个在另一个之后调用的函数组成。这使得它们彼此紧密耦合并依赖,导致以下问题:

使用算法分解的软件可以用图形表示如下:

这通过算法分解增加了软件开发的复杂性。必威真人投注

然而,人类通过这种方式处理复杂性。当我们与事物互动时,我们倾向于将它们视为提供一些功能的对象。不仅如此,我们不创建一个对象的简化视图,忽略与我们无关的细节。这个过程称为面向对象的分解因为系统被视为一组协作对象,并且每个对象都有一个角色播放。这也被称为a自底向上设计

由对象组成的系统可以由下图表示。

每个圆形块代表一个对象。这些线代表对象之间的交互。每个对象:

这表明对象之间通过消息(用行表示)进行通信。这与我们在现实生活中感知和与其他物体互动的方式非常吻合。我们处理对象的行为时不考虑内部实现细节。例如,当我们开车时,我们不处理它的内部实现。相反,我们通过发送诸如转向、加速和刹车等信息来驾驶。这样整个驾驶过程就简化了。

同样,面向对象的分解简化了软件开发的过程。必威真人投注它有助于管理大型软件项目的复杂性。

让我们比较算法和面向对象的分解:

算法的分解 面向对象的分解
系统被分解成实现为函数/程序的算法 系统被闯入协作对象
基本的构建块是一个函数 基本构建块是一个对象
函数依赖可能是全局的数据 对象有自己的数据
数据是全局的,因此可以由任何人修改 数据是对象私有的,只有该对象可以修改它
函数通过序列中的彼此呼叫通信 对象通过消息传递相互交互(方法调用)
函数之间是紧密耦合的 对象之间是松散耦合的
函数不能轻易重用 易于重用对象
添加新功能很困难 可以通过新对象添加新功能
不能代表现实生活实体或模拟他们的互动 现实生活实体可以通过没有不必要的细节来表示的
使用自上而下的设计 使用自底向上设计
不适合大型软件 适合大型软件

这个比较清楚地说明了为什么面向对象分解是解决软件复杂性的更好方法。面向对象分解的核心是对象。我们将在下一节中对此进行深入讨论。

定义一个对象

一个对象是一个可识别的项目或实体,可以是真实的或抽象的,并在问题域中提供一些功能。

对象可以是现实世界中存在的物理对象。真实世界的物体的例子是树,汽车或房子。它也可能是没有物理形式的抽象对象。它可能不是有形的,但仍然存在并代表重要的东西。例如,银行账户是一个抽象对象。它没有身体形式,但代表个人的资金。在软件系统中,我们使用抽象对象来定义程序中的特定实体。

每个对象都有以下三个特征:

让我们使用扬声器系统的示例来理解这些特征。

状态

状态对象由其属性组成,可以是静态或动态的。

扬声器系统的状态可以包括属性,例如:

卷是一个动态属性,可以随时间变化,而列出的其他属性是静态的,永远不会改变。

属性可能具有以下值:

输出功率 100瓦
连接 蓝牙
制造商 罗技
序列号 ABCD1234.
类型 5.1
体积 50%

属性值表示对象的状态 - 在这种情况下,上面的值表示特定扬声器系统的状态。

身份

对象的标识可以通过唯一标识该对象的属性来表示。在我们的扬声器系统示例中,唯一标识通过序列号提供。

行为

每个对象都将提供一些功能作为其责任的一部分,并且该功能由其表示行为.扬声器系统将提供以下行为:

调用这些行为将导致说话者系统以某种方式作出反应。注意,我们在调用行为时不处理内部实现。

从a创建一个对象班级

在编程语言中,对象来自类。可以创建任意数量的类对象。类是列出其对象的属性和行为的模板或蓝图。类包含数据和函数。函数通过对象对数据进行操作。

通过实例化类来创建对象。此过程通过调用对象的行为来初始化可以修改的值的属性。属性中的值构成对象的状态。每次实例化一个类时,它将创建一个具有新状态的新对象。

因此,对象是面向对象编程的基本构建块。

面向对象的编程

OOP是一种使用类和对象作为其构建块的编程范式。它是基于一个概念框架对象模型.该模型包含四个主要元素,用于定义面向对象的编程概念:

实现对象模型元素的语言称为面向对象语言,例如Java,C ++,C#和Python。尽管这些语言支持这些功能,但不了解这种概念框架,这些语言的编程仍然看起来像算法而不是类和对象。如果在您的工作中发生这种情况,很可能会正确地理解问题或域名。您的设计仍然有程序感受和包含功能/程序,这将难以扩展,重用和维护。

让我们了解对象模型的四个元素。

抽象

抽象是人类使用复杂性的基本方法之一。它允许我们仅关注相关细节,同时忽略或抑制不需要的细节。这让我们形成了一个抽象这代表了对象的整个基本行为。

在对象模型中,抽象可以指代a过程实体.抽象作为一个过程处理提取物品的重要细节。抽象作为A.实体指抽象过程的结果。

执行抽象是面向对象编程的第一步。这让我们能够专注于重要的方面,而忽略不重要的方面。在面向对象语言中,类以实体的形式表示抽象。类可以表示具有所需行为的现实对象。这些类是通过实体抽象创建的,因为它们直接表示存在于问题域词汇表中的对象,从而简化了我们对系统的理解。

借鉴第一人称射击电脑游戏的例子。球员的目标是到达森林的边缘,这是怪物居住的。球员对怪物防御和冒犯的枪。如果我们执行面向对象的分解,我们在游戏中找到以下主要对象:

下一步是以面向对象的编程语言代表这些对象。但是,我们必须确定我们在这些对象中所需的细节水平。让我们只关注播放器以简单。一名球员是一个控制游戏的人。一个人有一个长期的属性,例如:

游戏中的大部分都不是必需的,并且在该领域不相关。控制玩家的人的相关细节是:

可能更多地取决于游戏的类型,但对于这个例子,这些是我们游戏中最重要的。

这是抽象的结果。我们创建了一个具有相关细节的实体,忽略了其余的,因为它们不是必需的。这降低了与对象相关的复杂性。

让我们在Java程序中实现抽象。这是一种非常流行的语言,易于学习。有无数的Java教程和数以千计的书籍,可以帮助您学习和编写程序。

现在,我们可以通过班级代表玩家..

班级球员{公共INT health = 100;公共字符串名称;};

您可以指定与抽象相关的任何数据类型。在此抽象中,INT&String类型与我们想要捕获的信息相关,并表示数据的概念球员.这两个数据类型成为类的成员,并且称为字段或数据成员。

的实例创建之后球员,我们可以为此特定播放器分配名称和健康。但是这个课程有一些问题:

抽象本身并不是很有用,因为客户可以看到内部。因此,我们将通过内部细节隐藏封装

封装

封装是抽象之后的逻辑步骤。它隐藏了抽象的实现细节。它也被称为信息隐藏,作为关于如何实施类的信息是隐藏的来自外部世界。抽象反过来负责向客户提供其功能。

因此,我们示例中的下一步是添加实现球员课堂不公开细节。让我们修改播放器类并封装它。

班级球员{私有INT health = 100;私有字符串名称;公共空白攻击(敌人){//实施}公共空缺武田(int损坏){health  -  =伤害;If(健康< 0)健康= 0;Public Int Gethealth(){返回健康;}公共布尔alive(){返回健康!= 0;}}

抽象现在通过添加方法(类内部的函数)来封装。由于这些方法是类的一部分,它们可以访问类的私有成员,包括字段。

有了这个,我们创建了一个字段和方法的绑定。这些将共同提供类的功能。

现在,该类的内部细节现在通过封装隐藏。所有数据成员(字段)都是私有的,使其无法访问课外。

封装其实施的课程有几个优点:

假设我们决定在游戏设计之后为ARMOR添加支持。我们可以修改实施Takedamage()解释对损害较少的方法球员当它有盔甲。客户不必看到这一变化的实施Takedamage()方法。

我们也可以实现敌人课程如下:

敌人{INT Health = 100;强大;公共空缺武装(int伤害){health  -  =伤害;If(健康< 0)健康= 0;}公共void攻击玩家(播放器播放器){//实现}}

游戏的碰撞系统将调用适当的行为球员敌人对象取决于游戏玩法。

最后,请记住抽象和封装在手中。抽象提供实现和封装隐藏其实现细节。

等级制度

这指的是类和/或对象之间的关系。软件中的对象,就像现实生活中的对象一样,不是孤立存在的。它们与其他物体相互作用,并可能表现出某种关系。为对象分配层次结构简化了我们对对象如何相互协作的理解。有两种方法可以定义关系——对象组合和类继承。

如果一个对象具有另一个对象所需的功能,则可以使用作品的关系。在组合中,一个对象将被组合到另一个对象中。这也被称为部分的关系。这些关系是由物体展出的。

在我们的例子中,球员班级可能会用枪攻击怪物。拍摄行为可以由另一个课程提供.而不是重新实现这个功能,而不是重新实现这个功能球员班级将简单地重用它.因此,球员班将撰写实例。

班枪{int bulletdamage = 10;int bulletcount = 50;public int拍摄(){//减少子弹计数返回bulletdamage;} //其他方法,如重新加载,Pickammo等}级播放器{私人枪枪=新枪();私人INT Health = 100;私有字符串名称;公共空白攻击(怪物怪物){int伤害= gun.shoot();monster.tkatedamage(损坏);} //剩下的实施

这样,球员班级不必重新实现枪支功能。它可以通过简单地组成的功能来重用功能实例。

通过泛化创建其他关系。概括代表不同单独对象的共同特征。例如,汽车是不同类型的汽车的概括 - 它代表了汽车的所有共同属性和行为。所以,我们可以说BMW或Tesla是一种汽车。两者都提供了汽车的行为,但以不同的方式提供。这被称为“类型”或“是”的关系。在面向对象的编程中,我们将其称为继承.这种关系适用于类。

继承允许我们将不同类的共同功能放入一个广义类。广义类称为超级或基类。其他类将继承此类的功能,并且称为子类或子类。基类代表其子类可以提供的所有功能,尽管以不同的方式。调用此类的订购类层次结构

这种方法的优点是:

在我们的电脑游戏中,我们想要添加不同类型的敌人以保持游戏玩法的趣味性。每个敌人都有自己的属性和攻击玩家的不同方式。有几个敌人是:

敌人 的攻击方式
狼人 爪子

来攻击这些敌人球员班级必须了解他们的相应课程。这需要修改球员和课程之间的紧密耦合。如果我们将来添加更多课程,我们必须重复修改球员类。每次修改都可能引入bug,并以意想不到的方式破坏代码。错误可能累积到软件最终失败的程度。

可以以图形方式表示此依赖性:

尽量,我们应该尽量减少类之间的依赖。箭头显示了依赖球员上课狼人类。

狼人分享一些属性和行为。例如,两者都会有健康和力量。两者都会以自己的方式攻击玩家。因此,我们应该能够通过创建包含所有敌方类的共同功能的类来概括它们。我们打电话给这个课怪物

class Monster{private int health = 100;私人int实力;public Monster(int strength) {this。Strength =力量;} public void takeDamage(int damage){健康-=损害;If(健康< 0)健康= 0;public void taskplayer(){//实现}}

在Java中,我们使用关键字扩展代表继承关系。这是实施狼人类:

什班斯瓦尔夫延伸怪物{公共狼人(INT强度){超级(力量);public void taskplayer(){//与claws攻击}}级龙延伸怪物{int firedamage;公共龙(INT力量,int Filedamage){超级(力量);这个.Fiedamage = Filedamage;public void taskplayer(){//实现}}

类的特性继承怪物但提供自己的实施攻击玩家()方法。这是必要的,因为它们以不同的方式攻击玩家。因此,它们可以添加自己的实现,除了它们从Monster继承的实现。你们可能注意到了类具有支持其攻击模式的属性。然而,Takedamage()方法实现对于所有类都是常见的,并且不需要在子类中重新实现。

现在,唯一的问题是玩家课程如何与这些类交互?答案是通过基类怪物.记住,怪物表示所有子类的概括。其对象可以对子类对象进行引用。

怪物怪物=新狼人(20);monster.attackplayer();

在这种情况下,a怪物对象具有参考狼人.子类型,狼人,转换为怪物通过一个名为typecasting的过程。这只是意味着转换一种类型到另一个类型。在这种特殊情况下,施放的类型称为扫物,因为施放是从儿童到父母的。将子实例分配给基类引用时自动应用此演员。这使我们能够使用狼人对象通过怪物参考。

现在球员只需要与之互动怪物班级,不必处理其子类。

这可以如下图所示:

控件之间的依赖关系是如何减少到只有一个连接的球员怪物基类。现在我们可以在没有修改的情况下添加更多怪物到游戏球员类。

球员Class应该能够在不知道他们是谁的情况下发送不同种类的怪物的消息(调用方法)。我们将更新攻击()方法球员如下:

公共空白攻击(怪物怪物){Monster.Takedamage(20);}

你可能想知道当Takedamage()在怪物参考上调用方法。它应该调用正确对象的方法而不是怪物类。这可以通过多态性来实现。

多态性

多态性意味着“多种形式”。这与在对象之间传递的消息有关。当对象向另一个对象发送消息时,目标对象应该正确响应。如果目标对象是基类对象,则在内部引用子对象,则该消息将自动转到子对象。

在我们的例子中,消息是方法调用:Takedamage().这狼人课程已重新实施Takedamage()方法,并提供了它们自己的实现。这就是所谓的方法覆盖,不要与方法重载混淆。被覆盖的方法被称为多态

控件上调用此重写的方法时怪物参考,它将调用该方法潜在的对象而不是怪物参考。在编译时不知道哪个对象的方法将被调用。此分辨率将在运行时发生。这也被称为动态多态性

在Java中,默认情况下,所有方法都是多态性的,可以覆盖。在其他语言中,您可能必须使用关键字来指示覆盖行为。例如,C#和C ++使用虚拟的关键词。请注意,只能覆盖多态方法。

然而,在Java中,我们使用@Override.注释,以指示重写的意图。注意,它的用法是可选的。

什班斯瓦尔夫延伸怪物{公共狼人(INT强度){超级(力量);@override public void taskplayser(){//用claws攻击}}

在其他情况下,您还可以实现编译时多态性。要调用的方法是在编译时确定的,通常通过对方法的参数。这是以面向对象的语言重载的函数过载。

多态性有几个优点:

结论

在现代软件开发中使用的大多数语言实现了对象模型的概念框架。必威真人投注此类语言允许我们创建大型软件。它们通过抽象,层次结构和其他元素帮助降低复杂性。

这些是人类处理复杂性的自然方式。将已知的元素集成到语言中减少了与软件开发相关的整体复杂性。必威真人投注

应用程序必威真人投注的开发并不会在产品发布后结束。软件只是进入了维护的不同阶段——这种维护仅仅意味着对现有软件的更改。它包括错误修复、新组件的添加、旧特性或不需要的特性的弃用,等等。对已经部署的软件进行这些更改是困难的。这些更改也可能必须在开发阶段合并,这将带来一系列挑战。必威真人投注

如果软件是用对象模型的概念框架编写的,那么软件组件将是松散耦合的。这简化了对现有软件的修改,因为更改将本地化到特定的组件。其修改不会影响软件的其他部分。同样,我们可以通过简单地添加新类来添加新特性。

因此,我们已经看到了面向对象编程如何简化软件开发的整个过程。必威真人投注这就是为什么这是现代软件开发中最常用的编程范式。必威真人投注

然而,存在面向对象的编程的替代方法,例如功能编程,通用编程和程序编程。大多数现代语言都支持多个范式,程序员利用编写更复杂的程序。

面向对象编程的顶级课程

c# 8.0 - OOP -终极指南-初学者到高级
由Harsha Vardhan的网络大学
4.7 (227)
C#中间:类,接口和OOP
Mosh Hamedani.
4.6 (23,548)
畅销书
面向对象的分析,设计和编程与UML
奥马尔孤独
4.5 (402)
畅销书
Java面向对象编程:汤匙Ooad和设计模式
基础知识
4.4 (264)
畅销书
完整的PHP OOP概念为绝对初学者+项目
Srinivas Vanamala.
4.8 (318)
使用Python掌握4项关键技能
Mostafa Saad易卜拉欣博士
4.9 (437)
畅销书
PHP OOP:面向对象的初学者+项目编程
Edwin Diaz,编码教师解决方案
4.5 (3,275)
Python编程
Gulshan Bajaj
4.4 (47)
畅销书
面向对象的编程 - 从基础推进(Java)
Andrii Piatakha,学习IT大学
4.4 (443)

更多面向对象的编程课程

面向对象编程的学生也学习

让你的团队。领导行业。

通过Udemy为Business获取组织的在线课程和数字学习工具库的订阅。

请求演示

奥马尔孤独的课程

完整的现代c++ (c++ 11/14/17)
奥马尔孤独
4.5 (3074)
面向对象的分析,设计和编程与UML
奥马尔孤独
4.5 (402)
畅销书
C / C ++指针和应用程序
奥马尔孤独
3.9 (115)
检测C / C ++应用程序中的内存泄漏
奥马尔孤独
4.5 (50)
现代C ++的创造设计模式
奥马尔孤独
4.6 (43)
收视率最高
现代C ++中的结构设计模式
奥马尔孤独
4.5 (20)
c++模板开始
奥马尔孤独
4.5 (996)

奥马尔孤独的课程