2. Praxis der OOP mit C#

Größe: px
Ab Seite anzeigen:

Download "2. Praxis der OOP mit C#"

Transkript

1 2. Praxis der OOP mit C# A) Einleitung In diesem Kapitel 5.2 werden Sie Schritt für Schritt ein eigenes Spiel programmieren und dabei die wichtigsten Gedanken der OOP kennenlernen. Es wird vorausgesetzt, dass Sie Kapitel 2 "Einfache Programme mit C#" durchgearbeitet haben, oder dass Sie mit Schleifen, Verzweigungen und sonstigen grundlegenden Dingen in C# vertraut sind. Eine Vertiefung und Erweiterung Ihres Wissens erreichen Sie, wenn Sie nach diesem Kapitel noch Kapitel 5.3 bearbeiten. Dort wird an einem fertigen Spiel (AntMe!) aufgezeigt, wie selbst in komplexeren Programmen die OOP für Überschaubarkeit und Erweiterbarkeit sorgt. Die Idee zum Spiel in diesem Kapitel: Sie steuern jeweils mit zwei Fingern einer Hand die beiden Ameisen, die Sie von links in das Ziel rechts führen müssen. Käfer von oben und unten machen Ihnen das Leben schwer, denn wenn Ihre Ameisen zu nahe an die Käfer kommen, werden sie gefressen. Am Ende erhalten Sie eine Punktzahl, die von der Geschwindigkeit, mit der Sie das Problem gelöst haben und von der Anzahl der ins Ziel gebrachten Ameisen abhängt. Damit der Eindruck entsteht, dass die Ameisen und Käfer sich tatsächlich bewegen, werden immer abwechselnd zwei verschiedene Bilder der Insekten angezeigt. Obwohl der "rote Faden" in diesem Kapitel das "Ameisen-Käfer-Spiel" ist, werden wir für bestimmte Aufgaben auch andere Problemstellungen behandeln, um eine größere Allgemeinheit zu erreichen. 1

2 B) Erste Stufe: Klasse, Attribut, Eigenschaft, Methode Vorbereitung Holen Sie sich aus dem Tauschverzeichnis die Hülle des Programms KlassenObjekteInsekten00 : Hier wurde lediglich ein weißes Formular der festen Größe 1000 x 600 erzeugt und die später nötigen Bilder für die Ameisen und Käfer wurden bereits in die Resources.resx eingefügt. (So werden die Bilder dann auch in die ausführbare Datei eingefügt.). Außerdem wurde der Name für den namespace mit AmeisenKäferSpiel festgelegt. Fügen Sie nun noch aus der Toolbox links einen Timer und ein MenuStrip ein. Zum Schluss sorgen Sie für drei Menu-Einträge im MenuStrip: Mit Strg+Shift+S werden alle Änderungen gespeichert. Klasse Ameise Rechtsklick / Linksklick auf AmeisenKäferSpiel im Projektmappen-Explorer. Wie im nebenstehenden Bild dargestellt: Hinzufügen / Neues Element / Class 2

3 Wie im Theorie-Teil nachzulesen ist, ist eine Klasse (class) eine Schablone nach der dann später die Objekte hergestellt werden. In der ersten Stufe sollen nur zwei Ameisen erstellt werden, die man mit der Tastatur beschleunigend und bremsend auf die rechte Seite führen kann. Daher ist leicht einsehbar, dass eine Klasse für die Ameisen von Vorteil wäre. Klassen werden immer nach dem gleichen Muster erzeugt: class Ameise - Attribute - - Konstruktor - - Eigenschaften / Methoden - Hier ein erster Versuch für die Ameisen-Klasse: class Ameise private int x, y; //Koordinaten private float va; //Geschwindigkeit protected Graphics g; protected Bitmap[] bilder = new Bitmap[2]; ypos) public Ameise(Graphics g, Bitmap bildeins, Bitmap bildzwei, int xpos, int this.g = g; bilder[0] = bildeins; bilder[1] = bildzwei; x = 0; y = ypos; public int Xpos set x = value; get return x; public void Schneller(float dv) va += dv; if (va > 30) va = 30; public void Bremsen(float dv) va -= dv; if (va < 0) va = 0; Zunächst zum gelben und zum grauen Abschnitt: Die Klasse Ameise benötigt x- und y- Koordinaten, die aktuelle Geschwindigkeit va der Ameise und eine Oberfläche, auf die gezeichnet werden kann: Graphics g 3

4 Die zwei Bilder der Ameise, die abwechselnd gezeigt werden sollen, werden in einer "Bitmap-Liste", bestehend aus zwei Bitmaps, gespeichert. Sicher fallen einem später noch andere praktische Attribute ein. Sie werden dann einfach eingefügt. Es fällt auf, dass den Attributen verschiedene "Zugriffsmodifizierer" zugeordnet wurden, wie private und protected. Verwendet man private, so bedeutet dies, dass nur die Klasse selbst Zugriff auf das Attribut hat. (Bei protected kann auch eine eventuell abgeleitete oder übergeordnete Klasse zugreifen. Mit dem Thema werden wir uns aber erst im nächsten Schritt beschäftigen.) Weshalb soll nur die Klasse selbst auf ihre Attribute zugreifen können? Es wäre ja sehr bequem, wenn man zum Beispiel die Koordinaten x und y public deklarieren würde, denn dann könnte von überall im Projekt etwa per ameise.x = 5 ; die x-koordinate des Ameisenobjekts verändert werden. Aber genau das würde der Idee der OOP widersprechen: Alle Daten des Objekts sollen geheim gehalten (gekapselt) werden. Von außen sieht man nur ein Objekt ameise, mit dem man lediglich per vorgegebenen Eigenschaften und Methoden kommunizieren kann - sofern diese public deklariert sind. Das hat große Vorteile. Denn auf diese Weise bleiben die Daten des Objekts vor Überraschungen verschont, da man sich schon vorher überlegen muss, wer überhaupt das Recht bekommen soll, in die Struktur des Objekts einzugreifen und wie weit das Recht eventuell gehen soll. public int Xpos set x = value; get return x; Die Methode Xpos wird Eigenschaft genannt. Über sie kann die x-koordinate der Ameise ausgelesen und eingetragen werden. Beispiel: ameise.xpos = 5 ; Damit wird der Wert der x-koordinate auf 5 gesetzt. Der Unterschied zum oben dargestellten direkten Eintrag über eine public-variable, besteht vor allem darin, dass man über die Eigenschaft Xpos bestimmen kann, was von außen erlaubt ist. Man könnte beispielsweise die set-zeile weglassen und würde so erreichen, dass der Wert von außen überhaupt nicht gesetzt werden kann. Es wäre aber auch denkbar, dass man nur x-werte kleiner 1000 einsetzen lässt. Die Methoden Schneller(float dv) und Bremsen(float dv) sind kleine Unterprogramme, die einen Eingabe-Parameter dv erwarten und damit offensichtlich die Geschwindigkeit va verändern. Sie sind public und somit von überall im gleichen Projekt aufrufbar. Der Zusatz void (= Leere) besagt nur, dass die Methode keinen Rückgabewert liefert. Die "Intellisense" hilft sehr wirkungsvoll beim Schreiben des Codes: Wenn man beispielsweise (siehe unten) ameise. schreiben, dann werden nach dem Schreiben des Punktes die möglichen Ergänzungen, wie etwa die Eigenschaft Xpos oder die Methode Bremsen angezeigt: 4

5 Wenn man sich nicht mehr erinnert, welche Bedingungen die Methode Bremsen gefordert hat, dann zeigt ein Klick darauf alles Wissenswerte: (Man kann den beiden Bildern oben auch entnehmen, wie die Icons für Methoden und Eigenschaften aussehen.) Zum türkisfarbenen Abschnitt: Wenn ein Objekt erzeugt werden soll, benötigt man eine Art Methode, die das übernimmt. Man sie Konstruktor. Würde man keinen Konstruktor für Ameise schreiben, so käme ein (parameterloser) Standard-Konstruktor zum Einsatz. Er muss nicht eigens geschrieben werden, aber seine Funktion ist äußerst dürftig: Er initialisiert die Attribute bei der Erzeugung eines Ameisen-Objekts. Durch eine explizite Formulierung eines Konstruktors, wird der Standard-Konstruktor außer Kraft gesetzt. Sehen Sie selbst, was wir unserem Ameisen-Objekt alles mitgeben wollen: public Ameise(Graphics g, Bitmap bildeins, Bitmap bildzwei, int xpos, int ypos) Eine Zeichen-Oberfläche g, zwei Bilder und zwei Koordinaten. Eine Zeile in den nachfolgenden Zuweisungen muss genauer besehen werden: this.g = g; Hierbei bezeichnet this das neu zu erzeugende Objekt. Wenn der Name des Objekts ameise1 wäre, so wird damit festgelegt, dass die als Parameter übergebene Grafik g der neuen Ameise gehört. Mit ameise1.g. könnte man sie aufrufen. Setzt man an geeigneter Stelle der Klasse einen Haltepunkt (Debugging), dann kann man sich im "Überwachungsfenster" alle oben behandelten Begriffe und die zugehörigen Icons nochmals ansehen: 5

6 Zurück zu den Methoden und Eigenschaften der Klasse Ameise (grauer Abschnitt): Man sollte den Ameisen noch einige andere Fähigkeiten mitgeben. Wir ergänzen den Abschnitt durch folgende Zeilen: public void Schritt(Ameise ameise) // Schritt einer Ameise if (va == 0) return; x += Convert.ToInt32(va); //Verschieben der x-position aktuellesbild = (aktuellesbild + 1) % 2; // Bilder abgewechselnd zeigen public void AmeisenAktion(Ameise ameise) ameise.schritt(ameise); ameise.zeichnen(); // Ameise an neuer Position zeichnen public void Zeichnen() g.drawimage(bilder[aktuellesbild], x, y); public bool Angekommen set angekommen = value; get return angekommen; Aufgabe 1 Welche Abschnitte beschreiben eine Methode und welche Aufgaben haben diese Methoden? In wie fern unterscheidet sich die Eigenschaft Angekommen prinzipiell von der Eigenschaft Xpos? (Die vollständige Klasse Ameise ist im Anhang zu finden) Erstellen Sie mit UMLed ein Klassendiagramm von Ameise. (Lösung und Kommentare im Anhang!) Der mit UMLed erzeugte Java-Code der Klasse Ameise unterscheidet sich, wie Sie nach Bearbeitung von Aufgabe 1 gesehen haben, fast gar nicht vom C#-Code. Einziger Unterschied: Eigenschaft Xpos in C#: public int Xpos set x = value; get return x; Entsprechend die Setzte und Gib-Methode in Java: public void SetzeX(int px) 6

7 x = px public int GibX() return x Ein Beispiel: x-koordinate der Ameise auf 20 setzen: C# ameise.xpos = 20; Java ameise.setztex(20) Vorteil der Eigenschaften in C#: Man muss sich nur einen Methoden-Namen merken. Klasse Form1 Mit Rechtsklick auf das Formular und der Wahl "Code anzeigen" kann man den von C# selbst erstellen Teil der Klasse Form1 erkennen. Durch Program.cs wird dieser Code am Anfang gleich aufgerufen: Application.Run(new Form1()); Zunächst steht da herzlich wenig: namespace AmeisenKäferSpiel public partial class Form1 : Form public Form1() InitializeComponent(); Vor den Konstruktor von Form1, den wir im Anschluss überschreiben werden, müssen erst die Attribute für Form1 angebracht werden: List<Ameise> ameisenliste; //Die Ameisen private Graphics g; // Grafikobjekt, auf dem gezeichnet wird Der Konstruktor: public Form1() InitializeComponent(); initialisiereameisen(); Die Methode initialisiereameisen() legen wir durch diese Zeilen fest: private void initialisiereameisen() g = this.creategraphics(); ameisenliste = new List<Ameise>(); ameisenliste.add(new Ameise(g, Resources.ameise1a, Resources.ameise1b, 0, 260)); ameisenliste.add(new Ameise(g, Resources.ameise2a, Resources.ameise2b, 0, 410)); Wir hatten einen Timer timer1 integriert und legen nun fest, was bei jedem Tick- Ereignis (Voreinstellung 100 ms auf 50 ms stellen) passieren soll: 7

8 private void timer1_tick(object sender, EventArgs e) g.clear(color.white); foreach (Ameise ameise in ameisenliste) if (ameise.xpos <= 1000) //selbsterklärend... ameise.ameisenaktion(ameise); else ameise.angekommen = true; Aufgabe 2 Was bewirkt der folgende Code im Konstruktor? ameisenliste.add(new Ameise(g, Resources.ameise1a, Resources.ameise1b, 0, 260)); Kann die Höhe des Formulars von der Klasse Ameise aus geändert werden? Versuchen Sie nachzuvollziehen, welche Aktionen alle 50 ms durchgeführt werden. Was bewirkt die Zeile: ameise.ameisenaktion(ameise);? Technische Ergänzungen Unter dieser Rubrik wird Ihnen jeweils der Code vorgestellt, der das Programm voran bringt aber nicht notwendigerweise Ihr Verständnis für OOP erweitert. Die beiden Ameisen sollen auf Tastendruck reagieren. Wir programmieren hierzu das KeyDown-Ereignis des Formulars Form1: private void Form1_KeyDown(object sender, KeyEventArgs e) //Eigenschaft KeyPreview des Formulars auf true setzten! switch (e.keycode) case Keys.D: // Linke Hand : obere Ameise steuern ameisenliste[0].schneller(1.5f); // schneller: Taste D, langsamer: Taste A case Keys.A: ameisenliste[0].bremsen(1.5f); case Keys.L: // Rechte Hand : untere Ameise steuern ameisenliste[1].schneller(1.5f); // schneller: Taste L, langsamer: Taste J case Keys.J: ameisenliste[1].bremsen(1.5f); case Keys.R: 8

9 Application.Restart(); Wenn man die Eigenschaft KeyPreview von Form1 nicht auf true setzt, kann man die Tasten so oft drücken, wie man will, es wird nichts passieren, da die Tasten nicht "den Fokus haben". Vergleichbar dem Problem, wenn man online ein Formular ausfüllen will und es passiert nichts. Das Eingabefenster kurz anklicken und die Sache funktioniert, da das Fenster danach den Fokus hat. Die Menu-Einträge neu starten, beenden und Info müssen auch noch mit den passenden Click- Ereignissen versorgt werden: private void beendentoolstripmenuitem1_click(object sender, EventArgs e) Close(); private void neustartentoolstripmenuitem_click(object sender, EventArgs e) Application.Restart(); private void infotoolstripmenuitem_click(object sender, EventArgs e) MessageBox.Show("Steuerung der Ameisen mit den Tasten A/D bzw. J/L" + "\r\n Neustarten mit der Taste R"); Der gesamte Code für Form1 ist nochmals im Anhang aufgeführt. Aufgabe 3 Erstellen und testen Sie das Programm. Ein Spiel braucht eine Bewertung, um vergleichen zu können, wer das gegebene Problem besser löst. Wir werden als Kriterium die Zeit, die der Spieler benötigt, die Ameisen sicher auf die andere Seite zu bringen, messen. Jede Ameise bekommt also ihre Stoppuhr mit. wie viel Zeit bereits vorüber ist, soll für jede Ameise angezeigt 9

10 werden: (Anmerkung: Die benötigten Zeiten werden aufaddiert, jeweils mit 10 multipliziert und von der Maximal-Punktzahl 1000 abgezogen. Kommt eine Ameise nicht an, so werden von vornherein 500 Punkte abgezogen (entspricht 50 Sekunden für eine Ameise, die ankommt). Natürlich ist das nur ein erster Vorschlag, den Sie nach Belieben umändern können.) Hier ein Vorschlag, wie die Zeitmessung und Anzeige realisiert werden kann (es werden nur die neue hinzugekommenen Zeilen angegeben): Klasse Ameise: private string zeit = "0"; private string lebenszeit; Font schrift = new Font("Arial", 14); //Ausgabeschrift Der Konstruktor wird nur geringfügig verändert. Wir geben den Ameisen die Lebenszeit als String mit: public Ameise(Graphics g, Bitmap bildeins, Bitmap bildzwei, int xpos, int ypos, string lz) this.g = g; bilder[0] = bildeins; bilder[1] = bildzwei; x = xpos; y = ypos; lebenszeit = lz; Bei den Methoden muss Schritt erweitert und ZeitAusgeben hinzugefügt werden: public void Schritt(Ameise ameise) //Schritt einer Ameise if (va == 0) //Ameise steht 10

11 ZeitAusgeben(ameise,zeit); return; ZeitAusgeben(ameise,zeit); x += Convert.ToInt32(va); //Verschieben der x-position aktuellesbild = (aktuellesbild + 1) % 2; //Bilder abgewechselnd zeigen private void ZeitAusgeben(Ameise ameise, String zeit) zeit = (DateTime.Now - Form1.form1.StartZeit).TotalSeconds.ToString("0.0"); ameise.lebenszeit = zeit; g.drawstring(string.format(zeit + " s"), schrift, Brushes.Black, new PointF(Form1.form1.Breite - 80, y + 30)); Klasse Form1: public static Form1 form1; //Ohne Objekt keine Methoden... private DateTime startzeit; form1 = this; startzeit = DateTime.Now; public DateTime StartZeit get return startzeit; Stecken in diesem Code technische Details, die mit OOP nichts zu tun haben? Dass die Antwort ein klares Nein ist, lernen Sie bei der Bearbeitung der folgenden Aufgabe: Aufgabe 4 Nachfolgende Code-Ausschnitte stammen von der Ergänzung der Klasse Ameise und der Klasse Form1. Interpretieren Sie deren Bedeutung unter Berücksichtigung objektorientierter Aspekte: Convert.ToInt32(va) DateTime.Now Form1.form1.StartZeit ameise.lebenszeit = zeit; new PointF(Form1.form1.Breite - 80, y + 30) Aufgabe 5 Hier verlassen wir für kurze Zeit unser Projekt und versuchen die ersten Erkenntnisse der OOP auf ein eher rechnerisches Problem anzuwenden: Die Bruchrechnung. Über vier 11

12 Textfelder werden die Zähler und Nenner der Brüche eingegeben. Über die Click- Ereignisse der drei Buttons wird das jeweilige (gekürzte) Ergebnis der Rechnung ermittelt und ausgeben. Im Tauschverzeichnis finden Sie eine unfertige Version, bei der die Klasse Bruch noch ergänzt werden muss. (Ordner: BruchUnvollständig) Schauen Sie sich den Code von Form1 an und ergänzen Sie den Code von Bruch: Testen Sie das Programm! using System; namespace Bruch class Bruch private int zaehler, nenner; private int hv, zaehler1, nenner1; //Hilfsvariable public Bruch(int z, int n) //Konstruktor public int Zaehler //Eigenschaft public int Nenner //Eigenschaft public void addierenmit(bruch bruch) //Beispiel zaehler = zaehler * bruch.nenner + bruch.zaehler * nenner; nenner = nenner * bruch.nenner; kuerzen(); public void multiplizierenmit(bruch bruch) //Methode public void dividierendurch(bruch bruch) //Methode public void kuerzen() zaehler1 = Math.Abs(Zaehler); nenner1 = Math.Abs(Nenner); if (zaehler1 < nenner1) hv = zaehler1; zaehler1 = nenner1; nenner1 = hv; while (nenner1 > 0) hv = zaehler1 % nenner1; zaehler1 = nenner1; nenner1 = hv; hv = zaehler1; zaehler = zaehler / hv; nenner = nenner / hv; (Lösung im Anhang) 12

13 C) Zweite Stufe: Vererbung, Polymorphie, abstrake Klasse Bisher lassen sich lediglich zwei Ameisen von links nach rechts bewegen. Dabei ist es möglich, die Ameisen zu beschleunigen bzw. sie abzubremsen und zum Stehen zu bringen. Diese Aktionen haben nur Sinn, wenn den Ameisen unterwegs eine Gefahr lauert. In der nächsten Stufe werden wir das Spiel so erweitern, dass zunächst zwei Käfer mit verschiedenen Geschwindigkeiten von oben nach unten laufen. Kommen ihnen die Ameisen zu nahe, so werden sie gefressen. Klar, dass die Ameisen jetzt nur bei geschickter Steuerung ans Ziel kommen. Wenn die letzte Ameise angekommen oder gefressen ist, soll die erreichte Punktezahl ausgegeben werden. Nun liegt es zunächst nahe, dass man einfach eine neue Klasse Käfer erstellt und die Klasse Ameise beibehält. Viel geschickter wäre es allerdings, wenn man für eventuell weiter hinzukommende Akteure eine Klasse Insekt erzeugt. Denn es gibt mit Sicherheit Attribute, Eigenschaften und Methoden, die allen aktuellen und zukünftigen Insekten gemeinsam sind. Eine Klasse Käfer und eine Klasse Ameise erbt dann von der übergeordneten Klasse Insekt. Die Methode Laufen kommt in beiden Klassen vor, bewirkt aber nicht unbedingt das Gleiche. Man spricht in diesem Fall von Polymorphie. Ein Tier namens Insekt gibt es nicht. Daher wird die Klasse Insekt abstact definiert. Das bedeutet, dass man von dieser Klasse sinnvollerweise kein Objekt instanziieren kann. Methoden und Eigenschaften müssen auch in dieser Klasse nicht ausformuliert werden, denn in den Unterklassen bewirken sie gegebenenfalls ganz verschiedene Dinge. Mit UML sieht der Grobentwurf so aus: 13

14 Die Klasse Insekt ist schon vollständig, in den Unterklassen sind nur die Konstruktoren festgelegt. (Bedenken Sie, dass mit UMLed keine Eigenschaften festgelegt werden können. So muss es hier ein GibX() und ein SetzeX() für einen Lese- bzw Schreibzugriff auf die Koordinat x zu erreichen. ) Aufgabe 6 Laden Sie mit UMLed die Datei Insekt.urd (Bild oben). Schauen Sie sich die Attribute und die Methoden der Klasse Insekt an und überlegen Sie, weshalb sie hier in der Oberklasse formuliert wurden. Welche abstrakten Methoden finden Sie? Weshalb sind sie abstact? Welche Attribute und Methoden sollten nur in den Unterklassen vorkommen? Klasse Insekt abstract class Insekt protected int x, y; protected float va; protected bool lebt; protected string lebenszeit; protected Graphics g; protected Bitmap[] bilder = new Bitmap[2]; protected int w; protected int h; public Insekt(Graphics g, Bitmap bildeins, Bitmap bildzwei, int xpos, int ypos, string lz) this.g = g; bilder[0] = bildeins; bilder[1] = bildzwei; x = xpos; y = ypos; lebenszeit = lz; lebt = true; public int Xpos set x = value; get return x; public int Ypos set y = value; get return y; public float Geschwindigkeit get return va; 14

15 public bool Lebt get return lebt; public bool Berührt(Insekt k) if (x > k.xpos + k.w) return false; if (y > k.ypos + k.h) return false; if (x + w < k.xpos) return false; if (y + h < k.ypos) return false; return true; public string Lebenszeit set lebenszeit = value; get return lebenszeit; public virtual void Bremsen(float dv) va -= dv; if (va < 0) va = 0; public virtual void Schneller(float dv) va += dv; public virtual void Laufen(float dv) va = dv; public int W set w = value; get return w; public int H set h = value; get return h; public abstract void Zeichnen(); public abstract void Schritt(Insekt insekt); public abstract void AufAnfangspositionSetzen(int a); Zu den Attributen: Neu sind das boolsche Attribut lebt, und die integer-größen w und h. Letztere stehen für die Breite und Höhe des Insektenbildes. Beachten Sie: Nicht immer will man ein in der Oberklasse definiertes Attribut oder eine dort definierte Methode in allen Unterklassen sofort verwenden. Selbst wenn man im Augenblick keine Verwendung für z. B. w und h bei den Ameisen im Auge 15

16 hat, so lässt man sich durch die Definition in der Oberklasse die Möglichkeit offen, später eventuell doch noch darauf zurückgreifen zu können. Zum Konstruktor: Auch hier wurde dem Insekt der String lz (Lebenszeit) mitgegeben, obwohl wir in der Unterklasse Käfer zunächst keine Verwendung dafür haben. In einer späteren Entwicklung des Spiels wäre aber eine Einbeziehung der Lebenszeit der Käfer denkbar, indem man die zunächst feste Größe erhöht, wenn eine Ameise verspeist wurde. Zu den Eigenschaften und Methoden: Die letzten drei Methoden Zeichnen(), Schritt(Insekt insekt) und AufAnfangspositionSetzen() sind abstract. Sie werden daher hier nicht ausformuliert und bedeuten in den jeweiligen Klassen Verschiedenes (Polymorphie). Die Methode Berührt(Insekt k) muss genauer betrachtet werden. Inhaltlich ist klar, worum es geht: Berührt ein Insekt a ein anderes Insekt k? Wir werden damit testen, ob eine Ameise einen Käfer berührt und somit gefressen wird: ameise.berührt(käfer) (Aber natürlich kann jedes Insekt diese Methode aufrufen, um das Berühren mit jedem beliebigen Insekt zu testen.) Ein Bild soll klar machen, wie es zum obigen Code kommt: Die roten Punkte an den Rechtecken sind die C#-Koordinaten der Bilder der Insekten. Der Ursprung des Koordinatensystems ist links oben. Y-Werte werden von oben nach unten abgetragen. Grün steht hier für einen Käfer (die sich vertikal bewegen), hellblau steht für die vier Grenzsituationen einer Ameise, die gerade 16

17 eben den Käfer noch berührt. k.h und k.w sind hier also die Bildhöhe und die Bildweite des Käferbildes (ohne Beine - wird sonst zu schwer!). Aufgabe 7 Zeigen Sie Hilfe der obigen Skizze, dass der Code für Berührt(Insekt insekt) die richtige Antwort liefert: public bool Berührt(Insekt k) if (x > k.xpos + k.w) return false; if (y > k.ypos + k.h) return false; if (x + w < k.xpos) return false; if (y + h < k.ypos) return false; return true; Klasse Käfer class Käfer : Insekt //d.h. Käfer ist ein Insekt private int aktuellesbild; public Käfer(Graphics g, Bitmap bildeins, Bitmap bildzwei, int xpos, int ypos, string lebenszeit) : base(g, bildeins, bildzwei, xpos, ypos, lebenszeit) this.w = 74; //Eigentlich je 20 mehr. this.h = 100;//Kollision mit Ameisen soll nur gelten, wenn Ameisen den Käferkörper (Beine zählen nicht) berühren. public void KäferAktion(Käfer käfer) käfer.schritt(käfer); if (käfer.ypos > Form1.form1.Höhe) //Rand erreicht käfer.aufanfangspositionsetzen(0); käfer.zeichnen(); // Käfer an neuer Position zeichnen public override void Laufen(float dv) //Käfer nicht schneller als 14 if (dv < 15) base.laufen(dv); else base.laufen(14); public override void Schritt(Insekt insekt) y += Convert.ToInt32(va); //Verschieben der y-position aktuellesbild = (aktuellesbild + 1) % 2; //Bilder werden so abgewechselnd gezeigt public override void AufAnfangspositionSetzen(int a) 17

18 y = a; public override void Zeichnen() g.drawimage(bilder[aktuellesbild], x, y); Zu den Attributen: int aktuellesbild ist das einzige neue Attribut. Weil es private definiert wurde, steht es ausschließlich der Käfer-Klasse zur Verfügung. Aber natürlich kann Käfer auch alle Attribute aus Insekt, wie zum Beispiel int x und int y benutzen. Sie wurden ja dort protected definiert, stehen damit den abgeleiteten Klassen ebenfalls zur Verfügung. Zum Konstruktor: Achten Sie hier besonders auf :base(g, bildeins, bildzwei, xpos, ypos, lebenszeit) Hier wird erwartungsgemäß festgelegt, welche Parameter des Konstruktors von der Oberklasse Insekt geerbt werden. (Beachten Sie: Ein private string Attribut lz, das mit dem Parameter lebenszeit initialisiert werden könnte, wurde nur deshalb nicht formuliert, weil wir im Moment noch keine Verwendung dafür haben.) Zu den Eigenschaften und Methoden: Die Methode Laufen(float dv) wurde in der Klasse Insekt virtual angelegt. Das bedeutet, dass sie in allen abgeleiteten Klasse überschrieben werden kann aber nicht notwendigerweise überschrieben werden muss. Hat man sich fürs Überschreiben entschieden, so muss der Methode der Bezeichner override vorangestellt werden. Will man, wie hier, teilweise die Definition aus der Oberklasse übernehmen, so setzt man base vor den Namen der Methode: base.laufen(dv). Ändert man überhaupt nichts, kann man sich die Mühe sparen und die gesamte Methode einfach weglassen. Ähnliche Festlegungen gelten für die abstrakten Methoden der Oberklasse. Allerdings kann hier in der abgeleiteten Klasse nichts übernommen werden, weil ja auch nichts festgelegt wurde! Schritt(Insekt insekt) zum Beispiel muss daher komplett ausformuliert werden, auch wenn man gar nicht die Absicht hätte, in der abgeleiteten Klasse auf die Methode zugreifen. Aufgabe 8 Schreiben Sie den Code für die Klasse Ameise. Zwei Vorgaben sollen Ihnen dabei helfen: Wie wurde Ameise in Stufe 1 definiert und welche Teile sind nun in die Oberklasse ausgelagert worden. (Lösung im Anhang!) Klasse Form1 Die Attribute: List<Ameise> ameisenliste; //Die Ameisen 18

19 List<Käfer> käferliste; //Die Käfer private Graphics g; // Grafikobjekt, auf dem gezeichnet wird public static Form1 form1; private DateTime startzeit; private bool spielbeendet = false; private int ym; // Höhe des Formulars Font schrift = new Font("Arial", 24); Die neuen Attribute wurden oben durch größere Fett-Schrift hervorgehoben. Wenn Käfer ins Spiel kommen sollen, benötigt man eine käferliste. Über spielbeendet wird kontrolliert, ob beide Ameisen angekommen oder gefressen wurden. Dann wird mit dem Font Arial das Punkte-Ergebnis mit einer passenden Methode ausgegeben. Die Höhe des Formulars ym dient als Kontrollgröße, ob die Käfer unten angekommen sind. Das Ziel ist, sie dann wieder von oben weiterlaufen zu lassen. Der Konstruktor: public Form1() InitializeComponent(); form1 = this; ym = this.size.height; initialisiereinsekten(); startzeit = DateTime.Now; Auch hier sind die neuen Zeilen durch größere Fett-Schrift hervorgehoben. Weil ja sowohl Ameisen als auch Insekten initialisiert werden sollen, heißt die Methode jetzt entsprechend. Die Eigenschaften und Methoden: private void initialisiereinsekten() g = this.creategraphics(); ameisenliste = new List<Ameise>(); käferliste = new List<Käfer>(); ameisenliste.add(new Ameise(g, Resources.ameise1a, Resources.ameise1b, 0, 260,"0.0")); ameisenliste.add(new Ameise(g, Resources.ameise2a, Resources.ameise2b, 0, 410,"0.0")); käferliste.add(new Käfer(g, Resources.käfera, Resources.käferb, 200, 10, "0.0")); käferliste.add(new Käfer(g, Resources.käfera, Resources.käferb, 600, 10, "0.0")); public int Höhe //Eigenschaft nur lesen get return ym; private bool GefressenVonKäfer(Ameise ameise) bool gefressen = false; foreach (Käfer käfer in käferliste) if (ameise.berührt(käfer)) gefressen = true; return gefressen; private void timer1_tick(object sender, EventArgs e) 19

20 g.clear(color.white); int anzahlaktiverameisen = 0; foreach (Ameise ameise in ameisenliste) if (GefressenVonKäfer(ameise)) //gezeichnet wird nur, wenn Ameise nicht vom Käfer gefressen wird ameise.stirbt(); ameise.lebenszeit = "50"; //Nur für die Punktzahl: Strafe -500 Punkte... if (ameise.xpos <= 1000 && ameise.lebt) //rechter Rand noch nicht erreicht ameise.ameisenaktion(ameise); anzahlaktiverameisen++; if (anzahlaktiverameisen == 0) spielbeendet = true; if (!spielbeendet)//käfer nur zeichnen, wenn mindest. eine Ameise lebt und noch nicht angekommen ist for (int i = 0; i < 2; i++) käferliste[i].laufen(5 + 3*i);//Zweite Ameise schneller käferliste[i].käferaktion(käferliste[i]); if (spielbeendet) //Ameisen sind entweder tod oder angekommen PunkteAngeben(); private void PunkteAngeben() double lebenszeit1 = Convert.ToDouble(ameisenListe[0].Lebenszeit); double lebenszeit2 = Convert.ToDouble(ameisenListe[1].Lebenszeit); double punkte = * lebenszeit1-10 * lebenszeit2; if (punkte <= 0) punkte = 0; g.drawstring(string.format(convert.tostring(punkte) + " Punkte"), schrift, Brushes.Black, new PointF(400, 300)); Es sind nur die neuen und veränderten Methoden und Eigenschaften aufgeführt! Aufgabe 9 Welche Aktionen werden bei jedem Tick-Ereignis durchgeführt. Welche Zeilen dürfen nun im Konstruktor von Ameise gelöscht werden? Erstellen Sie das gesamte Programm und testen sie es. Welche Verbesserungen schlagen Sie vor? (Ergebnis im Tauschverzeichnis: KlassenObjekteInsekten03 ) 20

21 D) Dritte Stufe: Überladen, überschreiben, Ergänzungen In der dritten Stufe werden die OOP-Begriffe überladen und überschreiben an einem Beispiel erläutert. Außerdem soll unser Programm einige Veränderungen erfahren: Weitere zwei Käfer starten von unten. Die Geschwindigkeit jedes Käfers (wird innerhalb eines bestimmten Intervalls) durch Zufall bestimmt - sie sind also in der Regel nicht gleich (untereinander und in jedem Spiel). Der Spieler hat die Möglichkeit, das Spiel auf leicht, mittel oder schwer zu spielen. Erreicht wird dies durch größere Bandbreite der Käfergeschwindigkeit. Sicher ist es für einen Anfänger nicht leicht, die beiden ähnlich klingenden Methoden Varianten auseinanderzuhalten. Wie man Methoden überschreibt, haben Sie weiter oben schon gelernt. Entscheidend ist hier, dass die überschriebenen Methoden alle die gleiche Bezeichnung haben. Das gilt auch bei überladenen Methoden. Dennoch sind beide grundverschieden: Überschreiben von Methoden: Man kann Methoden nur innerhalb einer Vererbungshierarchie überschreiben. Die Oberklasse besitzt zum Beispiel eine virtual definierte Methode. In der Unterklasse kann diese dann mit override überschrieben werden. Schauen Sie sich dazu die Methode Schneller in Insekten und in der Unterklasse Ameise an. Die Bezeichnung ist unverändert aber der Methodenkörper hat sich geändert. Überladen von Methoden: In einer Klasse existieren zwei oder mehrere Methoden gleichen Namens, die sich aber in den Datentypen und/oder der Reihenfolge der Parameter unterscheiden. Die C#-Methode Convert.ToDouble() beispielsweise besitzt laut Intellisens 17 Überladungen: K a u Kaum zu glauben aber wahr: Man kann dieser Methode 17 verschiedene Parameter übergeben. Es ist ja dennoch sinnvoll, dass alle diese Methoden gleich bezeichnet werden, denn sie konvertieren den Parameter in eine double-variable. Zum ersten Ziel: Es sollen zwei weitere Käfer von unten nach oben starten. Das bedeutet, dass man praktischerweise den Objekten die Information mitgeben sollte, in welche Richtung sie zu laufen haben. Die Ameisen brauchen die Information aber nicht, denn sie laufen immer von links nach rechts. Ein Konstruktor ist eine spezielle Methode mit der Objekte erzeugt werden können. Daher kann man den Konstruktor auch überladen. Und genau das werden wir nun mit dem Konstruktor Insekt tun. 21

22 Folgender Code wird in der Klasse Insekt hinzugefügt: //überladender Konstruktor public Insekt(Graphics g, Bitmap bildeins, Bitmap bildzwei, int xpos, int ypos, string lz, Richtung richtung) this.g = g; bilder[0] = bildeins; bilder[1] = bildzwei; x = xpos; y = ypos; lebenszeit = lz; lebt = true; this.richtung = richtung; Damit die gleiche Zugriffs-Bedingungen herrschen, definieren wir eine Aufzählung (enum) namens Richtung noch oberhalb der Insekten-Klasse (im namespace): enum Richtung hoch, runter ; Und bei den Attributen wird ergänzt: protected Richtung richtung; Die Ameisen-Objekte werden nach wie vor durch den Konstruktor Ameise erzeugt, welcher wiederum vom dem Konstruktor Insekt abgeleitet ist. Und zwar von der Variante, der der Parameter richtung fehlt. Klingt kompliziert, ist aber im Grunde ganz einfach: Wir haben für beide Konstruktoren (gleichen Namens: Insekt) Verwendung. Den einen benötigen wir für die Ameisen, den anderen für die Käfer. Wäre unsere Insektenwelt größer, könnte man sich leicht vorstellen, dass noch weitere Überladungen hinzukämen. Damit sich der Aufwand lohnt, müsste dann aber jede Überladung für mehrere Insekten zuständig sein. Die Änderungen in der Klasse Käfer: int ym = Form1.form1.Höhe; //brauchen wir jetzt für die Käferaktion Zwei Methoden müssen hier verändert werden. Zum Einen haben die noch oben laufenden Käfer eine andere Anfangsposition als die nach unten laufenden. Zum Andern muss in der Methode Laufen die Richtung berücksichtig werden public void KäferAktion(Käfer käfer) käfer.schritt(käfer); if (käfer.ypos > Form1.form1.Höhe) //Rand erreicht käfer.aufanfangspositionsetzen(0); if (käfer.ypos < 0) //oberer Rand erreicht käfer.aufanfangspositionsetzen(ym); käfer.zeichnen(); // Käfer an neuer Position zeichnen public override void Laufen(float dv) if (richtung == Richtung.hoch) base.laufen(-dv); else base.laufen(dv); In der Klasse Ameise gibt es keine Änderungen. 22

23 In der Klasse Form1 werden die verschiedenen Insekten initialisiert. Dadurch ergeben sich folgende Änderungen: Initialisierung der vier Käfer in initialisiereinsekten(): käferliste.add(new Käfer(g, Resources.käfera, Resources.käferb, 200, 10, "0.0", Richtung.runter)); käferliste.add(new Käfer(g, Resources.käfer2a, Resources.käfer2b, 400, 480, "0.0", Richtung.hoch)); käferliste.add(new Käfer(g, Resources.käfera, Resources.käferb, 600, 10, "0.0", Richtung.runter)); käferliste.add(new Käfer(g, Resources.käfer2a, Resources.käfer2b, 800, 480, "0.0", Richtung.hoch)); Im Tick-Ereignis muss der Laufparameter geändert werden, da ja nun statt zwei vier Käfer zu steuern sind (Änderungen rot): if (!spielbeendet) for (int i = 0; i < 4; i++) käferliste[i].laufen(4 + 2*i);//ergibt vier verschieden Geschwindigkeiten käferliste[i].käferaktion(käferliste[i]); Aufgabe 10 Erstellen Sie nun, ausgehend vom letzten Stand des Programms, die neue Variante. Machen Sie sich bei den wenigen Änderungen immer klar, was sie bewirken und weshalb sie nötig sind. Weshalb wurde beim Tick-Ereignis von Form1 aus Laufen(5 + 3*i) Laufen(4 +2*i)? (Eine fertige Lösung finden Sie im Ordner KlassenObjekteInsekten04 im Tauschverzeichnis.) Aufgabe 11 Wir verlassen das Spiel und kehren zu unserem Bruchprogramm zurück. Hier sollen Sie unter einfachen Vorgaben das Erlernte vertiefen. Im Tauschverzeichnis finden Sie unter dem Namen 02GemBruchWindowsUnvollständig eine unvollständige Erweiterung des Bruchprogramms für gemischte Zahlen. 23

24 Es wurde eine Unterklasse GemZahl von Bruch eingefügt. Die Methoden multiplizierenmit() und dividierendurch() sollen überladen werden. Bei der Methode addierenmit() behilft man sich einfach dadurch, dass die gemischten Zahlen zuvor in Brüche umgewandelt werden. Dadurch muss diese Methode dann nicht überladen werden. An welcher Stelle des Programms wird Polymorphie verwendet? (Lösung der Aufgabe im Anhang) Technische Ergänzungen Zurück zum Spiel. Zwei Dinge sollen noch verändert werden: Die Käfer werden mit einer Zufallsgeschwindigkeit initialisiert, sodass der Spieler sich nicht auf wiederkehrende Situationen einstellen kann. Die tatsächliche Geschwindigkeit der Käfer kann man durch einen festen Summanden nach unten begrenzen. Je kleiner der Wert ist, desto einfacher ist das Spiel. Also kann man durch Wahl des Summanden (wir nennen ihn ag, wie Anfangsgeschwindigkeit) die Schwierigkeit des Spiels steuern. Dies soll so realisiert werden, dass beim Druck der (Ziffernblock-) Taste "1" der kleinste Wert (Vorschlag: ag = 3) eingestellt und auch links oben im Spielfeld angezeigt wird. Mit Taste "2" stellt man einen mittleren Schwierigkeitsgrad ein (Vorschlag: ag = 5) und mit Taste "3" wird das Durchkommen der Ameisen dann richtig schwer (Vorschlag: ag = 8). Für das Info-Menu muss noch ein kurzer, klarer Text erstellt werden, damit der Spieler weiß, was er zu tun hat. Alle Ergänzungen treffen ausschließlich Form1. Erweiterung der Attribute: Font schrift2 = new Font("Arial", 10);//Schrift für den Schwierigkeitsgrad private int[] z = new int[4]; //Zufallsgeschwindigkeiten private int ag = 3; //Anfangsgeschwindigkeit Erweiterung der Methode initialisiereinsekten(): ZufallsGeschwindigkeitenErzeugen(); 24

25 Neue Methode: private void ZufallsGeschwindigkeitenErzeugen() Random zufall = new Random(); for (int i = 0; i < 4; ++i) z[i] = zufall.next(7); Ergänzung bei Ameisen zeichnen im Tick-Event: SchwierigkeitsgradAngeben(); Käfer zeichnen im Tick-Event: for (int i = 0; i < 4; i++) käferliste[i].laufen(ag + z[i]);//ergibt vier Zufalls-Geschwindigkeiten käferliste[i].käferaktion(käferliste[i]); Ergänzung im KeyDown-Event: case Keys.NumPad1://leicht ag = 2; case Keys.NumPad2://mittel ag = 5; case Keys.NumPad3://schwer ag = 8; Neue Methode: private void SchwierigkeitsgradAngeben() string sg = ""; switch (ag) case 2: sg = "Schwierigkeitsgrad: leicht"; case 5: sg = "Schwiergkeitsgrad: mittel"; case 8: sg = "Schwiergkeitsgrad: schwer"; g.drawstring(sg, schrift2, Brushes.Green, new PointF(10, 30)); Die Message-Box im Info-Click-Event: MessageBox.Show("Ziel des Spiels ist es, die Ameisen auf die rechte Seite in ihren Bau zu führen," + "\r\n ohne sich von den stets hungrigen Käfern fressen zu lassen." + "\r\n Steuerung der Ameisen mit den Tasten A/D bzw. J/L" + " \r\n Schwierigkeitsgrad einstellen mit dem Ziffernblock:" + " \r\n 1: leicht, 2: mittel, 3: schwer \r\n Neustarten mit der Taste R"); Aufgabe 12 Erstellen Sie das Programm mit den obigen Angaben. Eigene Experimente sind erwünscht! (Form1 komplett im Anhang) 25

26 E) Vierte Stufe: Eigene Ideen Der Text dieses Abschnitts ist äußerst kurz! Hier sollen Sie Ihre eigenen Ideen verwirklichen. Hier nur einige wenige Anregungen: Es müssen drei Ameisen gesteuert werden. Die Ameisen müssen (sofern sie überleben) die Strecke zwei- oder dreimal laufen. Ameisen und / oder Käfer können von ihren geraden Strecken abweichen. Dabei sollten aber auch die Bilder entsprechend gedreht werden (anspruchsvoll!). Käfer laufen einen Zufallsweg (noch anspruchsvoller!)

27 Anhang: Lösungen und Ergänzungen Klasse Ameise (vollständig) Stufe 1: using System; using System.Drawing; namespace AmeisenKäferSpiel class Ameise private int x, y;//koordinaten private float va;//geschwindigkeit private int aktuellesbild; private bool angekommen = false; protected Graphics g; protected Bitmap[] bilder = new Bitmap[2]; public Ameise(Graphics g, Bitmap bildeins, Bitmap bildzwei, int xpos, int ypos) this.g = g; bilder[0] = bildeins; bilder[1] = bildzwei; x = xpos; y = ypos; public int Xpos set x = value; get return x; public void Schneller(float dv) va += dv; if (va > 30) va = 30; public void Bremsen(float dv) va -= dv; if (va < 0) va = 0; public void Schritt(Ameise ameise) //Schritt einer Ameise if (va == 0) return; x += Convert.ToInt32(va); //Verschieben der x-position aktuellesbild = (aktuellesbild + 1) % 2; //Bilder abgewechselnd zeigen public void AmeisenAktion(Ameise ameise) ameise.schritt(ameise); ameise.zeichnen(); // Ameise an neuer Position zeichnen 27

28 public void Zeichnen() g.drawimage(bilder[aktuellesbild], x, y); public bool Angekommen set angekommen = value; get return angekommen; Aufgabe 1 (Teillösung): Leider unterscheidet UMLed nicht zwischen Methoden und Eigenschaften. Dafür aber nicht standardgemäß zwischen Auftrag und Anfrage. Der Unterscheid: Eine Anfrage liefert Daten zurück (also nicht void...) wie public bool Angekommen. Tipps: Erst ein leeres Diagramm erzeugen und speichern (KlassenBeziehungen.urd) und dann eine Klasse hinzufügen: Ameise. Nach Beendigung: Diagramm speichern. Eigenschaften gibt es in UMLed nicht. Dafür kann man bei der Eingabe eines Attributs eine Lese-Anfrage bzw. einen Schreibauftrag mit erstellen lassen. (Siehe Bild rechts) Export in Java vornehmen (mögliche Lösung im Anschluss - braun: Kommentare) /** * import-liste * ggf. weiter von Hand anpassen */ public class Ameise 28

29 /** * Attribute der Klasse */ protected Bitmap[] bilder; protected Graphics g; private bool angekommen; private float va; private int aktuellesbild; private int x; /** * Attribute die aus Beziehungen resultieren */ /** * Ameise: Methoden */ /********* Konstruktor Ameise (public) *****************************************/ public Ameise(Graphics g, Bitmap bildeins, Bitmap bildzwei, int xpos, int ypos) //hier ggf. Code ergänzen /********* AmeisenAktion (public) **************************************/ public void AmeisenAktion(Ameise ameise) //hier ggf. Code ergänzen /********* Bremsen (public) ********************************************/ public void Bremsen(float dv) //hier ggf. Code ergänzen /********* Schneller (public) ******************************************/ public void Schneller(float dv) //hier ggf. Code ergänzen /********* Schritt (public) ********************************************/ public void Schritt(Ameise ameise) //hier ggf. Code ergänzen /********* SetzeAngekommen (public) ************************************/ public void SetzeAngekommen(bool pangekommen) angekommen = pangekommen /********* SetzeX (public) *********************************************/ public void SetzeX(int px) x = px 29

30 /********* Zeichnen (public) *******************************************/ public void Zeichnen() //hier ggf. Code ergänzen /********* GibAngekommen (public) **************************************/ public bool GibAngekommen() return angekommen /********* GibX (public) ***********************************************/ public int GibX() return x Klasse Form1 (vollständig) Stufe 1: using System; using System.Drawing; using System.Windows.Forms; using System.Collections.Generic; using AmeisenKäferSpiel.Properties; namespace AmeisenKäferSpiel public partial class Form1 : Form List<Ameise> ameisenliste; //Die Ameisen private Graphics g; // Grafikobjekt, auf dem gezeichnet wird public Form1() InitializeComponent(); initialisiereameisen(); private void initialisiereameisen() g = this.creategraphics(); ameisenliste = new List<Ameise>(); ameisenliste.add(new Ameise(g, Resources.ameise1a, Resources.ameise1b, 0, 260)); ameisenliste.add(new Ameise(g, Resources.ameise2a, Resources.ameise2b, 0, 410)); private void timer1_tick(object sender, EventArgs e) g.clear(color.white); foreach (Ameise ameise in ameisenliste) if (ameise.xpos <= 1000) //selbsterklärend... ameise.ameisenaktion(ameise); 30

31 else ameise.angekommen = true; private void Form1_KeyDown(object sender, KeyEventArgs e) //Eigenschaft KeyPreview des Formulars auf true setzten! switch (e.keycode) case Keys.D: // Linke Hand : obere Ameise steuern ameisenliste[0].schneller(1.5f); // schneller: Taste D, langsamer: Taste A case Keys.A: ameisenliste[0].bremsen(1.5f); case Keys.L: // Rechte Hand : untere Ameise steuern ameisenliste[1].schneller(1.5f); // schneller: Taste L, langsamer: Taste J case Keys.J: ameisenliste[1].bremsen(1.5f); case Keys.R: Application.Restart(); private void beendentoolstripmenuitem1_click(object sender, EventArgs e) Close(); private void neustartentoolstripmenuitem_click(object sender, EventArgs e) Application.Restart(); private void infotoolstripmenuitem_click(object sender, EventArgs e) MessageBox.Show("Steuerung der Ameisen mit den Tasten A/D bzw. J/L" + "\r\n Neustarten mit der Taste R"); Lösung Aufgabe 5 public Bruch(int z, int n) zaehler = z; nenner = n; public int Zaehler //Eigenschaft get return zaehler; set zaehler = value; 31

32 public int Nenner //Eigenschaft get return nenner; set nenner = value; public void multiplizierenmit(bruch bruch) zaehler = zaehler * bruch.zaehler; nenner = nenner * bruch.nenner; kuerzen(); public void dividierendurch(bruch bruch) zaehler = zaehler * bruch.nenner; nenner = nenner * bruch.zaehler; kuerzen(); Lösung Aufgabe 8 class Ameise : Insekt private int aktuellesbild; private bool angekommen = false; private string zeit = "0"; Font schrift = new Font("Arial", 14);//Ausgabeschrift public Ameise(Graphics g, Bitmap bildeins, Bitmap bildzwei, int xpos, int ypos, string lz): base(g, bildeins, bildzwei, xpos, ypos, lz) this.g = g; bilder[0] = bildeins; bilder[1] = bildzwei; x = xpos; y = ypos; this.w = 100; this.h = 75; public override void Schneller(float dv) base.schneller(dv); if (va > 30) va = 30; public override void Schritt(Insekt ameise) //Schritt einer Ameise if (va == 0) //Ameise steht ZeitAusgeben(ameise,zeit); return; ZeitAusgeben(ameise,zeit); x += Convert.ToInt32(va); //Verschieben der x-position aktuellesbild = (aktuellesbild + 1) % 2; //Bilder abgewechselnd zeigen public void AmeisenAktion(Ameise ameise) 32

33 ameise.schritt(ameise); ameise.zeichnen(); // Ameise an neuer Position zeichnen public override void Zeichnen() g.drawimage(bilder[aktuellesbild], x, y); public bool Angekommen get return angekommen; public void Stirbt() lebt = false; private void ZeitAusgeben(Insekt ameise, String zeit) zeit = (DateTime.Now - Form1.form1.StartZeit).TotalSeconds.ToString("0.0"); ameise.lebenszeit = zeit; g.drawstring(string.format(zeit + " s"), schrift, Brushes.Black, new PointF(920, y + 30)); public override void AufAnfangspositionSetzen(int a) //Im Moment unbenutzt x = a; Lösung Aufgabe 11 Form1: using System; using System.Windows.Forms; namespace Bruch public partial class Form1 : Form public Form1() InitializeComponent(); //Aus Demonstrationszwecken Bruchobjekte verwendet. //So kann man sich eine Überladung der Methode "addierenmit()" //für gem.zahlen ersparen! private void button1_click(object sender, EventArgs e) label_rechenzeichen.text = "+"; GemZahl gem1 = new GemZahl(0, 1, 1); GemZahl gem2 = new GemZahl(0, 1, 1); 33

34 einlesen(gem1, gem2); gem1.inbruch(); gem2.inbruch(); Bruch bruch1 = new Bruch(1, 1); Bruch bruch2 = new Bruch(1, 1); bruch1.zaehler = gem1.zaehler; bruch1.nenner = gem1.nenner; bruch2.zaehler = gem2.zaehler; bruch2.nenner = gem2.nenner; bruch1.addierenmit(bruch2); //Polymorphie! gem1.zaehler = bruch1.zaehler; gem1.nenner = bruch1.nenner; gem1.ingemzahl(); ausgeben(gem1); //Ohne Bruchobjekte- aber mit eigener Methode für GemZahl private void button2_click(object sender, EventArgs e) label_rechenzeichen.text = "*"; GemZahl gem1 = new GemZahl(0, 1, 1); GemZahl gem2 = new GemZahl(0, 1, 1); einlesen(gem1, gem2); gem1.multiplizierenmit(gem2);//nutzung der Polymorphie ausgeben(gem1); private void button3_click(object sender, EventArgs e) label_rechenzeichen.text = ":"; GemZahl gem1 = new GemZahl(0, 1, 1); GemZahl gem2 = new GemZahl(0, 1, 1); einlesen(gem1, gem2); gem1.dividierendurch(gem2); ausgeben(gem1); private void beendentoolstripmenuitem_click(object sender, EventArgs e) Close(); private void ausgeben(bruch bruch1) edit_zaehler.text = Convert.ToString(bruch1.Zaehler); edit_nenner.text = Convert.ToString(bruch1.Nenner); private void einlesen(gemzahl gem1, GemZahl gem2) gem1.gzahl = Convert.ToInt32(edit_gzahl1.Text);//Erste gem. Zahl einlesen gem1.zaehler = Convert.ToInt32(edit_zaehler1.Text); gem1.nenner = Convert.ToInt32(edit_nenner1.Text); 34

35 gem2.gzahl = Convert.ToInt32(edit_gzahl2.Text);//Zweite gem. Zahl einlesen gem2.zaehler = Convert.ToInt32(edit_zaehler2.Text); gem2.nenner = Convert.ToInt32(edit_nenner2.Text); private void ausgeben(gemzahl gem1) //Polymorphie! edit_gzahl.text = Convert.ToString(gem1.Gzahl); edit_zaehler.text = Convert.ToString(gem1.Zaehler); edit_nenner.text = Convert.ToString(gem1.Nenner); GemZahl: using System; namespace Bruch class GemZahl : Bruch private int ganzzahl; public GemZahl(int gzahl, int zaehler, int nenner) : base(zaehler, nenner) ganzzahl = gzahl; public int Gzahl // Eigenschaft get return ganzzahl; set ganzzahl = value; //überladene Methode public void multiplizierenmit(gemzahl gem) inbruch(); gem.inbruch(); Zaehler = Zaehler * gem.zaehler; Nenner = Nenner * gem.nenner; kuerzen(); ingemzahl(); //überladene Methode public void dividierendurch(gemzahl gem) inbruch(); gem.inbruch(); Zaehler = Zaehler * gem.nenner; Nenner = Nenner * gem.zaehler; kuerzen(); ingemzahl(); public void inbruch() if (Gzahl > 0) Zaehler = Gzahl * Nenner + Zaehler; Gzahl = 0; this.kuerzen(); 35

36 if (Gzahl < 0) Zaehler = -(-Gzahl * Nenner + Zaehler); Gzahl = 0; this.kuerzen(); public void ingemzahl() //Es wird davon ausgegangen, dass -2 1/2 -(2 1/2) bedeutet! Gzahl = Zaehler / Nenner; Zaehler = Math.Abs(Zaehler) % Math.Abs(Nenner); Lösung Aufgabe 12 namespace AmeisenKäferSpiel public partial class Form1 : Form List<Ameise> ameisenliste; //Die Ameisen List<Käfer> käferliste; //Die Käfer private Graphics g; // Grafikobjekt, auf dem gezeichnet wird public static Form1 form1; //Damit man in andern Klassen Methoden von Form1 verwenden kann private DateTime startzeit; private bool spielbeendet = false; private int ym; // Höhe des Formulars Font schrift = new Font("Arial", 24); //Schrift für die Punktezahl Font schrift2 = new Font("Arial", 10);//Schrift für den Schwierigkeitsgrad private int[] z = new int[4]; //Zufallsgeschwindigkeiten private int ag = 3; //Anfangsgeschwindigkeit public Form1() InitializeComponent(); form1 = this; ym = this.size.height; initialisiereinsekten(); startzeit = DateTime.Now; private void initialisiereinsekten() g = this.creategraphics(); ameisenliste = new List<Ameise>(); käferliste = new List<Käfer>(); ameisenliste.add(new Ameise(g, Resources.ameise1a, Resources.ameise1b, 0, 260,"0.0")); ameisenliste.add(new Ameise(g, Resources.ameise2a, Resources.ameise2b, 0, 410,"0.0")); käferliste.add(new Käfer(g, Resources.käfera, Resources.käferb, 200, 10, "0.0", Richtung.runter)); käferliste.add(new Käfer(g, Resources.käfer2a, Resources.käfer2b, 400, 480, "0.0", Richtung.hoch)); käferliste.add(new Käfer(g, Resources.käfera, Resources.käferb, 600, 10, "0.0", Richtung.runter)); käferliste.add(new Käfer(g, Resources.käfer2a, Resources.käfer2b, 800, 480, "0.0", Richtung.hoch)); ZufallsGeschwindigkeitenErzeugen(); 36

37 public DateTime StartZeit get return startzeit; public int Höhe get return ym; private bool GefressenVonKäfer(Ameise ameise) bool gefressen = false; foreach (Käfer käfer in käferliste) if (ameise.berührt(käfer)) gefressen = true; return gefressen; private void ZufallsGeschwindigkeitenErzeugen() Random zufall = new Random(); for (int i = 0; i < 4; ++i) z[i] = zufall.next(7); private void timer1_tick(object sender, EventArgs e) g.clear(color.white); int anzahlaktiverameisen = 0; foreach (Ameise ameise in ameisenliste) if (GefressenVonKäfer(ameise)) //gezeichnet wird nur, wenn Ameise nicht vom Käfer gefressen wird ameise.stirbt(); ameise.lebenszeit = "50"; //Nur für die Punktzahl: Strafe -500 Punkte... erreicht if (ameise.xpos <= 1000 && ameise.lebt) //rechter Rand noch nicht ameise.ameisenaktion(ameise); anzahlaktiverameisen++; SchwierigkeitsgradAngeben(); if (anzahlaktiverameisen == 0) spielbeendet = true; if (!spielbeendet)//käfer nur zeichnen, wenn mindest. eine Ameise lebt und noch nicht angekommen ist for (int i = 0; i < 4; i++) käferliste[i].laufen(ag + z[i]);//ergibt vier Zufalls- Geschwindigkeiten käferliste[i].käferaktion(käferliste[i]); 37

C# 2000 Expression Beispielcodes für Konsolen- und Formularanwendung

C# 2000 Expression Beispielcodes für Konsolen- und Formularanwendung C# 2000 Expression Beispielcodes für Konsolen- und Formularanwendung 1. "Hai!" [Konsolenanwendung] Console.WriteLine("Hai, wie geht's?"); 2. Muktiplikation mit sich selbst [Konsolenanwendung] // Ausgabe

Mehr

Vererbung. Generalisierung und Spezialisierung Vererbung und Polymorphismus

Vererbung. Generalisierung und Spezialisierung Vererbung und Polymorphismus Vererbung Generalisierung und Spezialisierung Vererbung und Polymorphismus Wir wollen in unserem Aquarium verschiedene Arten von Fischen schwimmen lassen. In einem ersten Ansatz definieren wir nicht nur

Mehr

Programmierung Nachklausurtutorium

Programmierung Nachklausurtutorium Programmierung Nachklausurtutorium Laryssa Horn, Tim Engelhardt 20 März 2018 Klassen Wofür wir Klassen brauchen: Definieren ein Bauplan eines Objektes Bauplan enthält Attribute und Methoden Klasse Beispiel

Mehr

Probeklausur: Programmierung WS04/05

Probeklausur: Programmierung WS04/05 Probeklausur: Programmierung WS04/05 Name: Hinweise zur Bearbeitung Nimm Dir für diese Klausur ausreichend Zeit, und sorge dafür, dass Du nicht gestört wirst. Die Klausur ist für 90 Minuten angesetzt,

Mehr

Begriffe 1 (Wiederholung)

Begriffe 1 (Wiederholung) Begriffe 1 (Wiederholung) Klasse Eine Klasse ist der Bauplan für ein oder mehrere Objekte. In einer Klasse werden Dienste (Methoden) zur Verfügung gestellt. Klassennamen beginnen mit einem Großbuchstaben.

Mehr

Vererbung und Polymorphie

Vererbung und Polymorphie Vererbung und Polymorphie Marc Satkowski, Sascha Peukert 29. September 2016 C# Kurs Gliederung 1. Methodenüberladung 2. Vererbung Polymorphie Methoden- & Eigenschaftsüberschreibung Weitere Schlüsselwörter

Mehr

ÜBUNGEN ZUR OBJEKTORIENTIERTEN MODELLIERUNG

ÜBUNGEN ZUR OBJEKTORIENTIERTEN MODELLIERUNG ÜBUNGEN ZUR OBJEKTORIENTIERTEN MODELLIERUNG Unter objektorientierter Modellierung versteht man das detailgetreue Darstellen einer zu programmierenden Szene durch Skizzen in UML. UML steht für Unified Modelling

Mehr

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8 Java 8 Elmar Fuchs Grundlagen Programmierung 1. Ausgabe, Oktober 2014 JAV8 5 Java 8 - Grundlagen Programmierung 5 Kontrollstrukturen In diesem Kapitel erfahren Sie wie Sie die Ausführung von von Bedingungen

Mehr

Objektorientierte Programmierung. Kapitel 22: Aufzählungstypen (Enumeration Types)

Objektorientierte Programmierung. Kapitel 22: Aufzählungstypen (Enumeration Types) Stefan Brass: OOP (Java), 22. Aufzählungstypen 1/20 Objektorientierte Programmierung Kapitel 22: Aufzählungstypen (Enumeration Types) Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester

Mehr

Objektorientierte Programmierung

Objektorientierte Programmierung Objektorientierte Programmierung In einer objektorientierten Programmiersprache können natürliche Objekte durch Konstrukte der Sprache dargestellt werden. Objekte zeichnen sich durch Eigenschaften und

Mehr

Objektorientierung. Marc Satkowski 20. November C# Kurs

Objektorientierung. Marc Satkowski 20. November C# Kurs Objektorientierung Marc Satkowski 20. November 2016 C# Kurs Gliederung 1. Weiterführende Verzweigungen Tertiäre-Verzweigung switch case 2. Schleifen Zählschleife (for) break & continue 3. Objektorientierung

Mehr

Neben der Verwendung von Klassen ist Vererbung ein wichtiges Merkmal objektorientierter

Neben der Verwendung von Klassen ist Vererbung ein wichtiges Merkmal objektorientierter Kapitel 1 Der vierte Tag 1.1 Vererbung Neben der Verwendung von Klassen ist Vererbung ein wichtiges Merkmal objektorientierter Sprachen. Unter Vererbung versteht man die Möglichkeit, Eigenschaften vorhandener

Mehr

Programmieren in Java

Programmieren in Java Einführung in die Objektorientierung Teil 4 Interfaces, innere Klassen und Polymorphie 2 Vererbung im Klassendiagram (Wiederholung) Vererbung repräsentiert eine ist ein Beziehung zwischen Klassen Ware

Mehr

7. Übung Informatik II - Objektorientierte Programmierung

7. Übung Informatik II - Objektorientierte Programmierung 7. Übung Informatik II - Objektorientierte Programmierung 29. Mai 2015 Inhalt 1 2 3 Übersicht 1 2 3 Idee Menschen nehmen die Welt in Form von Objekten wahr manche Objekte haben gleiche Eigenschaften, hierüber

Mehr

Theorie zu Übung 8 Implementierung in Java

Theorie zu Übung 8 Implementierung in Java Universität Stuttgart Institut für Automatisierungstechnik und Softwaresysteme Prof. Dr.-Ing. M. Weyrich Theorie zu Übung 8 Implementierung in Java Klasse in Java Die Klasse wird durch das class-konzept

Mehr

Vererbung I. Kfz Eigenschaften und Methoden der Klasse Kfz Lkw. Pkw. Eigenschaften und Methoden der Klasse Kfz

Vererbung I. Kfz Eigenschaften und Methoden der Klasse Kfz Lkw. Pkw. Eigenschaften und Methoden der Klasse Kfz Einführung in C++ Vererbung I Durch Vererbung können aus bereits bestehenden Klassen neue Klassen konstruiert werden. Die neue abgeleitete Klasse erbt dabei die Daten und Methoden der sog. Basisklasse.

Mehr

Programmieren in Java

Programmieren in Java Einführung in die Objektorientierung Teil 4 Interfaces, Polymorphie und innere Klassen 2 Vererbung im Klassendiagramm (Wiederholung) Vererbung repräsentiert eine ist ein Beziehung zwischen Klassen Object

Mehr

- EINSTIEG IN JAVA - (1/5) Datum:

- EINSTIEG IN JAVA - (1/5) Datum: - EINSTIEG IN JAVA - (1/5) Datum: 2.2 Wir lernen die Programmiersprache Java und entwickeln ein Computerspiel Schritt #1: Constructor-Methoden: Wir setzen die beiden Spieler in die 'Welt' (das Spielfeld)

Mehr

Programmieren II Abstrakte Klassen / Virtuelle Methoden. Programmieren II Abstrakte Klassen / Virtuelle Methoden

Programmieren II Abstrakte Klassen / Virtuelle Methoden. Programmieren II Abstrakte Klassen / Virtuelle Methoden Einleitende Bemerkungen Einleitende Bemerkungen Aspekte Aufbau von sinnvollen Klassenhierarchien Verwaltung von Objekten unterschiedlichen Typs Mitarbeiter Besonderheiten der Anwendung jeder Angehörige

Mehr

Mapra: C++ Teil 6. Felix Gruber, Sven Groß. IGPM, RWTH Aachen. 13. Juni 2017

Mapra: C++ Teil 6. Felix Gruber, Sven Groß. IGPM, RWTH Aachen. 13. Juni 2017 Mapra: C++ Teil 6 Felix Gruber, Sven Groß IGPM, RWTH Aachen 13. Juni 2017 Felix Gruber, Sven Groß (IGPM, RWTH Aachen) Mapra: C++ Teil 6 13. Juni 2017 1 / 22 Was bisher geschah Klassen I Attribute und Methoden

Mehr

Klausur Grundlagen der Programmierung

Klausur Grundlagen der Programmierung Klausur Grundlagen der Programmierung Aufgabenstellung: Martin Schultheiß Erreichte Punktzahl: von 60 Note: Allgemeine Hinweise: Schreiben Sie bitte Ihren Namen auf jedes der Blätter Zugelassene Hilfsmittel

Mehr

Am Anfang werden die Attribute deklariert public class Kreis {

Am Anfang werden die Attribute deklariert public class Kreis { Klassendiagramm Kreis Entwerfen Sie ein Klassendiagramm der Klasse Kreis mit allen Attributen und min. drei Methoden. public class Kreis { sichtbar Platz für Atributeund Methoden protected int xposition;

Mehr

In dieser Aufgabe geht es darum, das einfache Meteor-Spiel zu verstehen und anzupassen. Lade als erstes das Spiel sample12 und spiele es.

In dieser Aufgabe geht es darum, das einfache Meteor-Spiel zu verstehen und anzupassen. Lade als erstes das Spiel sample12 und spiele es. In dieser Aufgabe geht es darum, das einfache Meteor-Spiel zu verstehen und anzupassen. Lade als erstes das Spiel sample12 und spiele es. Im Spiel fällt ein Meteor vom oben zum unteren Rand. Das Raumschiff

Mehr

Es ist für die Lösung der Programmieraufgabe nicht nötig, den mathematischen Hintergrund zu verstehen, es kann aber beim Verständnis helfen.

Es ist für die Lösung der Programmieraufgabe nicht nötig, den mathematischen Hintergrund zu verstehen, es kann aber beim Verständnis helfen. Ziele sind das Arbeiten mit Funktionen und dem Aufzählungstyp (enum), sowie - einfache Verzweigung (if else) - Alternativen switch case - einfache Schleifen (while oder do while) Aufgabe 3: Diese Aufgabe

Mehr

Objektorientierte Programmierung Studiengang Medieninformatik

Objektorientierte Programmierung Studiengang Medieninformatik Objektorientierte Programmierung Studiengang Medieninformatik Hans-Werner Lang Hochschule Flensburg Vorlesung 5 12.04.2017 Was bisher geschah... Objektorientierte Programmierung Klassen und Objekte, Attribute

Mehr

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 3 - Objektorientierung

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 3 - Objektorientierung Javakurs FSS 2012 Lehrstuhl Stuckenschmidt Tag 3 - Objektorientierung Warum Objektorientierung Daten und Funktionen möglichst eng koppeln und nach außen kapseln Komplexität der Software besser modellieren

Mehr

Fakultät IV Elektrotechnik/Informatik

Fakultät IV Elektrotechnik/Informatik Fakultät IV Elektrotechnik/Informatik Probeklausur Einführung in die Informatik I Hinweis: Diese Probeklausur ist eine kleine Aufgabensammlung, die etwa dem Schwierigkeitsgrad der Teilleistung TL 2 (Programmiertest)

Mehr

2. Vererbung und Kapselung

2. Vererbung und Kapselung 2. Vererbung und Kapselung Die Objekte der Klasse BALL werden im Gegensatz zu den Objekten von KREIS noch nicht graphisch dargestellt. Um die BALL-Objekte auch graphisch darzustellen zu können, muss BALL

Mehr

hue13 January 30, 2017

hue13 January 30, 2017 hue13 January 30, 2017 1 Abgabehinweise Beachten Sie unbedingt diese Hinweise, sonst erhalten Sie keine Punkte aus dieser Abgabe! Für Details siehe z.b. Folien der nullten Zentralübung 1.1 Namen und Matrikelnummern

Mehr

6. Globalübung (zu Übungsblatt 8)

6. Globalübung (zu Übungsblatt 8) 6. Globalübung (zu Übungsblatt 8) Inhalt: Klassenhierarchien Verdecken von Attributen Überschreiben von Methoden Codeanalyse Analyse von JAVA-Programmen Semestralklausur Klausurtermin: Mittwoch 11.01.2006

Mehr

Sichtbarkeiten, Klassenmember und -methoden

Sichtbarkeiten, Klassenmember und -methoden Sichtbarkeiten, Klassenmember und -methoden Prof. Dr.-Ing. Thomas Schwotzer 11. November 2017 1 Einführung Wir haben uns mit Klassen und Objekten beschäftigt. Wir wissen nun, dass Objekte anhand von Klassen

Mehr

Tutorial zu Einführung in die Informatik für LogWi- Ings und WiMas Wintersemester 2015/16. 1 Zauberer und Zwerge, Aufgabenteil 1

Tutorial zu Einführung in die Informatik für LogWi- Ings und WiMas Wintersemester 2015/16. 1 Zauberer und Zwerge, Aufgabenteil 1 Tutorial zu Einführung in die Informatik für LogWi- Ings und WiMas Wintersemester 2015/16 1 Zauberer und Zwerge, Aufgabenteil 1 Stellen Sie sich vor, Sie sollen eine Charakterverwaltung für das neue Onlinerollenspiel

Mehr

Objektorientiertes Programmieren mit C++ für Fortgeschrittene

Objektorientiertes Programmieren mit C++ für Fortgeschrittene BEREICH DATENTECHNIK I CQ 300 00 TH 02 Objektorientiertes Programmieren mit C++ für Fortgeschrittene Kapitel 3 3. Mehrfachvererbung 3.1. Eigenschaften und Problematik 3.2. Virtuelle Basisklassen BEREICH

Mehr

Objektorientierte Programmierung

Objektorientierte Programmierung Unterlagen zur Veranstaltung Einführung in die Objektorientierte Programmierung Mit Processing Alexis Engelke Sommer 2012 Alexis Engelke Inhalt Level 1: Geometrie Hintergrundfarben Punkte, Linien und deren

Mehr

Praktikum 4: Grafiken und Ereignisse

Praktikum 4: Grafiken und Ereignisse Praktikum 4: Grafiken und Ereignisse Aufgabe 1: Java Applikation Bisher haben wir in Java (ebenso wie in C) jeweils selbständige Konsole-Applikationen erstellt. Java wurde als Programmiersprache für das

Mehr

Städtisches Gymnasium Olpe Java Ht Informatik - Q1 Die Klasse List im Abitur Methoden und Beispielcode Hier alle wichtigen Methoden. Ein Beispielcode

Städtisches Gymnasium Olpe Java Ht Informatik - Q1 Die Klasse List im Abitur Methoden und Beispielcode Hier alle wichtigen Methoden. Ein Beispielcode Die Klasse List im Abitur Methoden und Beispielcode Hier alle wichtigen Methoden. Ein Beispielcode folgt im Anschluss. Beispielcode Es gibt eine Klasse Benutzerverwaltung, welche eine Liste mit Benutzern

Mehr

Musterlösung Stand: 5. Februar 2009

Musterlösung Stand: 5. Februar 2009 Fakultät IV Elektrotechnik/Informatik Probeklausur Einführung in die Informatik I Hinweis: Diese Probeklausur ist eine kleine Aufgabensammlung, die etwa dem Schwierigkeitsgrad der Teilleistung TL 2 (Programmiertest)

Mehr

9. Vererbung und Polymorphie. Informatik Vererbung und Polymorphie 1

9. Vererbung und Polymorphie. Informatik Vererbung und Polymorphie 1 9. Vererbung und Polymorphie 1 Wiederholung Vererbung bedeutet, dass eine Klasse Attribute und Methoden an eine andere Klasse weitergeben kann. Im Klassendiagramm stellt man dies durch einen durchgezogenen

Mehr

Javakurs für Anfänger

Javakurs für Anfänger Javakurs für Anfänger Einheit 09: Vererbung Lorenz Schauer Lehrstuhl für Mobile und Verteilte Systeme Heutige Agenda 1. Teil Einführung in die Vererbung Motivation Das Schlüsselwort extends Einführendes

Mehr

Objektorientierte Programmierung Studiengang Medieninformatik

Objektorientierte Programmierung Studiengang Medieninformatik Objektorientierte Programmierung Studiengang Medieninformatik Hans-Werner Lang Hochschule Flensburg Vorlesung 2 22.03.2017 Was bisher geschah... Klassen und Objekte Attribute und Methoden Klasse Bruch

Mehr

Klausur Programmieren 2 SS 2016

Klausur Programmieren 2 SS 2016 Klausur Programmieren 2 SS 2016 Name Gruppe 1 Vorname Dauer 90 min Matrikelnummer Hilfsmittel keine Die Klausur ist mit 50 Punkten sicher bestanden. Hinweise: Formulieren Sie Ihre Lösungen auf dem Aufgabenblatt

Mehr

IT I: Heute. Nachbetrachtung Wissensüberprüfungen. Einführung Vererbung. Roboter in becker.robots. falls Zeit: Scheduling 8.11.

IT I: Heute. Nachbetrachtung Wissensüberprüfungen. Einführung Vererbung. Roboter in becker.robots. falls Zeit: Scheduling 8.11. IT I: Heute Nachbetrachtung Wissensüberprüfungen Einführung Vererbung Roboter in becker.robots falls Zeit: Scheduling 8.11.2016 IT I - VO 5 1 Organisatorisches VO nächste Woche im Peter-Tunner-HS! Tutorium

Mehr

Probeklausur Informatik 2 Sommersemester 2013

Probeklausur Informatik 2 Sommersemester 2013 Probeklausur Informatik 2 Sommersemester 2013 1 Probeklausur Informatik 2 Sommersemester 2013 Name: Matrikelnummer: Hilfsmittel: Es sind alle schriftlichen Unterlagen, aber keine elektronischen Hilfsmittel

Mehr

Objektorientierte Programmierung

Objektorientierte Programmierung Universität der Bundeswehr Fakultät für Informatik Institut 2 Priv.-Doz. Dr. Lothar Schmitz FT 2006 Übungsblatt 3 Lösungsvorschlag Objektorientierte Programmierung 08. 05. 2006 Lösung 8 (Java und UML-Klassendiagramm

Mehr

Handbuch für die Erweiterbarkeit

Handbuch für die Erweiterbarkeit Handbuch für die Erweiterbarkeit Inhalt Pakete für die Erweiterbarkeit... 2 Actions... 2 Items... 2 Itemset... 2 Die UseCaseNewAction... 3 Eigene Shapes... 4 Der Shape Container... 5 User Objects... 6

Mehr

IT I: Heute. Nachbetrachtung Wissensüberprüfung. Einführung Vererbung. Roboter in becker.robots. Filialenbelieferung 4.11.

IT I: Heute. Nachbetrachtung Wissensüberprüfung. Einführung Vererbung. Roboter in becker.robots. Filialenbelieferung 4.11. IT I: Heute Nachbetrachtung Wissensüberprüfung Einführung Vererbung Roboter in becker.robots Filialenbelieferung 4.11.2014 IT I - VO 4 1 Organisatorisches Tutorium am Mi, 12.11. schon um 11 Uhr (bis 12:30).

Mehr

Implementieren von Klassen

Implementieren von Klassen Implementieren von Klassen Felder, Methoden, Konstanten Dr. Beatrice Amrhein Überblick Felder/Mitglieder (Field, Member, Member-Variable) o Modifizierer Konstanten Methoden o Modifizierer 2 Felder und

Mehr

Objektorientierung. Klassen und Objekte. Dr. Beatrice Amrhein

Objektorientierung. Klassen und Objekte. Dr. Beatrice Amrhein Objektorientierung Klassen und Objekte Dr. Beatrice Amrhein Überblick Konzepte der Objektorientierten Programmierung Klassen und Objekte o Implementierung von Klassen o Verwendung von Objekten 2 Konzepte

Mehr

Kapitel 13. Abstrakte Methoden und Interfaces. Fachgebiet Knowledge Engineering Prof. Dr. Johannes Fürnkranz

Kapitel 13. Abstrakte Methoden und Interfaces. Fachgebiet Knowledge Engineering Prof. Dr. Johannes Fürnkranz Kapitel 13 Abstrakte Methoden und Interfaces 13. Abstrakte Klassen und Interfaces 1. Abstrakte Klassen 2. Interfaces und Mehrfachvererbung Folie 12.2 Abstrakte Methoden und Klassen Manchmal macht es überhaupt

Mehr

Delegatesund Ereignisse

Delegatesund Ereignisse Delegatesund Ereignisse «Delegierter» Methoden Schablone Funktionszeiger Dr. Beatrice Amrhein Überblick Definition eines Delegat Einfache Delegate Beispiele von Delegat-Anwendungen Definition eines Ereignisses

Mehr

Probeklausur Java Einführung in die Informatik. Wintersemester 2016/2017

Probeklausur Java Einführung in die Informatik. Wintersemester 2016/2017 Fakultät IV NI & CV Java Einführung in die Informatik Wintersemester 2016/2017 Hinweis: Diese ist eine kleine Aufgabensammlung, die etwa dem Schwierigkeitsgrad der schriftlichen Prüfung des Moduls Einführung

Mehr

Probeklausur Java Einführung in die Informatik. Wintersemester 2017/2018

Probeklausur Java Einführung in die Informatik. Wintersemester 2017/2018 Fakultät IV NI & CV Java Einführung in die Informatik Wintersemester 2017/2018 Hinweis: Diese ist eine kleine Aufgabensammlung, die etwa dem Schwierigkeitsgrad der schriftlichen Prüfung des Moduls Einführung

Mehr

Probeklausur Java Einführung in die Informatik. Wintersemester 2014/2015

Probeklausur Java Einführung in die Informatik. Wintersemester 2014/2015 Fakultät IV NI & CV Probeklausur Java Einführung in die Informatik Wintersemester 2014/2015 Hinweis: Diese Probeklausur ist eine kleine Aufgabensammlung, die etwa dem Schwierigkeitsgrad der schriftlichen

Mehr

Umsetzung einer Klassenkarte in einer Programmiersprache

Umsetzung einer Klassenkarte in einer Programmiersprache Klassen in Java Umsetzung einer Klassenkarte in einer Programmiersprache Objektorientierte Programme bestehen (nur) aus Klassendefinitionen In Klassendefinitionen wird die Struktur der Objekte festgelegt,

Mehr

2 Teil 2: Nassi-Schneiderman

2 Teil 2: Nassi-Schneiderman 2 Teil 2: Nassi-Schneiderman Wie kann man Nassi-Schneiderman in einer objektorientierten Sprache verwenden? Jedes Objekt besitzt Methoden, welche die Attribute des Objektes verändern. Das Verhalten der

Mehr

Staubsauger-Roboter. Als Vorlage dienen dir drei Klassen: RECHTECK Damit kannst du die Wände des Raums darstellen.

Staubsauger-Roboter. Als Vorlage dienen dir drei Klassen: RECHTECK Damit kannst du die Wände des Raums darstellen. Projekt: Staubsauger-Roboter Immer beliebter werden die kleinen automatischen Haushaltshilfen. Du sollst nun einen Staubsauger-Roboter programmieren, der gesteuert von einer künstlichen Intelligenz (KI)

Mehr

Graphic Coding. Klausur. 9. Februar 2007. Kurs A

Graphic Coding. Klausur. 9. Februar 2007. Kurs A Graphic Coding Klausur 9. Februar 2007 Kurs A Name: Matrikelnummer: Hinweise - Es sind keine Hilfsmaterialien erlaubt. (Keine Bücher, Taschenrechner, Handys) - Sie haben zwei Stunden Zeit. - Insgesamt

Mehr

Der Ball kann angezeigt werden: anzeigen( ) {... } Der Ball kann z.b. seine Größe verändern: groesseaendern(int veraenderung) {... } usw.

Der Ball kann angezeigt werden: anzeigen( ) {... } Der Ball kann z.b. seine Größe verändern: groesseaendern(int veraenderung) {... } usw. Objekt-Orientierung Die ersten objektorientierten Sprachen wurden ab 1967 entwickelt (Simula, Smalltalk). Die Grundidee besteht darin, Objekte der realen Welt abzubilden. Java-Programme bestehen aus Klassen.

Mehr

Javakurs für Anfänger

Javakurs für Anfänger Javakurs für Anfänger Einheit 11: Vererbung Lorenz Schauer Lehrstuhl für Mobile und Verteilte Systeme Heutige Agenda 1. Teil Einführung in die Vererbung Motivation Das Schlüsselwort extends Einführendes

Mehr

7. Arrays. Beim Deklarieren und Initialisieren der Liste bräuchte man oft zueinander sehr ähnlichen Code:

7. Arrays. Beim Deklarieren und Initialisieren der Liste bräuchte man oft zueinander sehr ähnlichen Code: 7. Arrays Gelegentlich braucht man für ein Programm mehrere Attribute desselben Datentyps oder derselben Klasse. Beispiel: In der Highscore-Liste eines Spiels werden von den 10 besten Spielern die Namen

Mehr

Klassen und Objekte. Klassen sind Vorlagen für Objekte. Objekte haben. Attribute. Konstruktoren. Methoden. Merkblatt

Klassen und Objekte. Klassen sind Vorlagen für Objekte. Objekte haben. Attribute. Konstruktoren. Methoden. Merkblatt Klassen und Objekte Klassen sind Vorlagen für Objekte. Objekte haben Attribute Konstruktoren Methoden Aus einer Klasse kann man beliebig viele Objekte herstellen. Attribute bestimmen die Eigenschaften

Mehr

Programmieren in Java -Eingangstest-

Programmieren in Java -Eingangstest- Programmieren in Java -Eingangstest- Nummer: 1. Studiengang: Informatik B.Sc. Informatik M.Sc. ESE B.Sc. ESE M.Sc. Sonstiges: Fachsemester: Bitte Fragen, die Sie nicht beantworten können unbedingt mit

Mehr

Einstieg in die Informatik mit Java

Einstieg in die Informatik mit Java 1 / 35 Einstieg in die Informatik mit Java Vererbung Gerd Bohlender Institut für Angewandte und Numerische Mathematik Gliederung 2 / 35 1 Grundlagen 2 Verdeckte Variablen 3 Verdeckte Methoden 4 Konstruktoren

Mehr

Probeklausur Java Einführung in die Informatik. Wintersemester 2014/2015. Musterlösung

Probeklausur Java Einführung in die Informatik. Wintersemester 2014/2015. Musterlösung Fakultät IV NI & CV Probeklausur Java Einführung in die Informatik Wintersemester 2014/2015 Hinweis: Diese Probeklausur ist eine kleine Aufgabensammlung, die etwa dem Schwierigkeitsgrad der schriftlichen

Mehr

01. Grundprinzipien der Vererbung

01. Grundprinzipien der Vererbung 01. Grundprinzipien der Vererbung 1.1 Grundidee der Vererbung Bei der Analyse eines Problems (z.b. Baukasten) stellt man beispielsweise fest, dass 67 % an Daten/Funktionen immer vorkommen 25 % an Daten/Funktionen

Mehr

Algorithmen und Datenstrukturen 07

Algorithmen und Datenstrukturen 07 (7. Juni 2012) 1 Besprechung Blatt 6 Fragen 2 Referenzen Referenzsemantik 3 Vererbung Allgemein abstract Interfaces Vererbung in UML 4 Vorbereitung Blatt 7 Anmerkungen Fragen Fragen zu Blatt 6? Referenzsemantik

Mehr

Klassen können bekanntlich aus zwei Komponententypen bestehen, nämlich Attributen und Methoden.

Klassen können bekanntlich aus zwei Komponententypen bestehen, nämlich Attributen und Methoden. Objektzugriff Klassen können bekanntlich aus zwei Komponententypen bestehen, nämlich Attributen und Methoden. Attribute sind in der Klasse mit Datentyp und Namen deklariert im Objekt sind sie mit jeweils

Mehr

Ereignisse (Events) Asynchrones Versenden von Informationen Sender (Herausgeber) Empfänger (Abonnent) Dr. Beatrice Amrhein

Ereignisse (Events) Asynchrones Versenden von Informationen Sender (Herausgeber) Empfänger (Abonnent) Dr. Beatrice Amrhein Ereignisse (Events) Asynchrones Versenden von Informationen Sender (Herausgeber) Empfänger (Abonnent) Dr. Beatrice Amrhein Überblick Definition eines Ereignisses Sender und Empfänger Einfache Ereignisse

Mehr

Greenfoot: Verzweigungen

Greenfoot: Verzweigungen Greenfoot: Verzweigungen Nicolas Ruh und Dieter Koch Betrachten wir die act()-methode des Wombats aus dem Wombats-Szenario: Wie interpretieren Sie diesen Code? (einfach übersetzen) Falls der Wombat ein

Mehr

Programmiertechnik Klassenvariablen & Instantiierung

Programmiertechnik Klassenvariablen & Instantiierung Programmiertechnik Klassenvariablen & Instantiierung Prof. Dr. Oliver Haase Oliver Haase Hochschule Konstanz 1 Klassenvariablen Zur Erinnerung: Klassen bestehen aus Variablen und Methoden; beide zusammen

Mehr

Arrays. Theorieteil. Inhaltsverzeichnis. Begriffe. Programmieren mit Java Modul 3. 1 Modulübersicht 3

Arrays. Theorieteil. Inhaltsverzeichnis. Begriffe. Programmieren mit Java Modul 3. 1 Modulübersicht 3 Programmieren mit Java Modul 3 Arrays Theorieteil Inhaltsverzeichnis 1 Modulübersicht 3 2 Eindimensionale Arrays 3 2.1 Arrays deklarieren.............................. 3 2.2 Arrays erzeugen................................

Mehr

Die Welt in unseren Programmen false -1.4E-12. false. Klassen

Die Welt in unseren Programmen false -1.4E-12. false. Klassen Algorithmen und Datenstrukturen Die Welt in unseren Programmen Die Welt in unseren Programmen Wintersemester 2012/13 9. Vorlesung Sortieren von Objekten 1.357374356 25236748458 true "HalloWelt!" 14136.23462

Mehr

Greenfoot: Verzweigungen Nicolas Ruh und Dieter Koch

Greenfoot: Verzweigungen Nicolas Ruh und Dieter Koch Greenfoot: Verzweigungen Nicolas Ruh und Dieter Koch Betrachten wir die act()-methode des Wombats aus dem Wombats-Szenario: Wie interpretieren Sie diesen Code? (einfach übersetzen) Falls der Wombat ein

Mehr

Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen

Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen 16OH21005 gefördert. Die Verantwortung für den Inhalt dieser

Mehr

pue13 January 28, 2017

pue13 January 28, 2017 pue13 January 28, 2017 1 Aufgabe 1 (Klammern und Anweisungsblöcke) Wie Sie in der Vorlesung gelernt haben, werden Anweisungsblöcke in Java nicht durch Einrückung, sondern mithilfe von geschweiften Klammern

Mehr

Objektorientiertes Programmieren (Java)

Objektorientiertes Programmieren (Java) Grundlagen Objektorientiertes Programmieren (Java) Java folgt gewissen Rechtschreibregeln die Syntax. Diese besagt, dass hinter jeden Befehl ein Semikolon( ; ) stehen muss, damit der Computer weiß, dass

Mehr

Polymorphie und UML Klassendiagramme

Polymorphie und UML Klassendiagramme Polymorphie und UML Klassendiagramme Prof. Dr.-Ing. Thomas Schwotzer 1 Einführung Vererbung hat einen sehr interessanten und effektiven Effekt: die Polymorphie. Darum geht es in dieser Veranstaltung. 2

Mehr

Überblick. Überblick. Abstrakte Klassen - rein virtuelle Funktionen Beispiele

Überblick. Überblick. Abstrakte Klassen - rein virtuelle Funktionen Beispiele Überblick 1. Einführung C++ / Entwicklung/ Sprachfamilie 2. Nicht objektorientierte Erweiterungen von C 2.1 Das Ein-/Ausgabekonzept von C++ 2.2 Referenzen in C++ 2.3 Heap-Allokatoren in C++ 3. Grundlagen

Mehr

3. Bedingte Anweisungen

3. Bedingte Anweisungen 3. Bedingte Anweisungen Fallunterscheidungen der Form WENN...DANN... in der Informatik kennst du aus der 7. Klasse beim Programmieren mit Karol sowie aus der 9. Klasse beim Arbeiten mit Tabellen und Datenbanken.

Mehr

3. Das erste eigene Programm mit Greenfoot: Litte Crab

3. Das erste eigene Programm mit Greenfoot: Litte Crab Eigenes Programm: Little Crab1, Seite 1 von 5 3. Das erste eigene Programm mit Greenfoot: Litte Crab 3.1. Quelltext bearbeiten Nachdem Sie etwas Erfahrungen in der Bedienung von Greenfoot gewonnen haben,

Mehr

Einführung in die Programmierung I. 11. Vererbung. Stefan Zimmer

Einführung in die Programmierung I. 11. Vererbung. Stefan Zimmer Einführung in die Programmierung I 11. Vererbung Stefan Zimmer 21.1.2008 Programmcode wiederverwenden Wenn wir einige Klassen geschrieben haben, werden wir dabei Teile davon öfters hingeschrieben haben

Mehr

Java Vererbung. Inhalt

Java Vererbung. Inhalt Java Vererbung Inhalt 1 Zielsetzung... 2 1.1 Bewertung... 2 2 Grundlagen der Vererbung... 2 2.1 Super und Subklassen... 2 3 Überladen von Methoden... 4 3.1 Unterschiedliche Parameter... 4 3.2 Gleiche Parameter

Mehr

Programmierkurs Java

Programmierkurs Java Programmierkurs Java Dr. Dietrich Boles Aufgaben zu UE22-NutzungVonKlassen (Stand 28.09.2012) Aufgabe 1: Entwickeln Sie in Eclipse auf der Basis der vorgestellten Java-GUI-Klassen ein Java- Programm, das

Mehr

Informatik 10 Objektorientiertes Modellieren und Programmieren mit Java

Informatik 10 Objektorientiertes Modellieren und Programmieren mit Java Informatik 10 Objektorientiertes Modellieren und Programmieren mit Java 1. Klassen und Objekte Zunächst wollen wir mit Hilfe eines Miniprogramms die Entwicklungsumgebung BlueJkennen lernen. Die Installation

Mehr

1 Grundlagen der Objektorientierung

1 Grundlagen der Objektorientierung Kapitel 1 Grundlagen der Objektorientierung Seite 1/8 1 Grundlagen der Objektorientierung Dieses Kapitel stellt eine solide, pragmatische Einführung in die fundamentalen Konzepte der Objektorientierung

Mehr

12 Abstrakte Klassen, finale Klassen und Interfaces

12 Abstrakte Klassen, finale Klassen und Interfaces 12 Abstrakte Klassen, finale Klassen und Interfaces Eine abstrakte Objekt-Methode ist eine Methode, für die keine Implementierung bereit gestellt wird. Eine Klasse, die abstrakte Objekt-Methoden enthält,

Mehr

Javakurs für Anfänger

Javakurs für Anfänger Javakurs für Anfänger Einheit 10: Mehr zur Vererbung und abstrakte Klassen Lorenz Schauer Lehrstuhl für Mobile und Verteilte Systeme Heutige Agenda 1. Teil: Mehr zur Vererbung Methoden vererben und überschreiben

Mehr

Kapitel 9. Programmierkurs. Attribute von Klassen, Methoden und Variablen. 9.1 Attribute von Klassen, Methoden und Variablen

Kapitel 9. Programmierkurs. Attribute von Klassen, Methoden und Variablen. 9.1 Attribute von Klassen, Methoden und Variablen Kapitel 9 Programmierkurs Birgit Engels Anna Schulze Zentrum für Angewandte Informatik Köln Objektorientierte Programmierung Attribute von Klassen, Methoden und Variablen Interfaces WS 07/08 1/ 18 2/ 18

Mehr

Ein erstes "Hello world!" Programm

Ein erstes Hello world! Programm OOP Henrik Horstmann 14. September 2014 Inhaltsverzeichnis Inhaltsverzeichnis 1 Bedeutung der Symbole...1 2 Die Benutzer Oberfläche von HOOPLU...2 2.1 Projekte öffnen und speichern...2 2.2 Die Klasse Program

Mehr

9. Zurück zur OOP: Vererbung und Polymorphismus

9. Zurück zur OOP: Vererbung und Polymorphismus bertram.hafner@t-online.de Informatik 11 Seite 38 9. Zurück zur OOP: Vererbung und Polymorphismus Eine neue Klasse wird immer durch Vererbung aus einer bereits vorhandenen Klasse abgeleitet. Durch die

Mehr

OOP und Angewandte Mathematik. Eine Einführung in die Anwendung objektorientierter Konzepte in der angewandten Mathematik

OOP und Angewandte Mathematik. Eine Einführung in die Anwendung objektorientierter Konzepte in der angewandten Mathematik Eine Einführung in die Anwendung objektorientierter Konzepte in der angewandten Mathematik WS 2011/12 Inhalt Test-Besprechung! Ziele verdeutlichen Große Bild von OOP Wiederholung: Einbettung als Technik

Mehr

Vererbung P rogram m ieren 2 F örster/r iedham m er K apitel 11: V ererbung 1

Vererbung P rogram m ieren 2 F örster/r iedham m er K apitel 11: V ererbung 1 Vererbung 1 11.1 Motivation und Begriffsdefinitionen 11.2 Vorgehensweise und Implementierung 11.3 Arten von Vererbung 11.4 Konstruktoren 11.5 Abstrakte Klasse 11.6 Verschattung 11.7 Wurzelklasse Object

Mehr

Propädeutikum Programmierung in der Bioinformatik

Propädeutikum Programmierung in der Bioinformatik Propädeutikum Programmierung in der Bioinformatik Java Klassen und Objekte Thomas Mauermeier 27.11.2018 Ludwig-Maximilians-Universität München Rückblick Imperative Programmierung Variablen Fallunterscheidungen

Mehr

Objektorientierte Programmierung (OOP)

Objektorientierte Programmierung (OOP) orientierte Programmierung (OOP) 1. Motivation Die objektorientierte Sichtweise der Welt Als Motivation für die OOP sieht man sich am besten die reale Welt an: Die reale Welt besteht aus "en", z. B.: Gegenstände,

Mehr