Wie bekomme ich endlich das Verständnis für die objektorientierte Programmierung?
Hallo,
Seit Jahren versuche ich nun schon, mir ein Verständnis dafür aufzubauen. Aber ich bin stets am scheitern. Vielleicht liegt es daran, dass ich zu früh aufgebe, ich weiß es nicht.
Eventuell kapiere ich wenigstens das Konzept des objektorientierten Programmierparadigmas: Es geht lediglich darum, dass man im Quelltext eine Struktur bekommt, dass man quasi einen Überblick auf den Quelltext hat. Das man unter anderem Codezeilen nicht mehrfach schreiben muss etc etc.
Selbst da bin ich mir nicht sicher, ob ich es tatsächlich verstanden habe. Ich lerne in der Programmiersprache Java und habe wie bereits erwähnt gewaltige Probleme, das Konzept der OOP bzw. die Syntax und die Verwendung dafür zu verstehen...
Wie kann ich mir anderweitig denn noch helfen?
Letztens hatte ich diesbezüglich eine Frage gestellt, könnt ihr euch ja anschauen, wenn ihr möchtet. Und mir haben auch welche geantwortet, aber ich habe überhaupt nichts verstanden. :/
MFG
5 Antworten
Es geht lediglich darum, dass man im Quelltext eine Struktur bekommt, (...)
Ja, das ist ein Ziel.
Einfacher ist es zu sagen, dass man versucht, wie in der realen Welt, alles mit Objekten zu beschreiben, die miteinander agieren. Das Problem, welches es zu lösen gilt (Beispiele folgen), wird als ein System abgebildet, welches sich durch diese Objekte beschreiben lässt.
Lamaninis Gleichnis mit dem Organsystem des Menschen ist dafür gut. Oder beziehe es auf Pacman:
- Es gibt Blöcke, die die Wand darstellen
- Es gibt Geister, die sich bewegen und angreifen können
- Es gibt Früchte, die sich aufsammeln lassen und eine bestimmte Punktzahl darstellen
- Es gibt Pacman, der sich bewegen und fressen kann
Natürlich gibt es hier noch mehr Spielelemente, aber ich möchte ja nur exemplarisch auf ein paar Eigenschaften eingehen.
Für jedes Spielobjekt bräuchtest du zunächst eine Klasse, damit du Instanzen / Objekte davon anlegen kannst. Es gibt also Klassen für Block, Ghost, Fruit und eine für Pacman. Jedes Objekt kann einen eigenen Zustand definieren. Früchte geben bspw. Extrapunkte und Geister können fressbar sein oder nicht. Ebenfalls haben die Spielemente ein eigenes Verhalten. Die Geister bewegen sich, Pacman kann sich bewegen. Wenn eine Geist mit einem Blockelement kollidiert, wählt er eine neue Richtung.
Wie kann ich mir anderweitig denn noch helfen?
Durch Übung.
Ich kann dir folgend ein paar Übungsaufgaben aufschreiben, die mir spontan einfallen (oder du suchst dir selbst welche via Google). Beschränke dich im ersten Schritt nur auf die Analyse: Welche Objekte gibt es, welche Klassen werden demzufolge benötigt? Was behalten die Klassen (Methodendefinitionen, Attribute)? Die Implementation in Java erfolgt erst danach, sobald das System klar ist. Das macht es dir auch einfacher, denn so musst du die Struktur im Grunde nur noch in der richtigen Sprache formulieren.
Konkret helfen UML-Diagramme bei Schritt 1 (Objekte finden: Objektdiagramm) und Schritt 2 (Klassen beschreiben: Klassendiagramm). Sofern du nicht auf Blättern oder irgendeinem Zeichenprogramm wie Paint malen möchtest, kannst du dir ein Programm wie StarUML installieren. Einfacher aufgebaut ist ansonsten noch NClass. Das ist zwar nur für Klassendiagramme gedacht, aber du kannst anfangs ja auch einfach die Boxen zuklappen und mit Objektnamen beschriften. Ignoriere zudem Angaben, mit denen du anfangs nichts anfangen kannst (private, static, final, u.ä.). Dem kann man sich später nach und nach widmen. In Wikipedia findest du Artikel zu Klassen- und Objektdiagramm, die auf die wesentlichen Elemente eingehen.
Noch etwas zu den Aufgaben:
- Du kannst sie beliebig erweitern, bei der Beschreibung hast du meist viel Freiheit (ich habe sie bewusst freier formuliert). Wenn du es implementierst, reicht es für den Anfang, die Methoden leer zu lassen oder besser, mit println in ihnen Ausgaben vorzunehmen (so kannst du es später besser testen). Dann steht in einer Methode run bspw. Läuft.
- In deren Zusammenhang solltest du dich etwas mit Kapselung auseinandersetzen, Vererbung und Polymorphie sind auch ab und an gefragt. Die beiden letzten Übungen dürften die Schwierigsten sein, insgesamt meine ich allerdings, dass der Schwierigkeitsgrad hier bei einfach liegt.
- Nimm dir für alles, was du zeichnen möchtest (Minispiele, etc.), Processing zu Hilfe. Es ist meines Erachtens die einfachste Möglichkeit, in Java zu zeichnen. Eine Referenz über alle möglichen Methoden findest du hier. Du kannst auch direkt die Processing IDE verwenden und diesen Projekten java-Dateien zufügen.
- Alle anderen Programme lassen sich am leichtesten als Konsolenanwendungen umsetzen.
Aufgaben:
- Beschreibe und implementiere einen Taschenrechner. Der beherrscht die Grundrechenarten und nimmt das vorherige Ergebnis als Grundlage für weitere Rechnungen.
- Beschreibe eine Musikbibliothek (als Orientierung kannst du ja einmal auf Discogs schauen).
- Beschreibe einen Bankautomat.
- Beschreibe eine Bank. Es gibt einen Safe, auf den nur bestimmte Personen Zugriff haben. Geld kann getauscht (Euro, Dollar) und eingezahlt werden. Es gibt Kunden, die Geld abziehen können, sofern sie nicht pleite sind und die Kredite aufnehmen können, sofern kreditwürdig. Die Bank bedient nur Kunden, die sie kennt, kann aber neue Kunden erfassen oder alte Kunden können sich wieder eine neue Bank suchen. Vielleicht gibt es auch Bankräuber, die die Bank plündern.
- Beschreibe drei verschiedene Fahrzeugtypen, die nur von bestimmten Personen gefahren werden können (der Bus z.B. nur von Busfahrern).
- Beschreibe einen Zoo. Es gibt fünf verschiedene Tierarten mit individuellen Verhaltensweisen (z.B. Affen die klettern, Elefanten die tröten, etc.), einen Pfleger und Besucher.
- Erweitere 1). Jede Tierart soll fressen können. Der Pfleger soll jedes beliebige Tier füttern können. Wenn er ein Tier füttert, frisst es.
- Beschreibe das Nutzersystem bei GuteFrage. Was kann ein Nutzer, mit welchen Objekten steht er in einer Beziehung?
- Beschreibe und implementiere eine Liste. Listen sind bildlich wie Eisenketten aufgebaut. Du kannst Glieder einfügen, entfernen, anhängen (vorn oder hinten), die Länge ermitteln oder alle Elemente (bzw. deren Werte) ausgeben lassen.
- Beschreibe das Spiel Pong. Du kannst es auch gern implementieren.
- Beschreibe das Spiel Pacman. Du kannst es auch gern implementieren.
- Obstkorb-Aufgabe
- Implementiere Space Invaders.
- Implementiere Tetris.
- Beschreibe ein Kartenspiel (z.B. Mau-Mau). Du kannst es auch gern implementieren.
- Gegeben ist ein Spielfeld (Marktplatz), auf dem sich Spielfiguren bewegen und Händler platziert sind. Jede Spielfigur besitzt eine Einkaufsliste mit individuell zusammengestellten Waren, die gekauft werden müssen. Jeder Händler hat sich auf höchstens zwei Waren festgelegt. Die Spielfiguren sollen nun so lange über das Spielfeld wuseln, bis sie ihre Liste abgearbeitet haben. Dann bleiben sie stehen.
Hier findest du noch weitere Übungsaufgaben: https://www.gutefrage.net/frage/suche-aufgaben-im-bereich-objektorientierung. Die sind zwar auf C# gemünzt, lassen sich aber genauso in Java umsetzen. Sie fokussieren sich mehr auf den Einsatz von Design Pattern, also Strukturmodelle, die dein Programm flexibler machen sollen. Diese Aufgaben sind dementsprechend schwieriger.
- Wenn du dort Aufgabe 25 lösen möchtest, schau dir die Java Socket API oder RMI an.
- Sollte es darum gehen, Formulare grafisch anzulegen (ComboBoxen, Textfelder, u.ä.), kannst du für den Anfang Swing verwenden. Nutze, um Swing zu lernen, die Oracle Tutorials oder Java ist auch eine Insel und verwende von Anfang an Layout Manager. Swing baut fest auf der OOP und du findest verschiedene Design Pattern in diesem Toolkit (z.B. Command, Composite, ...). Das MVC lässt sich gut damit verwenden. Alternativ zu Swing gibt es das modernere OpenJFX (JavaFX).
Solltest du zu den Aufgaben Fragen haben, frag via Kommentar.
Und mir haben auch welche geantwortet, aber ich habe überhaupt nichts verstanden. :/
Du hättest nachhaken können. Dafür gibt es die Kommentarfunktion.
Im Wesentlichen geht das darum, dass man eine Datenstruktur und den Code, der darauf Zugriff hat, zusammenfasst. Die Datenstruktur ist dadurch nach außen geschützt, so dass sie in sich konsistent bleibt.
Du könntest stattdessen auch einen Satz von Funktionen schreiben, die alle auf eine bestimmte Datenstruktur zugreifen. Jeder Funktion wird dabei ein Pointer auf die Struktur übergeben. Bei der OOP passiert intern auch nichts anderes, nur, dass es in der Sprachsyntax integriert ist.
Also ein rectangle.clear() ist im Prinzip dasselbe wie ClearRectangle(rectangle).
Natürlich gehören noch weiter Merkmale zur OOP, aber das ist im Grunde das Wichtigste.
Beispiel: Du hast ein Objekt mit dem Feld Postleitzahl vom Typ int. Ohne OOP könntest du da jeden Wert reinschreiben. Mit OOP gibt es eine Eigenschaft, die beim Setzen des Feldes den Wertebereich prüft und ggf eine Exception auslöst, wenn der Wertebereich nicht eingehalten wird.
Soweit ich mich erinnere, gibt's in der Java-Welt mit die besten Bücher, wenn's um die OOP geht.
Schaust Du dir irgendwelche angeblich super guten Tutorials an? Spoiler: Die sind nie gut.
Es geht lediglich darum, dass man im Quelltext eine Struktur bekommt, dass man quasi einen Überblick auf den Quelltext hat.
Ich würde es etwas anders beschreiben:
Es geht darum, ein Stück der realen Welt in Form von Daten abzubilden, da man es so als Entwickler leichter hat. Die Struktur und reduzierte Wiederholungen kommen dann noch dazu.
Der wichtigste und einfachste Part dürfte die Kapselung sein. Früher bestand ein Programm aus einer elendig langen Liste von Befehlen und in dieser Liste ist man immer hin und her gesprungen, um auf Situationen reagieren zu können.
Das ist grausig, also hat man sich überlegt: Lass uns doch Teile der Befehle zusammenfassen, sodass wie sie dann immer wieder ausführen können, ohne sie jedes Mal wiederholen zu müssen.
Das war die Kapselung, man konnte Funktionen (von Programmierern meist "Methode" genannt) schreiben und immer wieder aufrufen. Im Grunde ist alles danach nur eine weiter gedachte Kapselung, man ist auf ein Problem mit dem vorherigen Konzept gestoßen und hat eine Lösung gesucht.
Mit der Kapselung war es nämlich noch lange nicht getan, es gab ein Problem:
Du als Mensch denkst zwar mehr oder weniger abstrakt, versuchst aber Dinge zusammenzufassen. Für dich bleibt ein Auto immer ein Auto und nicht die Summe seiner Teile und Funktionen. Die Tür ist zwar eine Tür, aber sie gehört zum Auto.
Für einen PC ist das aber genau umgekehrt, der denkt gar nicht und kennt nur die kleinen Teile und Funktionen, vom Auto weiß der nichts. Und weil das so ist, musste man bisher als Entwickler auch so denken, wenn Du ein Auto rudimentär simulieren wolltest, musstest Du in Einzelteilen denken und hattest nur die Kapselung als Hilfe.
Mit der Objektorientierung kannst Du die Einzelteile und Funktionen zusammenfassen. Du baust dir eine Klasse und beschreibst darin, was das Auto ausmacht. Damit hast Du noch kein Objekt (dein Auto), Du hast nur die Beschreibung des Objektes. Und weil der Compiler hinter der Sprache ein verdammt raffiniertes Teil ist, versteht der PC diese Beschreibung und kann dir damit ein fertiges Objekt erstellen, ohne dass Du wirklich die Einzelteile einzeln betrachten musst.
Du hast also ein Objekt und die Beschreibung dazu, doch wenn Du genauer darüber nachdenkst, wirst Du damit ziemlich schnell bei dem Problem angelangt sein, dass Du für alle möglichen Autos (und es gibt viele) deine eigene Beschreibung brauchst.
Keine sehr praktikable Lösung, oder?
Nun, Du könntest die Klasse so bauen, dass Du die Objekte einstellen kannst, das funktioniert auch nur so lange, wie keine neuen Eigenschaften und Funktionen hinzukommen, denn dann wird es knifflig.
Daher hat man sich überlegt, dass eine Klasse (Objekt-Beschreibung) die eigenen Eigenschaften und Funktionen an eine Andere vererben kann. Damit ist die Polymorphie geboren.
Soweit so gut. Du kannst jetzt eine Auto-Klasse bauen, ohne ständig alles doppelt und dreifach schreiben zu müssen. Du erbst einfach von einer Klasse und fügst zu dem vorhandenen Set an EIgenschaften und Funktionen Weitere hinzu.
Aber was ist, wenn ein Auto zwar die gleiche Funktion hat, diese Funktion aber anders arbeitet? Ein E-Auto ist auch ein Auto und es kann fahren, aber niemand würde auf die Idee kommen, dass es wie ein Verbrenner funktioniert.
Bei dem aktuellen Stand unserer Objektorientierung müsstest Du wieder eine neue Klasse schreiben, denn die Vorherige simuliert noch die Verbrennungsmotoren. Nochmal die ganzen Klassen und Funktionen schreiben? Nein Danke.
Deshalb hat man sich überlegt, dass die Funktionen nur nach außen gleich aussehen müssen, ob sie sich auch gleich verhalten, ist gar nicht so wichtig. Die Idee war also, dass das E-Auto die Motor-Funktionen vom Auto erbt, aber die interne Arbeitsweise verändern kann, ohne eine neue Klasse dafür erstellen zu müssen.
Damit hatte man nun die wichtigsten Konzepte der OOP.
Man kann beinahe alles halbwegs sinnvoll in eine Objekt-Struktur drücken, die wir als Mensch noch verstehen können und müssen dabei nicht alles doppelt und dreifach schreiben.
|
Soweit die OOP.
Daneben gibt's noch mehr Konzepte, wie z.B. Zugriffsmodifizierer, womit man Inhalte einer Klasse "verstecken" kann. Nur andere Mitglieder der Klasse können sie nutzen, so verhindert man ungewollt problematische Zugriffe von außerhalb der Klasse.
Oder es gibt Interfaces, die sozusagen eine halbe Klasse sind. Die sind tatsächlich nur eine Beschreibung, aber sie beschreiben nicht das Objekt, sondern die Klasse, wie die Klasse tatsächlich arbeitet, ist da noch gar nicht klar.
|
Das braucht aber auch Zeit.
Solche Konzepte sind nicht dafür gemacht, in einem kleinen Übungsprojekt sofort die Stärken ausspielen zu können, sie werden erst bei größeren und komplexeren Programmen relevant.
Das Verständnis der OOP ist also ein fließender Prozess.
Also ich stelle es mir immer wie meine Organe vor.
Anstatt das alles einfach nur irgendwie in meinem Körper zusammengekleistert ist, wo alles ein bisschen alles tut, gibt es klar abgetrennte Organe, die jeweils bestimmte Aufgaben erfüllen. Dabei gibt es bestimmte Grenzen, die nicht überschritten werden können. Das hat verschiedene Vorteile.
Dein Magen kann nicht dein Herz steuern, dein Gehirn kann nicht das Blut in deinem Körper zum stehen bringen. Und das, obwohl die Muskeln natürlich dein Herz stoppen könnten. Nur da haben einfach die anderen Organe keinen Zugriff drauf.
Kenn ich, hatte auch riesige Probleme damit. Lerne erstmal Python, welche eine Sprache ist, die auch ohne OOP funktioniert. Kere dann zurück und alles wird sich so ergeben.
Ja, aber ich brauche Java für eine Prüfung oder so.....
Falls du ihn nicht kennst: schaue The Morpheus Tutorials auf der Platform Youtube.
Dort findest du alles rund um IT. DeBukkit ist zwar um Längen nicht so gut wie Morpheus, bringt die Materie aber trotzdem an den Mann.
Wieso sollte sich mit Python alles ergeben, wenn er sich in dieser Sprache dann auch nicht mit der OOP befasst? 🤨 Nun noch mit einer anderen Sprache zu beginnen, die wiederum eine andere Syntax hat, bringt ihn doch eher nur von dem Pfad ab, auf dem er sich bereits befindet. Es verzögert und macht es auch nicht leichter.