Wie kann ich jemandem, der nur in Fortran 77 codiert ist, die objektorientierte Programmierung erklären?


11

Meine Mutter hat ihre College-Arbeit in Fortran gemacht und muss jetzt (über ein Jahrzehnt später) C ++ für Flüssigkeitssimulationen lernen. Sie ist in der Lage, die gesamte prozedurale Programmierung zu verstehen, aber egal wie sehr ich versuche, ihr Objekte zu erklären, es bleibt nicht hängen. (Ich arbeite viel mit Java, damit ich weiß, wie Objekte funktionieren.) Ich denke, ich erkläre es möglicherweise auf zu hoher Ebene, sodass es für jemanden, der noch nie mit ihnen gearbeitet hat und gewachsen ist, keinen Sinn ergibt im Zeitalter der rein prozeduralen Programmierung.

Gibt es eine einfache Möglichkeit, sie ihr zu erklären, die ihr das Verständnis erleichtert?


2
Sie können ein Vogelhaus bauen, ohne Zimmermann zu werden. Vielleicht kann sie mit dem Projekt beginnen, indem sie es auf ihre / prozedurale Weise macht, und Sie könnten ihr zeigen, wie man es auf OOP-Weise umgestaltet. Manchmal ist es nicht "Ich bekomme kein OOP", sondern "Ich verstehe nicht, warum du so
viel

4
Muss sie wirklich selbst objektorientiert programmieren oder reicht es aus, OpenFOAM prozedural zu verwenden?
Starblue

Sie will es objektorientiert machen. Zumindest muss sie verstehen, wie man mit den Apis umgeht, bei denen es sich wahrscheinlich um Objekte und Klassen handelt. (Beachten Sie, dass ich mit OpenFOAM nichts gemacht habe, das ist also eine Vermutung.)
Eric Pauley

1
Ich stimme meinem vorherigen Poster voll und ganz zu. Ihre Wahrnehmung dessen, was OOP ist und was sie benötigt, um diese Bibliothek zu verwenden, kann sehr unterschiedlich sein. Ich würde die Mailingliste dieser Bibliothek kontaktieren und einige ältere Benutzer fragen, wie sie Probleme mit der Bibliothek angehen. Bitte versuchen Sie nicht, ihr OOP beizubringen, da dies nur zu Missverständnissen führt, ohne ihr Problem zu lösen.
AndreasScheinert

Antworten:


18

Kurze Antwort: nein.

Lange Antwort: Es gibt keinen "einfachen Weg", weil OOP alles andere als einfach ist. Bei der prozeduralen Programmierung dreht sich alles um "Variablen" und "wenn dann gehe". Alles andere ist syntaktischer Zucker, aber diese vier Dinge sind alles, worum es bei der prozeduralen Programmierung geht. Sobald Sie sie erhalten, kann Sie nichts mehr aufhalten.

OOP ist eine Möglichkeit, Variablen und Codeteile zu organisieren. Wie viele Muster gibt es, um OOP zu definieren? 25? 30? Selbst Lehrer, die OOP aus verschiedenen Sprachen und Hintergründen gelernt haben, sind sich nicht einig über ihre eigene Definition. Wie kann das einfach sein?

Ich weiß nicht, wie du dazu gekommen bist, aber da deine Mutter eine ähnliche Erfahrung wie ich hat, kann ich dir sagen, wie ich dazu gekommen bin.

Ich habe in C in einem sehr großen Projekt programmiert. Es war 1988. Viele Programmierer organisierten Module und Bibliotheken mit der Schwierigkeit, Störungen in anderen Berufen zu vermeiden und eine gute Aufgabentrennung aufrechtzuerhalten.

Wir kamen zu einer "Lösung", die darin bestand, alle miteinander verbundenen globalen Daten in Strukturen zu platzieren und in diese Struktur einige Funktionszeiger zu setzen, für die Rückrufe erforderlich waren. Wir haben auf diese Weise verallgemeinert, was wir genannt haben io_mask(Art von Textmodus-Dialogfeldern) und graphic_managerusw. usw.

1996 war es sehr leicht festzustellen, dass diese Strukturen als "Klassen" bezeichnet wurden und diese Funktionszeiger durch Elementfunktionen und virtuelle Funktionen ersetzt wurden oder durch Links zu anderen Objekten (als Verhalten bezeichnet) von anderen Programmierern, die dieses alte Projekt erneuerten.

Ich fing an, OOP zu verstehen, als ich anfing, das Bedürfnis danach zu spüren : Segregation, Polymorphismus und zur Laufzeit definiertes Verhalten.

Heute arbeite ich mit OOP, aber ich sehe es nicht als eine Lehre, der wir dienen sollen: nur eine "gemeinsame Redewendung" (Satz von ...), mit der wir miteinander sprechen können, ohne ständig lange Erklärungen und Beschreibungen liefern zu müssen . In der Tat mehr eine "Konvention" als alles andere. Immerhin ist alles, was OOP tut, wieder "wenn dann gehe": es macht es einfach "mehrschichtig". Daher Abstraktion und Redewendungen über Redewendungen.

Ignoriere sie. Bis sie nicht das Bedürfnis nach ihnen verspürt, versuchen Sie nicht einmal zu erklären: Sie wird sie als eine komplizierte Art empfinden, einfache Dinge zu tun. Und sie hat Recht ... bis das, was sie tut, tatsächlich einfach ist.

Niemand wird daran denken, "einen Schreibtisch zu organisieren", wenn nur vier Dinge oben drauf sind. Es ist sinnvoll, wenn sich die Dinge an der Spitze gegenseitig stören. Das ist die Zeit für OOP.

Sie benötigen kein OOP, um mit C ++ zu arbeiten. Die gesamte C ++ - Standardbibliothek ist nicht in Bezug auf OOP konzipiert (obwohl sie damit zusammenarbeiten kann), und C ++ ist kein Java.

Nach all meiner Erfahrung sind die schlechtesten C ++ - Lehrer und C ++ - Programmierer diejenigen, die aus Java stammen. Alle ihre Vorurteile über alles zu lehren, ist nicht OOP, und denaturiert eine Sprache wie C ++, die nicht (nur) für OOP ist.

Lassen Sie mich ein gutes Buch für diejenigen vorschlagen, die sich C ++ nähern möchten: Accelerated C ++ : Es bringt Sie in C ++ - Redewendungen, ohne vorzugeben, einer vordefinierten Doktrin zu folgen.


Sie muss C ++ kennen, um mit OpenFOAM arbeiten zu können, also muss sie definitiv bald Klassen kennen. Ich denke, sie versteht die Grundideen dahinter. Aus irgendeinem Grund scheint sie jedoch an der „Punktstruktur“ festzuhalten. (dh System.out.println (), außer in c ++)
Eric Pauley

@Zonedabone, es ist ziemlich einfach, eine operative Semantik von Klassen, virtuellen Methoden usw. zu verstehen (und zu erklären) (genau wie diese Antwort nahelegt). Es ist keine Raketenwissenschaft. Halte dich einfach von den nutzlosen und irrelevanten OOP "Abstraktionen" fern.
SK-Logik

1
OOP ist (irgendwie) einfach, C ++ "OOP" nicht. Nehmen Sie Smalltalk (Objekt hat Instanzvariablen und eine Klasse, Klasse hat Methoden, Sie senden eine Nachricht an und ein Objekt, das von einer Methode bedient wird, das ist es im Grunde). Prototyporientiertes OOP kann sogar Klassen aus der Gleichung streichen. --- Deshalb würde ich (wenn möglich) empfehlen, nur eine Teilmenge zu verwenden (keine private, keine geschützte, keine const, keine Mehrfachvererbung, alle Methoden virtuell, alle Destruktoren virtuell usw.), damit das Modell einfacher ist. Fügen Sie später weitere Dinge hinzu.
Herby

7

Ein alter Freund behauptete, ich hätte die kürzeste Definition, die er von OO-Programmierung kenne, und ich habe festgestellt, dass sie für einige Leute funktioniert (und nicht für andere):

Objektorientierte Programmierung sind Daten mit einer Meinung. Sie bewegen den Stuhl nicht, Sie bitten den Stuhl, sich selbst zu bewegen. Sie sortieren die Liste nicht, Sie bitten sie, sich selbst zu sortieren (möglicherweise mit einem Hinweis). Etc.

Die Idee ist, die Person dazu zu bringen, anders darüber nachzudenken, wie Dinge in ihrem Programm erledigt werden.


+1 Dies gilt auch für "Fragen, nicht erzählen".
user949300

Du meinst "Sag, frag nicht". :)
Ramon Leon

3

Sagen Sie ihr, sie soll an Objekte wie Objekte in der realen Welt denken. Zum Beispiel kann die ganze Welt eine Mischung aus objektorientierter Programmierung (in C ++) mit einer Art funktionaler Programmierung sein (wahrscheinlich in Gottes Sprache, Lisp).

Nehmen Sie ein Objekt, zum Beispiel den Rasenmäher, es hat bestimmte Eigenschaften und es kann eine bestimmte Sache tun. (Objekt und Klasse)

Dann erzähle ihr von einem besseren Rasenmäher, der eine Erweiterung des Rasenmähers ist, den du bereits hast. Sagen Sie ihr, es ist besser, baut aber immer noch auf demselben Mechanismus (Vererbung) auf.

Dann erzähl ihr von dir. Sagen Sie ihr, dass Sie manchmal ein Rasenmäh-Experte werden können, aber tatsächlich ein Programmierer sind und es für Ihren Lebensunterhalt tun. Dies ist so, als würden Sie gleichzeitig als zwei verschiedene Einheiten agieren. Das ist Polymorphismus.

Wenn sie das bekommt, erzähle ihr, wie sie diese Dinge in der Sprache implementieren kann, die sie lernen muss (C ++).

Dann sag ihr, wenn sie eine Simulation dieser Welt in der Computerwelt schreiben muss, muss sie lernen, wie es geht.

Wenn sie weiß, wie sie ihre Gedanken an die reale Welt in Programmcode umwandeln kann. sie hätte gelernt, in objektorientierter Programmiersprache zu programmieren.


@Zonedabone kein Problem, ich habe 1 Jahr gebraucht, um OOP zu lernen (ich habe es selbst gelernt), aber ich habe die gleichen Beispiele verwendet :) und fühlte mich plötzlich erleuchtet. LOL
Aniket Inge

5
Nein nein Nein Nein Nein! Nach meiner Erfahrung ist "Denken Sie an Objekte in der realen Welt" eine schreckliche Möglichkeit, OOP jemandem zu erklären, der es noch nicht versteht. Es führt zu bizarren Missverständnissen und Fehlanwendungen von OOP und vertieft oft nur die Verwirrung.
JSB 8

Regeln für Polymorphismus sind wie Optimierung. Regel A) Tu es nicht., Regel B) (Nur für Experten!): Tu es noch nicht.
Mattnz

1
Stimmen Sie mit JSB überein ձոգչ. Es ist eine sehr übliche Art, OOP zu erklären, aber meiner Meinung nach ist es wirklich nicht hilfreich. Objekte in der Programmierung sind wirklich nichts wie Objekte im wirklichen Leben.
Rowan Freeman

Der Unterschied zwischen prozeduraler und OO-Programmierung besteht im Wesentlichen darin, dass Sie bei der prozeduralen Programmierung über eine Liste von Aufgaben in einer bestimmten Reihenfolge nachdenken und bei OO über den Status. Wenn Menschen ein solides Verständnis für den Zustand haben, können sie OO sinnvoll einsetzen. Viel mehr als der Versuch, die reale Welt zu modellieren.
Pieter B

1

Ich bin von Assembler und COBOL zu Ruby gewechselt.

Was mir anfangs geholfen hat, war das Konzept der Klassen, die Instanzen erstellen, zu ignorieren.

Beginnen Sie einfach mit dem Code. Haben Sie eine Klasse, aber nur Methoden auf Klassenebene. Innerhalb von Methoden geht es bei vielen Dingen um Parameter, Variablen, Bedingungen, Arrays, Strings, Boolesche Werte usw. Diese Dinge sollten bekannt sein.

An diesem Punkt kann die Klasse so gesehen werden, dass sie nur dem Zweck dient, all Ihre verwandten Methoden einzufügen. Nennen Sie es einen Container oder eine Bibliothek, die ihr vertrauter ist.

Offensichtlich muss der Code segmentiert werden, um verwaltbar zu sein, damit Sie in jedem Bereich einen davon haben. Zum Verwalten einer Reihe von Hilfsprogrammen auf einem PC verfügen Sie möglicherweise über eine Taschenrechnerklasse, in der Sie den gesamten Code für einen Taschenrechner an einem Ort ablegen können. Wenn Sie nur 1 Taschenrechner auf Ihrem PC haben, reichen Methoden auf Klassenebene aus.

Das ist ein Anfang.

OK, bedenken Sie jetzt die Tatsache, dass Sie mehrere Taschenrechner öffnen und ändern möchten, wie jeder aussieht und wo er auf dem Bildschirm angezeigt wird. Jetzt können Sie nicht einfach eine Taschenrechnermethode wie 'screen_location' verwenden, da Sie mehrere davon haben und jede Instanz ihren eigenen Speicherort hat ... jede Instanz ... ok, also brauchen wir Instanzen.

Hinweis: Meine Begriffe stammen von Ruby, nicht von C ++, daher müssen Sie möglicherweise übersetzen.


0

Ich würde es in zwei oder vielleicht vier Schritten erklären, je nachdem, wie sehr Sie Ihre Konzepte aufteilen möchten.

Schritt 1: Machen Sie sie mit Strukturen bekannt. Es ist ein ziemlich kleiner Schritt von Fortran-Datentypen zu Strukturen. Schritt 1a: Stellen Sie sicher, dass sie die dynamische Speicherzuordnung und die Zeiger versteht.

Schritt 2: Fügen Sie Prozeduren hinzu, die nur diesen Strukturen zugeordnet sind. Schritt 2a: Hinzufügen einer Vererbung basierend auf dem Aufbau größerer Strukturen, die kleinere Strukturen "umschließen".

Für einen Fortran-Programmierer ist der "Wow" -Faktor, dass der Compiler viel im Auge behalten muss. Jep. Dafür sind Compiler da ...


Ich denke, sie versteht den Prozess hinter Objekten. Es ist nur so, dass sie aus irgendeinem Grund die Punkte nicht versteht. ('.') Es ist wirklich komisch. Ich denke, wenn Sie mit dem Codieren beginnen, wenn alles manuell erledigt werden muss (Zuordnung und so), wissen Sie, wie das Innenleben moderner Sprachen funktioniert, ohne zu wissen, wie man sie bearbeitet.
Eric Pauley

0

Wenn sie ihre Diplomarbeit vor einem Jahrzehnt gemacht hat, hat sie wahrscheinlich Fortan 90 oder 95 verwendet. In diesem Fall ist es wichtig, in Bezug auf abgeleitete Datentypen darüber zu sprechen. Wenn es lange genug her ist, dass sie Fortran 77 verwendet hat, stellen Sie ihr abgeleitete Datentypen in Fortran 90 vor und sprechen Sie dann darüber ...

Ich würde nicht auf Polymorphismus und Vererbung eingehen, bis sie die Einkapselung begriffen hat, da sie als Sonderfälle und Erweiterungen der Einkapselung angesehen werden können. Ich würde sie wahrscheinlich mit einer Sprache beginnen, die entweder freie Funktionen oder statische Klassen erlaubt.


0

Sobald sie Strukturen verstanden hat, denke ich, wird der nächste wichtige Punkt darin bestehen, zu erkennen, dass objektorientierte Programmierung dazu dient, die Menge der Methoden, an die eine Sache übergeben werden kann, auf die Menge der Methoden zu beschränken, die tatsächlich darauf angewendet werden könnten Sache.

Wenn in der nicht objektorientierten Programmierung separate Datentypen für einen Baum und eine verknüpfte Liste verwendet werden, müssten unterschiedliche Methoden zum Hinzufügen eines Knotens zu jedem verwendet werden. Nicht-objektorientierten Sprachen würde squawk im Allgemeinen , wenn man versucht , beide Methoden zu nennen AddItem, da nur jeder gegebenen Namen ein Verfahren beziehen, damit eine führende wie Methodennamen zu erstellen AddTreeItem, AddLinkedListItem, RemoveTreeItemusw. Ein solcher Vorgang funktioniert, aber es ist ein bisschen hässlich. Konzeptionell scheinen die Methoden AddTreeItemund zusammen RemoveTreeItemzu gehören, aber die Namen sortieren nicht so. Man könnte den Namen umschreiben als TreeAddItem, TreeRemoveItem,LinkedListAddItemusw., aber das würde zu Beginn jedes Methodenaufrufs viel "redundantes Rauschen" verursachen. Die überwiegende Mehrheit der Methodenaufrufe in einem typischen Programm enthält drei wesentliche Informationen: (1) Welcher Abschnitt des Quellcodes enthält die Methode? (2) welche der Methoden in Abschnitt verwendet wird; (3) Auf welche Daten wird reagiert? In vielen Fällen reicht die Art der Daten, auf die reagiert wird, aus, um zu identifizieren, zu welchem ​​Codeabschnitt die Methode gehört, sodass Teil (1) der obigen Angaben redundant ist. Es ist einfacher, Material zu Beginn einer Anweisung visuell zu identifizieren als Material an anderer Stelle, sodass bei einem Codierungs- / Benennungsstil wie TreeAddItem(myTree, whatever)am Ende die am wenigsten nützliche Information an erster Stelle steht.

Im Gegensatz dazu würde man bei objektorientierter Programmierung Methoden effektiv als Tree.AddItemusw. bezeichnen, und eine Anweisung wie myTree.AddItem(whatever)würde einen Compiler dazu veranlassen, im Wesentlichen zu sagen: "Hmm ... myTreeist vom Typ Tree, daher sollte dieser Code aufgerufen werden Tree.AddItem(). Dies ist nicht erforderlich." Geben Sie das Tree.beim Aufrufen an, AddItemda der Compiler den Typ von kennt myTree. Konzeptionell ist eine Anweisung wie myTree.AddItem(whatever)äquivalent zu Tree.AddItem(myTree, whatever), und einige objektorientierte Sprachen können beide Formen als äquivalent zulassen. Tatsächlich lassen die meisten Sprachen den ersten Parameter in der Funktionsspezifikation weg und haben stattdessen Verfahren, wie in einer Klasse definiert sind Treenehmen implizit einen Parameter vom Typ Tree, und es einen Namen wie zuweisen this, selfoder Me.

Objektorientierte Programmiersprachen enthalten häufig eine Vielzahl zusätzlicher Funktionen wie Vererbung, virtuelle Funktionen usw., die in vielen Anwendungen sehr nützlich sind, aber auch ohne diese Funktionen ist die Möglichkeit, Funktionen nach den Funktionen zu gruppieren, mit denen sie arbeiten, sehr nützlich.


0

Bei der objektorientierten Programmierung - im hier relevanten klassenorientierten Sinne - geht es darum, eine Datendarstellung mit dem Code zu koppeln, der sie manipuliert. Es ist sinnvoll, wenn folgende Dinge sinnvoll sind:

  • Kopplung: Definieren einer Operation neben der Datendarstellung, an der sie arbeitet

  • Späte Bindung: Auswahl einer Kombination aus Datendarstellung und Verhalten zur Laufzeit

  • Kapselung: Sicherstellen, dass die Daten konstruktionsbedingt gültig sind und später nicht ungültig werden

Das ist alles. Wie bei jeder Technologie ist es im Kern einfach eine Annehmlichkeit, aus der später viele Entwicklungen hervorgegangen sind. Sobald Sie die Grundlagen verstanden haben, folgt der Rest rechtzeitig.


0

Ich würde vorschlagen, BlueJ herunterzuladen, 20 Minuten damit zu spielen und sie dann 20 Minuten damit spielen zu lassen.

Die Art und Weise, wie Klassen, Schnittstellen und Vererbung visualisiert werden, ist so offensichtlich und intuitiv, dass Sie wirklich sofort verstehen, wenn Sie etwas implementieren - alles.

Es zeigt Ihnen sogar direkt den Unterschied zwischen einer Klasse und einem Objekt

Es wird keine tiefen Einblicke in OO-Designmuster geben, aber es wird einen fantastischen Überblick über die Konzepte geben.


0

Ich möchte meinen Beitrag als Erinnerung an die Unterscheidung zwischen Programmierparadigmen und Programmiersprachen, die diese Paradigmen implementieren, hinzufügen.

Meiner Meinung nach besteht der beste Weg, einem F77-Benutzer die Objektorientierung mit C ++ zu erklären, darin, schrittweise vorzugehen:

Führen Sie die Benutzerin zunächst in einer vertrauten Umgebung in das Konzept der Objektorientierung ein, indem Sie ihr zeigen, wie man objektähnliche Strukturen in Fortran 77 entwickelt. Schauen Sie sich beispielsweise Artikel wie B. Patton "Objektorientiertes Fortran 77 (Praktiker) an view) "SIGPLAN Fortran Forum 12, 2 (1993), S. 23-24, und Referenzen darin.

Stellen Sie dann eine Entsprechung zwischen diesen Strukturen und C ++ - Klassen und -Methoden her.

Besprechen Sie abschließend zusätzliche Funktionen, die C ++ zur Erleichterung der OO-Programmierung bereitstellen kann.


0

Als ich von meiner ersten Ausbildung in Pascal zum ersten Mal in eine objektorientierte Sprache migrierte, war das '.' Das Problem war auch für mich die größte Hürde. Ich habe Jahre gebraucht, um darüber hinwegzukommen.

Es ist eigentlich nicht intuitiv, wenn eine Variable zu einer anderen Variablen gehört, insbesondere wenn Sie es gewohnt sind, sie als Zeiger zu betrachten. Der Stolperstein für mich war:

  • Was bedeutet es für etwas, das im Grunde genommen ein Zeiger ist, einen anderen Zeiger darauf zu haben, der sich in eine andere Sache als den übergeordneten Zeiger auflöst?

Der Aha-Moment für mich war, als mir klar wurde, dass der Zeiger der obersten Ebene im Grunde nur ein Namespace war.

Ich würde vorschlagen, dass sie eine Menge Code schreibt, für den sie ihre Funktionen benennen muss, idealerweise ohne die Punktnotation zu verwenden. Lassen Sie sie dann versuchen, es mit Punktnotation neu zu schreiben.

Wenn Sie diese Übung machen, sollte sie über das anfängliche "Was für eine Hexerei ist das?" Hürde.


-2

Eine wichtige Erkenntnis, die mir zuvor bei der Erklärung geholfen hat, ist die Tatsache, dass Sie mehrere Instanzen einer Klasse haben können. Versuchen Sie das mit "Zeichnungen" oder "Formen" und "Kopien" zu erklären und sehen Sie, ob es irgendwohin führt.


Verstehe die Abstimmungen nicht wirklich. Diese Art zu erklären hat mir ein paar Mal geholfen. Ich sage nicht, dass es eine Silberkugel ist, aber es scheint, als würden die Leute daran hängen bleiben.
Alexander Torstling
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.