Programmierung

So Li
Flashcards by , created 9 months ago

Einführung in die Programmierung

0
0
0
So Li
Created by So Li 9 months ago
Codierung
Tom Kühling
Wirtschaftsinformatik Teil 1
Sabrina Heckler
Einführung in das Studium Informatik
Daniel Doe
Reducing the Impact of Earthquakes
siobhan.quirk
Účto Fífa 3/6
Bára Drahošová
Informatik
Tom Kühling
ein kleines Informatik Quiz
AntonS
PHP Grundlagen
chrisi.0605
Wirtschaftsinformatik Teil 2
Sabrina Heckler
Informatik 1 - Einführung
Svenja
Question Answer
Compiler Übersetzt Befehle in Maschinenbefehle
COMPILER VORTEILE - Hohe Ausführungsgeschwindigkeit der Programme, - Optimale Nutzung der Prozessoreigenschaften, - Quellcode gut geschützt
Compiler Nachteile • Langwieriger Übersetzungsvorgang • Programme auf Zielrechner spezialisiert • Zusätzlicher Aufwand für Anpassungen • Verschiedene Compiler notwendig (Mac, Windows)
Interpreter Vorteile • KEIN LANGWIERIGER ÜBERSETZUNGSVORGANG • QUELLCODE DIREKT AUSFÜHRBAR, WENN INTERPRETER VERFÜGBAR
Interpreter Nachteile • Langsame Ausführung • Quellcode lesbar • Verschiedene Interpreter notwendig
Interpreter Schritt für Schritt unmittelbare Ausführung
Java: Mischung Compiler Interpreter Vorteile • Nur ein Compiler • Sprache ist Plattformunabhängig • Quellcode teilweise geschützt
Java: Mischung Compiler Interpreter Nachteile • Langsame Ausführung • Verschiedene Interpreter notwendig
Variable - Platzhalter für Wert eines bestimmten Typs - Mit Adresse im Hauptspeicher assoziiert z.B. x
Deklaration - Erwähnen der Variable - Typfestlegung der Variable dadurch wird festgelegt: - Art der Operationen - Speicherplatzbedarf - Werte des Speicherinhalts z.B. double x;
Zuweisung - Weist einer Variable einen Wert zu: mit Zuweisungsoperator "=" - x = Wert einer Zahl int i = 10; i%10 ; i = 0; Bedingungen verändern auch die Variable
Datentyp Bauplan für Werte von Variablen oder Konstanten, der festlegt: • Wie die Darstellung der Werte im Speicher erfolgt • Welche Operationen erlaubt sind • Welche Standardwerte (Default-Werte) festgelegt sind
Ausdruck Kombination von Operanden und Operatoren als Vorschrift zur Berechnung eines Wertes - Liefert immer Ergebnis
Operand Konstante: 1 Variable: x
Operator = / *
Anweisung - Kombination von Ausdrücken und Methoden zur Ausführung einer Aktion - x = 5: Wertzuweisung - Print(x): Ausgabeanweisung: Methodenaufruf „Drucke x“ () Argumentklammer
Anweisungs-Sequenz: mehrere Anweisungen, die nacheinander ausgeführt werden
Anweisungs-Block: logisch zusammengefasste Anweisungen oder Programmteile, die als eine Anweisung aufgefasst werden können
Bedingte Anweisung / Entscheidungsanweisung: Anweisung mit mehreren Alternativen
Wiederholungsanweisung / Schleife: mehrfach ausgeführter Anweisungsteil
Java-Programm ausführen 1. Editieren: Programmtext erstellen; in einer Datei speichern: notepad Kehrwert.java 2. Übersetzen in Java-Bytecode: Compiler javac Kehrwert.java -> dabei entsteht gleichnamige Datei mit Endung .class 3. Bytecode Ausführen mit Interpreter: Java Kehrwert
C-Programm ausführen 1. Editieren: Programmtext erstellen; in einer Datei speichern: nano kehrwert.c 2. Übersetzen in Maschinencode: Programmtext mit Compiler in Maschinencode übersetzen gcc –o kehrwert kehrwert.c //ausführbare Datei kehrwert entsteht 3. Ausführen: ./kehrwert
Grammatik Der Compiler übersetzt nur korrekte Java-Programme Die Korrektheit wird anhand der Grammatik überprüft
Grammatik, festgelegt durch: 1. Alphabet: erlaubter Zeichenvorrat 2. Syntax: zulässige Zeichenfolgen 3. Semantik: Bedeutung & Bezeichnung zwischen Sprachelementen, die die Bedeutung des Programms festlegen
Der Compiler... 1. Scannt zunächst die Zeichenfolge 2. Sucht Gruppen von Zeichen, indem nach Trennern gesucht wird 3. Zeichen zwischen zwei Trennern sind lexikalische Elemente (Token)  Wort der Sprache Trenner: Whitespace, Kommentare, Satzzeichen, Operatoren
Bezeichner: Lexikalische Elemente (Tokens) beliebig lange Zeichenfolge, beginnend mit Buchstaben
Keywords: Lexikalische Elemente (Tokens) reservierte Wörter mit vordefinierter Bedeutung -> können kein Bezeichner sein Abstract, new, return, if, static, this, long
Literale: Lexikalische Elemente (Tokens) repräsentieren konstante Werte von Datentypen Int, float, true, false, ‚char‘, „String“, Nullreferenz
Satzzeichen: Lexikalische Elemente (Tokens) . , ; )( }{][
Operatoren: Lexikalische Elemente (Tokens) (Trenner und Token) + && >>>
8 Goldene Regeln: 1. 1 Anweisung pro Zeile 2. Blöcke einrücken 3. } stehen alleine in ihrer Zeile & in der gleichen Spalte 4. switch-Blöcke gut formatiert 5. Klassennamen beginnen groß 6. Variablen und Methoden klein am Anfang 7. Konstanten komplett GROSS_GESCHRIEBEN public static final int GROSS = 10; 8. eine Return-Anweisung pro Funktion (Methode mit Rückgabetyp)
Einfache (elementare) Datentypen = Primitive Datentypen: o Boolean, nummerische ganzzahlige Typen (byte, short, int, long), Gleitkommatypen, char
Referenztypen: o Klassen, Interfaces, Felder
byte byte 8 Bit -128 127 0
short short 16 Bit -32768 32767 0
int int 32 Bit -2147483648 2147483647 0
long long 64 Bit -9223372036854775808 9223372036854775807 L 0L
float float 32 Bit 1.4E-45 3.40282347E38 f 0.0F
double double 64 Bit 1.7976931348623157E308 4.9E-324 1.3E7d 0.0D
boolean boolean 8 Bit false true false
char char 16 Bit 0 6553 \u0000
Typumwandlung Probleme von unten nach oben immer Datenverlust int = long int = float long = double float = double
Einstellige Operatoren monadische, unäre ++ beziehen sich auf einen einzelnen Operanden
Zweistellige Operatoren dyadische, binäre Operatoren *, &&,<
Dreistellige Operatoren triadische, ternäre Operatoren ?:
Präfix-Notation: -a
Postfix-Notation: n++
Infix-Notation: a+b oder max = (a>b) ?a : b;
int i = 0; feld[++i + i++] = i++ + ++i; feld[2] = 2+4;
true & true true
false & true false
true && false false
false && true false && egal false
true | true = true
false | true = true
true || false true || egal = true
false || true = true
true ^ false = true
true ^ true = false
false ^ true = true
false ^ false = false
a=-55; ~a; a=? a = -55; ~a = 54
a << b: Schiebt die Bits in a um b Stellen nach links i = 2<<3 ; 2*23= 16
a>>b: Schiebt die Bits in a um b Stellen nach rechts füllt mit dem höchsten Bit von a auf
a>>>b: o Schiebt die Bits in a um b Stellen nach rechts o füllt mit 0-Bits auf
Auswertungsreihenfolge in Ausdrücken Einstellig ++ vor multiplikativ * vor additiv + vor vergleichend < vor logisch & vor zuweisend = ++ * + > < &| =
Switch-Ausdruck verbotene Datentypen long, float, double, boolean
Switch - Werte sind konstant - break & default (nur wenn Wert davor nicht vordefiniert) nicht vergessen
Switch Code switch (<switch-Ausdruck>){ case <Konstante>: <Anweisungsfolge> break; case <Konstante>: <Anweisungsfolge> break; default: <Anweisungsfolge> break; //optional }
while-Schleife: o der Schleifenkörper wird solange ausgeführt, wie die Bedingung wahr ist o ist die Bedingung falsch, wird die Schleife verlassen o wenn man eine while-Schleife unterbrechen möchte, z.B. if(x==10) break;
do-while-Schleife: o Der Schleifenkörper wird einmal abgearbeitet, erst danach wird die Bedingung geprüft. o Bei positivem Test, wird die Schleife durchlaufen, bei negativem beendet
Syntax Bestandteile der for schleife: for-Schleife Syntax Bestandteile der for schleife: for (Initialisierungsliste; Logischer Ausdruck; Update-Liste) { Anweisung bzw. Block mit Anweisungsfolge }
break - break: Wenn man einer Schleife raus möchte, z.B. if(x==10) break;
continue: - continue: beendet den aktuellen Durchlauf der Schleife und man gelangt wieder in den Schleifenkopf (bei for wird dadurch iteriert )
int [ ] iv; was wird hier gespeichert? dort wird die Adresse abgespeichert, in der der Inhalt vom Feld gespeichert wird. Hier steht noch null drinnen
int [ ] iv = new int [3]; was wird hier gespeichert? - Im Speicher wird Platz für 3 Variablen gesucht - Die Speicheradresse der 3 Variablen wird als Referenz im Array gespeichert
Gleichheit zwei einfacher Datentypen wenn gilt (b == a)
Gleichheit zweier Referenzdatentypen wenn sie auf die gleiche Referenz zeigen (r==s)
Dynamische Array Allokation double[ ] x = new double[3];
Fachwörter dafür: double[] x = new double[3]; <Typ>[] <Feldname> = new <Typ>[<Grenze>]; <Typ> = Typ oder Klasse <Grenze> = Feldlänge; Feldelemente von 0 bis <Grenze>-1
Statische Array Allokation double[ ] y = {3.0, 6.0,9.0};
Was passiert, wenn man die Array-Größe verändert? - die Referenz wird auf ein neues Array gelegt - die Informationen des alten Arrays sind nicht mehr zugreifbar -> Garbage-Collector
Array Fehler • fehlende Initialisierung durch new oder Werte • System.out.println (feldname); -> hier bekommt man die Speicheradresse • Bei Schleifen immer feld.length -1 • Länge kann nur ganzzahlig sein • Beim Initialisieren müssen immer die gleiche Anzahl von Klammern rechts und links stehen • Bei mehrdimensionalen Feldern, müssen immer zuerst die ersten Dimensionen initialisiert werden o int [] [] [] big = new int [] [] [2];
Was passiert? int[ ] f1 = new int[2]; int[ ] f2 = new int[5]; f2 = f1; Referenzkopie: - f2 hat nun die gleiche Referenz wie f1 - f2.length = 2 - Eine Veränderung von f2 bewirkt eine Veränderung von f1
Flache Kopie: o Die erste Ebene einer Struktur wird dupliziert o Die hinteren Referenzen werden kopiert o Änderung der ersten Ebene von f2 wirkt sich nicht auf f1 aus o f2 = f1.clone();
Tiefe Kopie Tiefe Kopie = Clonen o Die komplette Struktur wird dupliziert o f2 ist völlig unabhängig von f1
Klassen: - selbstdefinierte Baupläne für einen Datentyp - zum Erzeugen von Objekten, die aus mehreren Komponenten unterschiedlicher Typen entstehen - sind Referenzdatentypen
Klassen Syntax Modifizierer-Folge class Bezeichner { public class Datum { Modifizierer-Folge kann entfallen }
Wo können Klassen deklariert werden? - Innerhalb einer Klasse geschachtelt o inner classes: non static o nested classes: static - Außerhalb einer Klasse, in eigenständiger Datei (bevorzugt) - Außerhalb der Klasse, in gleicher Datei
Nachteile geschachtelter Klassen o unübersichtliche Dateistruktur o größerer Programmtext o Schwere Korrektur -> lieber als Elementklasse/Top-Level-Klasse auslagern
Zugriffs-Modifizierer: + public: Zugriff für alle Klassen - private: Zugriff nur innerhalb der Klasse # protected: Zugriff für vererbte Klassen + Paket ~ package: default „package-private“ Zugriff für alle Klassen des Pakets
Wie kann man private Variablen erfragen? public String getName() { return this.name; } System.out.println(charly.getName());
Instanzvariablen • stehen nicht in einer Methode, nur in einer Klasse • beim Erzeugen eines Objekts dieser Klasse werden • diese Variablen automatisch miterzeugt und können individuell belegt werden Zugriff: <Objektname>.<Variablenname>
Klassenvariablen: static: Kennzeichnung von Komponenten, die genau einmal erzeugt werden (Beim Laden der Klasse) - Diese Komponenten haben für jedes Objekt der Klasse den selben Wert Beispiel: Wechselkurs Euro in Dollar Zugriff: <Klassenname>.<Klassenvariable> (auch über Objektreferenz möglich)
Konstruktor Aufgabe o Objekterzeugung mit Startwerten • statt drei nur ein Befehl o Initialisierungsarbeiten o Das Bilden von Objekten z.B. Belegen von Instanzvariablen mit den Werten vom Benutzer
Konstruktor Code public class Sudent { String name; Student (String name) { this.name = name; }} Student charly = new Student("Charly");
Instanzmethode: • Methode ohne static, die zu einem Objekt gehört (einer Klasseninstanz) public String toString() { return "Student " + this.name; } System.out.println(charly.toString());
Klassenmethoden: - statische Methoden haben nur Zugriff auf statische Variablen (Instanzvariablen brauchen ein Objekt objekt.variablenname) - Klassenvariablen brauchen kein Objekt
Prozeduren & Funktionen Prozeduren: liefern keinen Rückgabewert Funktionen liefern einen Rückgabewert
Methodeneigenschaften 4 Eigenschaften 1. Unterprogramm 2. Über Methodenaufruf ausführbar 3. Können Parameter/Argumente übergeben bekommen 4. Können Rückgabewert zurückliefern
Bedeutung von Methoden 3 Bedeutungen 1. Strukturieren das Programm 2. Reduzieren den Programmieraufwand 3. Leichtere Anpassbarkeit von Programmen
Vorteile von Methoden 8 Vorteile von Methoden 1. Wiederverwendung von Code 2. Erleichtern das Testen des Programms 3. Jede Methode kann / sollte vor Gebrauch getestet werden 4. Können leichter geändert werden 5. Definierter Zugriff auf gekapselte Daten ist durch Methoden möglich (getter,setter) 6. Methoden unterstützen: Generalisierung, Vererbung, Kapselung, Polymorphie 7. Erleichtern Rekursion und damit Divide&Conquer und das Top-Down-Prinzip (schrittweise Verfeinerung) 8. Unterstützung des Paradigmas der modularen Programmierung
Zusammenfassungen von Methoden 6 Zusammenfassungen von Methoden 1. Zusammenfassung von Code unter einem Namen 2. Kann unter Verwendung von Parametern formuliert sein 3. Übergabe der Parameter ist Pass/Call-by-Value 4. Methoden -> Modularisierung: eigenständige Einheiten mit Teilaufgaben 5. Wiederverwendbarkeit: sollte nur eine einzelne, wohldefinierte Aufgabe haben 6. Wenn 5 nicht funktioniert, sollte man Methode in kleinere Stücke zerlegen
Divide & Conquer – Verfahren Divide: Problem in möglichst viel gleichgroße Teilprobleme derselben Art wie das Originalproblem aufspalten, die dann unabhängig gelöst werden Conquer: Die Lösung der Teilprobleme werden zu einer Lösung des Gesamtproblems zusammengefügt
Top-Down-Prinzip in der modularen Programmierung Gang und Gäbe - Bei jedem Entwurfsschritt wird festgelegt, was die Untermodule leisten sollen, nicht aber WIE sie es leisten sollen
Modulare Programmierung Modul in der Praxis wird als ein in sich zusammenhängender Baustein aufgefasst, der folgende Eigenschaften besitzen sollte: - Logisch oder funktional abgeschlossen - Information hiding: wie er arbeitet oder implementiert ist, braucht außen nicht bekannt zu sein - Klar definierte Schnittstellen nach außen - Überschaubar und leicht testbar - Sollte möglichst wenig andere Module verwenden
Softwaremodul abgeschlossene Programmeinheit aus - Konstanten, Variablen, Datentypen, Operationen die genau definierten Funktionen ausführen und bestimmte Eigenschaften besitzen
System ist modular, wenn Es aus abgrenzbaren Einheiten zusammengesetzt ist o Diese Einheiten einzeln ausgetauscht verändert oder hinzugefügt werden können o Ohne, dass andere Teile des Systems beeinflusst werden
Call-by-Value / Pass-by-Value - Die Parameter werden nicht verändert - Außer es ist eine Referenz  Veränderungen möglich
Methodensyntax Modifizierer Ergebnistyp Bezeichner (Formale Parameter){ Methoden-Rumpf Ausführungsende/Rückgabe des Wertes }
Sichtbarkeit und Verdecken von Variablen Innerhalb von Methoden verdecken lokale Variablen und formale Variablen (übergebene) die Klassenvariablen
Klassenmethode - static main: MeineKlasse.derenMethode(x);
Instanzmethode kein static main: MeineKlasse objName= new MeineKlasse(); objName.zuveränderndevariable=7;
Überladen - Variablen dürfen nicht denselben Namen haben - Methoden dürfen gleichen Namen haben, aber brauchen unterschiedliche Signatur - Unterscheidung der überladenen Methoden anhand der Signatur: o Name der Methode o Anzahl der Parameter o Datentyp der Parameter o Reihenfolge der Parameter - Es wird immer die spezifischste aufgerufen
Iteration - Problem wird durch die wiederholte Anwendung desgleichen Verfahrensschritt gelöst - Jeder Iterationsschritt liefert Ergebnisse, die im nächsten Schritt wiederverwendet werden - Abbruch, wenn die Abbruchbedingung erfüllt wird
Rekursion - Problem wird durch Zurückführen auf einfacheres Problem gelöst - greift auf sich selbst zurück - Wichtig: o Rekursionen müssen abbrechen o ein oder mehrere Fälle müssen gesondert behandelt werden - direkt: Im Rumpf der Methode m steht der Aufruf für Methode m - indirekt: Im Rumpf der Methode m steht der Aufruf für Methode a, in Methode a steht der Aufruf für Methode b; in Methode b steht der Aufruf für Methode m - Vorteil: elegant und kurz für viele Problemstellungen - Nachteil: Manchmal ineffizient (Fibonacci)
Fakultätsberechnung iterativ static long fak(long n){ long fa = 1; for (long i = 1; i<=n; i++){ fa = fa * i; return fa; }
Fakultätsberechnung rekursiv static long fak (long n){ if (n==0) return 1; else return n * fak(n-1); }
3 Motivationsgründe für OOP 1. Grafische Benutzeroberflächen: Bedarf vervielfacht sicht 2. Kosten für Wartung sind zu hoch; dauert zu lange -> 70% der Gesamtkosten entstehen durch die Softwarewartung 3. Softwarekrise: Imageschaden
Paradigmen = Denkmuster/Philosophie, wie ein Programm auf dem Rechner verfasst werden sollte • Funktionales Programmieren o Gofer, Lisp • Imperatives Programmieren o C, Pascal, Basic • Prozedurales Programmieren o Funktionalität realisieren o m(a)
Objektorientiertes Programmieren o a.m() o Java, C++ o Modell des Systems realisieren o Grundsatz: Spiegelt ein Teil der Welt wider; Objekte sollten daher abgebildet werden können o Klasse dient als Bauplan (abstrakter Datentyp) und repräsentiert Eigenschaften eines Objekts o Objekt einer Klasse erzeugen -> Instanziierung
4 Grundprinzipien 1. Abstraktion 2. Kapselung 3. Vererbung 4. Polymorphismus -> Entwicklungszeit sparen -> Fehlerquellen reduzieren
Abstraktion/Generalisierung: • Zusammenfassung von Klassen mit gleichen Merkmalen zu Oberklasse • ist-ein Säugetier Ziele: 1. Hierarchie mit verschiedenen Beziehungen, wie in der Realität -> Superklasse und Subklasse 2. Gemeinsame Eigenschaften einheitlich modellieren
Kapselung: • Daten und Methoden fest an ihr Objekt binden • Leichtere Umstrukturierung der Klasse • Trennung von Schnittstelle (nach außen sichtbare Methode) und interne Realisierung:  information hiding: Daten werden vor direkten Zugriffen geschützt o private, public, protected… o dennoch getter und setter
Vererbung • Weiterreichen von Eigenschaften an Subklassen (extends) • Ziele: 1. gemeinsame Eigenschaften einheitlich modellieren 2. viel Programmcode wiederverwenden • Wenn man nicht weiß, welchen Rückgabewert eine Oberklasse hat z.B. die Klasse Währung kann kein Geld zurückgeben und sie ist nicht konkretisiert wie € oder $ Übergang zum Polymorphismus -> abstrakt:
abstrakte Klassen o Definition einer Schnittstelle: Array eines Objekts der abstrakten Klasse ist füllbar mit den verschiedenen Subklassen o es werden keine Methoden ausformuliert { } ; -> Objekte daraus zu bilden ist daher nicht möglich erst in Subklasse wird durch Override die Methode mit Methodenrumpf überschrieben {};
Polymorphismus: • Individualisieren -> Override -> • Individuelle Ausprägung verschiedener Objektklassen unter der einheitlichen Schnittstelle der Superklasse • Mutterklasse: Währung; Kindklasse: USDollar • geht: Waehrung quarter = new USDollar(0.25); • Ziele: 1. Besonderheiten bei Subklassen berücksichtigen 2. einheitliche Schnittstellen erzeugen
Typumwandlung: wenn es sich bei einem übergegebenen Objekt um einen bestimmten Typ handelt, dann soll etwas gemacht werden public static void klaeff(Hund obj){ if(obj instanceof Bernhardiner){ Bernhardiner berni = (Bernhardiner) obj; berni.jaul(); <Klasse> Variablenname = (Klasse) Objektname;
Warum Typecast • Elementtyp einer Collection kann nicht spezifiziert werden • daher beim Zugriff immer Typecast zur Klasse • Dadurch überprüft Compiler, ob mit den Typen alles in Ordnung ist
Variablen überschreiben Polymorphismus gilt nicht für Variablen (Verdeckung ist möglich) Superklasse gewandelt = (Superklasse) sub; gewandelt = Objekt sub + Instanz Superklasse sout(gewandelt) = sub weil toString Methodenaufruf sout(gewandelt.name) = Super weil Variablenname
Klasse Object Object – Mutter aller Klassen • java.lang.Object • steht über allen Klassen  jede Klasse erbt automatisch z.B. toString-Methode, Hashtabelle
Interfaces implements • Warum? In Java kann nur von einer Klasse geerbt werden • Beispiel: Firmenvermögen = Bargeld + Immobilien + Aktien: Wertgegenstände haben unterschiedliche Eigenschaften daher schwer in einer allgemeinen Klasse zu definieren -> Alle Objekte, die das Interface implementieren können als Wertgegenstände aufgefasst werden • Unterschied zu abstrakten Klassen: Die Methoden im Interface müssen alle abstrakt sein (); • Mehrfachvererbung erlaubt
Hilfs-/Hüllklasse String 1. Alle Zeichenketten-Literale z.B. „abc“ sind Instanzen der Klasse String 2. Werte eines Strings sind konstant und können nicht mehr verändert werden 3. -> Änderung = neues Objekt
Verschiedene Möglichkeiten ein String zu erzeugen String s1 = "abc"; String s2 = new String("abc"); char[] a = {'a', 'b', 'c'); String s3 = new String(a); byte[ ] b= {97,98,99); String s4 = new String(b); String s5 = new String (s4);
5. Methoden der Klasse String: o Zugriff auf einzelne Zeichen der Zeichenkette indexOf(„n“); charAt(4); o Vergleich von Zeichenketten compareTo; equals o Suchen von Teil-Zeichenketten substring(3); (ab dem 3. Buchstaben) o Herausgreifen von Teil-Zeichenketten replace(‚e‘,‘E‘); o Wandeln von Groß- in Kleinbuchstaben und umgekehrt toLowerCase(); toUpperCase(); o Aneinanderhängen mehrerer Strings +
StringBuffer (veränderbare Zeichenketten) • StringBuffer x = new StringBuffer(); • x = new StringBuffer(“start“).append(“s“).insert(4,“le“); o start + s = starts o 4. Stelle le einfügen star__ts • x = „starlets“
Hüllklassen(wrapper classes) • Listen sind z.B. nicht für primitive Datentypen erlaubt, daher verwende ich die Klasse davon: Integer, Float … und muss davon ein neues Objekt erstellen o Integer x = new Integer(10); // Einpacken o x.intValue();  10 (int) // Auspacken
Hüllklassen(wrapper classes) Methoden • Double valueOf(String s){…}: String -> Double-Objekt • double doubleValue() {…}: Double-Objekt-> double-Wert • double parseDouble (String s) {…}: String -> double-Wert • double x = Double.valueOf(„12.345“).doubleValue(); entspricht • double x =Double.parseDouble(„12.345“);
C++ Klassen Klassen: • können verwendet werden • Methoden können auch außerhalb einer Klasse auftreten
C++ Vorwärtsdeklaration: • man kann keine Variable aufrufen, die zuvor nicht deklariert worden ist  zyklische Aufrufe sind unmöglich -> Methodenordnung ist schwierig • Lösung: Header-Datei pro Klasse zum Deklarieren der Variablen
C++ Header-Dateien Header-Dateien (.h) enthalten: • Deklarationen von Funktion, Datenstrukturen und Klassen • Attributen und Methoden • private / public Modifizierer können für ganze Blöcke verwendet werden
C++ Source-Dateien Source-Dateien (.cpp) • Implementierung der Methoden • Können auf Variablen des Headers zugreifen • :: zeigt Zugehörigkeit zur Klasse
C++ Objekte: Objekte: • können direkt deklariert und angesprochen werden • Objekte werden wie einfache Datentypen behandelt • Variablen von Objekten sind keine Referenzen oder Pointer, sondern wirklich das Objekt selbst • Ansprechen durch Punktnotation • -> Wenn man einen Pointer auf ein Objekt oder struct hat • ptr -> y == (*ptr).y;
C++ Speicherverwaltung • Stack: o Objekt-Deklaration o Objekte sind nur für Code-Block instanziiert • Heap: o Allokation mit malloc() und free() • new: o Allokiert Speicher o führt Konstruktor aus o liefert Pointer zurück • delete: o Deallokiert Speicher des Objekts o führt Destruktor aus o räumt Speicher im Heap auf
Enumeration • gewisse Menge an aufgelisteten KONSTANTEN Werten • Klassentyp • Jeder deklarierte Wert ist eine eigene Instanz der enum-Klasse o public, static, final • Vergleich durch equals und == • Enums sind sortierbar
Enum Vorteile 1. Liefert Typsicherheit zur Compile-Zeit 2. Lesbare Namen für ihre Zustände 3. Robust (hinzufügen etc. von Konstanten erfordert Rekompilierung) 4. Können zu Collections hinzugefügt werden, weil es Objekte sind 5. Können auch Attribute und Methoden enthalten, weil es Klassen sind
Enum Methoden • String toString() o gibt Name des Enum-Objektes als Konstante zurück • boolean equals (Object other) o vergleicht die enum-Konstanten • int compareTo (E o) o Ordnung zum sortieren -1, 0, 1 • static enum-type valueOf (String s) o gibt das Enum Objekt mit dem Namen s zurück • static enum-type[] values() o gibt ein Array der Enum-Objekte zurück
Array Eigenschaften o Eigenschaften: • Lineare Folge fester Größe • length-Attribut • enthält primitive Datentypen oder Referenzen auf Objekte • Nur Objekte eines Typs
Array Vorteile • sehr effizient • Typüberprüfung zur Compile-Zeit
Array Nachteile • Feste Größe • Nur ein Typ • Wenig Methoden Wegen der Nachteile gibt es Container
Was sind Container? = Objekt, das eine Sammlung von Referenzen auf andere Objekte enthält
Zwei Konzepte von Containern • Collection Interface o Enthält einzelne Objekte o ( Set, ArrayList, LinkedList) o Die Verwendung generischer Interfaces erleichtert den Austausch von z.B. ArrayList zu LinkedList • Map: Interface o Schlüssel-Wert Paare o Ein Schlüssel darf nur einmal vorkommen o HashMap, HashTable
Container Eigenschaften 1. Können Verschiedene Typen beinhalten 2. Keine feste Größe -> automatische Größenanpassung 3. Enthalten nur Referenzen auf Objekte 4. Keine primitiven Typen
Container Methoden • add (Object o) • remove (int index) • size() • get(int index) • put(Object key, Object value) //Map
Iteratoren: • besser als get, da eine get Iteration immer von vorne anfängt • boolean hasNext() • Object next() Iterator e = songs.iterator(); return ((Song) e.next()),toString();
Iteratoren Nachteile • Weniger effizient als Arrays • manuelle Typumwandlung notwendig, da keine Typüberprüfung
Generics Generische Programmierung = Programmierung von Klassen und Methoden mit parametrisierten Typen • Werkzeug zur Erstellung wiederverwendbarer objektorientierter Typen und Bibliotheken • Generische Methoden können in normalen und generischen Klassen definiert werden • beim Aufruf kann der Typ spezifiziert werden
Vorteile Generics • Mehr Sicherheit und Lesbarkeit • Keine sichtbaren Typecasts • für allgemeine Datenstrukturen nützlich • Frühe Compile-Zeit Erkennung von Typverletzung (Kein String einfügen in ArrayList<Song>)
Dokumentation • Code ist für den Menschen geschrieben, daher sollte man ihn auch nach längerer Zeit noch verstehen • javadoc: Code und Dokumentation in einer Datei • @param, @return erzeugt HTML Dokumentation
Compilerfehler: o z.B. System.outprint Punkt vergessen  Fehlermeldung + Interpretieren nicht möglich o ausführen ist nicht möglich, man merkt aber schnell, wenn etwas falsch ist
Exceptions • Exception = Ausnahmesituation • hilft beim Verstehen von Problemen, statt es nur abstürzen zu lassen • Abfangen (catching) einer Exception durch try and catch • Beim Abfangen auf Hierarchie achten
Exceptions Hierarchie 1. Throwable 2. Exception + Error 3. RuntimeException 4. NullPointerException
Skriptsprachen • Python • Keine Kompilierung • Nur Zeile für Zeile interpretieren • Sobald ein Fehler auftaucht, wird an dieser Stelle abgebrochen
Iterator – Erweiterung • kann auch durch Doppelpunktnotation ersetzt werden • for each: Für jeden String song aus songs for (String song:songs)
Programmierparadigmen - Imperativ - Deklarativ - Prozedural - Objektorientiert - Ereignisorientiert - Logisch - Funktional
Imperativ 1. Abfolge von Befehlen, die Computer in Reihenfolge auszuführen hat 2. Compiler übersetzt Befehle in Maschinenbefehle o vergleichbar mit Möbelbau-Anleitung o Sprachen: Java, C, Assembler
Deklarativ 1. Nicht der Weg zum Ziel, sondern WAS? ist das Ziel 2. Menge von Definitionen, Relationen und Regeln 3. Befehle sind aus Relationen und Regeln extrahierbar o Vergleichbar mit mathematischen
Prozedurale Programmierung Imperative Programmiersprachen beinhalten prozeduralen Ansatz 1. Anweisungsfolgen in Teilfolgen (Prozeduren) zerlegen 2. Prozeduren sind nach Außen durch Schnittstellen definiert 3. Prozeduren können sich untereinander aufrufen o z.B.: Fortan, C, COBOL
Objektorientierte Programmierung 1. Objekte instanziieren Objekt-Templates (Klassen) 2. Objekte haben Eigenschaften (Attribute) und können Aktionen (Methoden) ausführen 3. Objekte zur Modularisierung vom Code 4. Methoden oft nach prozeduralen Paradigmen definiert o Java, C#, C++
Ereignisorientierte Programmierung 1. kein linearer Vorgang (parallel) 2. Ereignisbehandlungsroutinen werden ausgeführt, wenn ein bestimmtes Ereignis auftritt 3. Routinen können andere Ereignisse auslösen o gut mit objektorientierten Sprachen vereinbar o Typische Anwendung bei GUI-Programmierung o Sprachen: Visual Basic, Pascal
Logische Programmierung 1. beruht auf mathematischer Logik 2. Statt Anweisungsfolgen, Menge von Axiomen 3. Lösung wird aus Fakten und Regeln hergeleitet o deklarative Programmiersprache o Was gilt, nicht wie o Sprache: Prolog
Funktionale Programmierung 1. deklarativ: ausschließlich mathematische Funktionen 2. besteht aus Funktionsaufrufen 3. Verbietet: Variablen, Schleifen, Objekte, Anweisungsfolgen 4. Rekursion ist wichtig o Künstliche Intelligenz o Sprachen: Haskell, Erlang, Scala
C Ein Student mit id Und name (vor- + nachname) struct student{ int id; struct{char vorname [20]; char nachname[20]; } name; };
C Stundent mit id oder name (vor- + nachname) union student { int id; struct{ char vorname [20]; char nachname [20]; } name; };