如何向只用Fortran 77编码的人解释面向对象的编程?


11

我母亲在Fortran上完成了大学论文,现在(十多年后)需要学习c ++进行流体模拟。她能够理解所有过程编程,但是无论我多么努力向她解释对象,它都不会停留。(我在Java上做了很多工作,所以我知道对象是如何工作的)我想我可能会以太高层次的方式来解释它,所以对于那些从不与它们一起工作并且成长的人来说,这真的没有任何意义。在纯粹的程序化编程时代。

有什么简单的方法可以向她解释,以帮助她理解?


2
您可以在不成为木匠的情况下建造鸟屋。也许她可以以项目/程序方式开始该项目,并且您可以向她展示如何以OOP方式进行重构。有时不是“我不明白”,而是“我不明白为什么您会遇到麻烦”
JeffO 2012年

4
她是否真的需要自己编写面向对象的程序,还是以某种程序方式使用OpenFOAM足够了?
starblue 2012年

她想以一种面向对象的方式来做。至少,她需要了解如何与api(可能是对象和类)交互。(请注意,我没有对OpenFOAM做任何事情,所以有点猜测。)
Eric Pauley 2012年

1
我完全同意我以前的海报。您对什么是OOP以及她对使用该库的需求的理解可能彼此完全不同。我会联系该库的邮件列表,并询问一些高级用户如何解决lib问题。请不要试图“教”她的面向对象操作,这只会导致误解,而不能解决她的问题。
AndreasScheinert

Answers:


18

简短的回答:不。

长答案:没有“简单方法”,因为OOP远非简单。过程编程全部与“变量”和“ if then goto”有关。其他所有内容都是语法糖,但是这四件事就是过程编程的全部内容。一旦获得它们,没有什么可以阻止您。

OOP是一种组织变量和代码段的方法。有多少种模式可以定义OOP?25吗 30吗 即使是从不同语言和背景学习过OOP的老师也不同意其自己的定义,所以...它怎么简单?

我不知道您是怎么想到的,但是由于您母亲的经历与我相似,所以我可以告诉您我是如何想到的。

我在一个非常大的项目中用C编程。当时是1988年。许多程序员都在组织模块和库,但要避免避免干扰其他工作并保持良好的职责分离。

我们来到了一个“解决方案”,该解决方案是将所有相互关联的全局数据放入结构中,在这些结构中放置一些需要回调的函数指针。我们以这种方式概括了所谓的io_mask(各种文本模式对话框)graphic_manager等。

在1996年,很容易发现这些结构被命名为“类”,而那些函数指针被成员函数和虚拟函数所取代,或者被其他更新旧项目的程序员所链接到其他对象(称为行为)。

当我开始感到对OOP的需求时,我开始了解OOP :隔离,多态和运行时定义的行为。

今天,我与OOP一起工作,但我不认为它是服务的原则:只是一个“共同的成语”(...集),它使我们可以一起讲话,而无需一直提供冗长的解释和描述。 。实际上,最重要的是“常规”。毕竟,OOP所做的只是-如果-if then goto:它只是“多层”进行。因此,抽象和成语优于成语。

别理他们。直到她感觉不到它们的需要之前,都不要尝试解释:她会觉得它们就像做简单事情的复杂方式一样。她是对的...直到她所做的-实际上-很简单。

如果只有四件事,没有人会想到“整理桌子”。当最上面的东西开始相互干扰时,这才有意义。那是OOP出现的时候了。

您不需要OOP即可使用C ++。整个C ++标准库不是根据OOP设计的(尽管它可以与OOP配合使用),并且C ++不是Java。

从我的所有经验来看,最差的C ++老师和C ++程序员都是来自Java的人,他们对所有事物的偏见都不是OOP,会使像C ++这样的语言(不是)仅适用于OOP。

让我为那些想使用C ++的人推荐一本好书:Accelerated C ++:它将带您进入C ++习惯用法,而无需假装遵循预先定义的学说。


她需要了解c ++才能与OpenFOAM一起使用,因此她肯定需要很快了解类。我认为她了解其背后的基本思想。但是由于某种原因,她似乎被卡在“点结构”上。(即System.out.println(),在c ++中除外)
Eric Pauley 2012年

@Zonedabone,很容易理解(并解释)类,虚拟方法等的操作语义(正如此答案所暗示的那样)。这不是一门火箭科学。只是远离无用和无关的OOP“抽象”。
SK-logic

1
OOP很简单,而C ++“ OOP”不是。以Smalltalk为例(对象具有实例变量和类,类具有方法,您将消息发送给对象并由方法提供服务,基本上就是这样)。面向原型的OOP甚至可以使类脱离方程式。---这就是为什么我建议(如果可能)仅使用子集的原因(没有私有,没有保护,没有const,没有多重继承,所有方法都是虚拟的,所有析构函数都是虚拟的,等等),因此模型更简单。稍后添加其他内容。
Herby 2012年

7

一位老朋友声称我对OO编程的定义最短,我发现它对某些人(而不是其他人)有效:

面向对象的程序设计是带有观点的数据。 您不移动椅子,而是要求椅子自行移动。您不对列表进行排序,而是要求它对自身进行排序(可能带有提示)。等等。

这样做的目的是让人们以不同的方式思考程序内部如何完成事情。


+1这也通过“问,不告诉”。
user949300 2014年

您的意思是“告诉,不要问”。:)
拉蒙·莱昂

3

告诉她想像现实世界中的物体之类的物体。例如,整个世界可能是面向对象的程序设计(在C ++中)与某种功能性程序设计(可能是用上帝的语言Lisp完成)的混合体。

以一个物体为例,例如割草机,它具有一定的属性,并且可以做某件事。(对象和类)

然后告诉她一个更好的割草机,这是您现有割草机的扩展。告诉她更好,但仍建立在相同的机制(继承性)上。

然后告诉她关于你自己的事。告诉她,有时您可以成为割草专家,但实际上您是一名程序员,并且以谋生为生。就像您同时充当两个不同的实体一样。这是多态性。

等到她明白了,再告诉她如何用她必须学习的语言(C ++)来实现这些东西。

然后告诉她,如果她必须在计算机世界中编写这个世界的模拟,那么她将必须学习如何做到这一点。

当她知道如何将她对现实世界的想法转化为程序代码时。她将学习如何使用面向对象的编程语言进行编程。


@Zonedabone没问题,我花了一年的时间学习OOP(我自己学习),但是我使用了相同的示例:)并突然感到开悟。LOL
Aniket英格

5
不,不,不,不,不!以我的经验,“思考现实世界中的对象”是一种向还不了解OOP的人解释OOP 的糟糕方法。这导致对OOP的奇怪误解和错误应用,并且通常只会加深混乱。
JSBձոգչ2012年

多态的规则就像优化。规则A)请勿执行,规则B)(仅适用于专家!):请勿执行。
mattnz

1
同意JSBձոգչ。这是解释OOP 的一种非常常见的方式,但我认为这毫无用处。编程中的对象实际上不像现实生活中的对象。
罗恩·弗里曼

从本质上来说,过程编程和OO编程之间的区别是,在过程编程中,您考虑要按某种顺序进行的工作的列表,而在OO中则考虑状态。如果人们对状态有扎实的了解,他们可以有用地使用OO。然后尝试建立现实世界的模型。
Pieter B

1

我已经从汇编程序和COBOL转到了Ruby。

最初帮助我的实际上是忽略了创建实例的类的概念。

只需从代码开始。有一个类,但是只有类级别的方法。在方法中,很多东西与参数,变量,条件,数组,字符串,布尔值等有关。这些东西应该很熟悉。

因此,在这一点上,该类可以看作是作为目的来放置所有相关方法的地方。将其称为容器或库对她来说将更为熟悉。

显然,必须对代码进行分段以使其易于管理,因此您将在每个区域中拥有一个。例如,要在PC上管理一组实用程序,您可能有一个计算器类,可以在其中将计算器的所有代码放在一个地方。如果您的电脑上只有1个计算器,则类级别的方法就足够了。

那是一个开始。

好的,现在考虑您要打开多个计算器并更改每个计算器的外观以及它在屏幕上的位置这一事实。所以现在您不能只拥有像'screen_location'这样的计算器方法,因为您有多个方法,并且每个实例都有自己的位置...每个实例...好的,所以我们需要实例。

注意:我的术语来自ruby而不是c ++,因此您可能需要翻译。


0

我将分两个步骤或四个步骤来解释它,具体取决于您想拆分概念的程度。

步骤1:将她介绍给建筑物。从Fortran数据类型到结构,这仅是很小的一步。步骤1a:确保她了解动态内存分配和指针。

步骤2:添加仅与那些结构关联的过程。步骤2a:在构建“包裹”较小结构的较大结构的基础上添加继承。

对于Fortran程序员来说,“哇”的因素是编译器需要跟踪很多东西。对。那就是编译器的用途...


我认为她了解对象背后的过程。只是出于某种原因她不了解这些点。('。')真的很奇怪。我想当您开始编码时,必须手动完成所有事情(分配和工作)时,您会知道现代语言的内部工作原理是如何工作的,却不知道如何工作。
埃里克·保利

0

如果十年前她写论文,她可能会使用Fortan 90或95,在这种情况下,要讨论的是与衍生数据类型的关系。如果很久以前她使用Fortran 77,那么请向她介绍Fortran 90中的派生数据类型,然后再进行讨论...

在她掌握封装之后,我才将涉及多态性和继承,因为它们可以被视为特殊情况和封装的扩展。我可能会以允许自由函数或静态类的语言来介绍她。


0

一旦她了解了结构,我认为下一个关键点将是认识到面向对象编程是将事物可以传递给的方法集限制为可以实际应用于该方法集的一种手段。事情。

在非面向对象的编程中,如果一个树和一个LinkedList使用不同的数据类型,则必须使用不同的方法向每个树添加节点。非面向对象的语言一般会发牢骚如果试图命名这两种方法AddItem,因为任何给定的名称,只能是指一种方法,从而导致一个以创建像方法名AddTreeItemAddLinkedListItemRemoveTreeItem,等这种方法的作品,但它是一个有点丑陋。从概念上讲,方法AddTreeItemRemoveTreeItem似乎属于同一类,但名称却不是那样。人们可以为重写的名字TreeAddItemTreeRemoveItemLinkedListAddItem等等,但是这会在每次方法调用的开始时带来很多“冗余噪音”。典型程序中的绝大多数方法调用将具有三个基本信息:(1)源代码的哪一部分包含该方法;(2)正在使用本节中的哪种方法;(3)正在处理什么数据?在许多情况下,所作用的数据类型足以识别该方法属于哪个代码段,因此上述部分(1)是多余的。在语句开始处以视觉方式识别材料比在其他地方更容易识别材料,因此像这样的编码/命名风格TreeAddItem(myTree, whatever)最终将最不有用的信息放在了首位。

相比之下,使用面向对象的程序,可以将方法有效地命名为Tree.AddItem等,而类似的语句myTree.AddItem(whatever)将使编译器实质上说:“ Hmm ... myTree是类型的Tree,因此应调用此代码Tree.AddItem()。指定Tree.调用的时候AddItem,因为编译器知道的类型myTree从概念上讲,声明等。myTree.AddItem(whatever)相当于Tree.AddItem(myTree, whatever),以及一些面向对象的语言可能允许这两种形式是等同的;事实上,大多数语言省略从功能规范的第一个参数,而是有在一个类中定义这样的方法Tree隐含地采取类型的参数Tree,并为其分配一个名称等thisselfMe

面向对象的编程语言通常包括各种附加功能,例如继承,虚拟功能等,这些功能在许多应用程序中非常有用,但即使没有这些功能,根据功能对其进行分组的功能也非常有用。


0

面向对象的程序设计(在这里与类有关的意义上)是关于将数据表示形式与操作它的代码耦合在一起的。如果满足以下条件,这是有道理的:

  • 耦合:在操作所依据的数据表示形式旁边定义一个操作

  • 后期绑定:在运行时选择数据表示和行为的组合

  • 封装:确保数据在构造上是有效的,以后不会失效

就这样。像任何技术一样,从本质上讲,它只是一种便利,后来随之而来的是许多发展。一旦您了解了基础知识,其余的就会及时处理。


0

我建议下载BlueJ,玩20分钟,然后玩20分钟。

它可视化类,接口和继承的方式是如此明显和直观,以至于您在实现任何东西时都能立即获得理解。

它甚至直接向您显示类和对象之间的区别

它不会对OO设计模式有任何深入的了解,但是会提供有关概念的出色概述。


0

我想贡献自己的力量,以提醒人们注意编程范例与实现这些范例的编程语言之间的区别。

因此,我认为,向F77用户解释C ++的面向对象的最佳方法是逐步进行:

首先,向用户展示如何在Fortran 77中开发类似于对象的结构,从而向用户介绍面向对象的概念-例如,看看B. Patton等论文“面向对象的Fortran 77(从业者查看”),SIGPLAN Fortran论坛12,2(1993),第23-24页,以及其中的参考文献。

然后,在那些结构与C ++类和方法之间建立对应关系。

最后,讨论C ++可以提供的有助于OO编程的其他功能。


0

当我最初在Pascal上接受培训时迁移到面向对象的语言时,“。” 对我来说,问题也是最大的障碍。我花了好几年才能克服它。

一个变量属于另一个变量实际上是很不直观的,特别是当您习惯于将它们视为指针时。对我来说,绊脚石是:

  • 对于基本上是指针的东西,又有另一个指针指向它,它解析为与父指针不同的东西,这意味着什么?

对我而言,当我意识到顶级指针基本上只是一个命名空间时,我感到非常难受。

我建议让她编写一堆代码,要求她对功能进行命名空间,最好不要使用点符号开头。然后让她尝试使用点表示法重写它。

这样做a应该使她克服最初的“这是什么巫术?” 栏。


-2

以前帮助我解释的一个关键见解是您可以拥有一个类的多个实例。尝试用“图纸”或“模具”和“副本”来解释这一点,并查看它是否可以引导到任何地方。


不太了解否决票。这种解释方式已经帮助了我两次。并不是说这是灵丹妙药,但似乎人们陷入了困境。
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.