Programmierung 1 Studiengang MI / WI
Dipl.-Inf., Dipl.-Ing. (FH) Michael Wilhelm
Hochschule Harz
FB Automatisierung und Informatik
mwilhelm@hs-harz.de
http://mwilhelm.hs-harz.de
Raum 2.202
Tel. 03943 / 659 338
Inhalt der Vorlesung
Überblick:
•
Erste Beispiele, Interaktion
•
elementare Datentypen
•
Variablen und Kontrollstrukturen
•
Arrays und Funktionen
•
Objekte und Methoden
•
Algorithmen und Pseudocode
•
Laufzeitverhalten
•
Simulation
•
Bibliotheken
• Folien basierend auf Daniel Schiffman “Learning Processing” und Donald W. Smith
Grundlegende Algorithmen und Methoden:
•
Suchen und Sortieren
•
Hashing
•
Rekursion
•
Graphen
•
Dynamische
Programmierung
Von Processing zu Java
Kapitel
Objekte
•
Attribute
•
Methoden
•
Überschreiben
•
Überladen
Vererbung
• Polymorphie
Interface
Klassen und Objekte
Teil 1: vordefinierte Klassen und Bibliotheken Was ist ein Objekt?
•
basiert auf “Hauptwort/Substantiv” (ein Auto, ein Laden,...)
•
hat Eigenschaften (Attribute genannt).
•
hat Aktionen (Methoden) die ausgeführt werden können (Verben)
•
Objekte sind (selbst erstellte) Datentypen.
•
Diese Datentypen heißen Klassen.
•
Objekte werden immer mit “call by reference” übergeben
Aufruf der Methoden eines Objekts:
•
Erzeugen eines Objekts
•
objektname.methode( Parameter ):
Erzeugen einer Klasse:
•
class name {
•
…
•
}
Objekt objektname = new Objekt(<parameterliste>);
objektname.methode()
Konstruktor:
•
sorgt dafür, dass Objektattributen Anfangswerte zugewiesen werden.
Konstruktor
Beispiel: String in Processing/Java eingebaute Klasse:
•
enthält als Attribut eine Zeichenfolge fester Länge.
•
verfügbare Methoden zur Manipulation der Zeichenfolge:
Methode Aktion
charAt() gibt das Zeichen am angegebenen Index zurück equals() vergleicht den String zum übergegebenen Objekt
indexOf() gibt den Index des ersten Auftretens des übergebenen Zeichens
length() gibt die Anzahl der Zeichen im String zurück
substring() gibt neuen String zurück, der Teil des Eingabestrings ist toLowerCase() wandelt alle Zeichen in Kleinbuchstaben
toUpperCase() wandelt alle Zeichen in Großbuchstaben
Objektorientierte Programmierung:
•
Daten und Aktionen werden zusammen in einem
•
“Objekt” als Attribute und Methoden zusammengeführt.
Objektbeispiel: Mensch
Attribute Methoden
Alter Schlafen
Größe Aufwachen
Gewicht Essen
Name Arbeiten
… …
Klassen und Objekte
Klasse:
•
Eine Blaupause/Konstruktionsplan für ein Objekt.
•
Die allgemeine Idee hinter einem Ding
•
Hat Platzhalter für die Details (Attribute)
•
Deklariert Funktionen/Methoden, die auf ein Objekt angewandt werden können.
Objekt:
•
Ein Objekt ist eine Instanz einer Klasse.
•
Das “echte” Ding mit all seinen Eigenschaften
•
Seine Methoden können aufgerufen werden
•
Jedes Objekt kennt die Klasse von der es konstruiert wurde.
•
Man muss einen Plan haben, bevor man ein Objekt erzeugen
kann: Klasse kommt vor dem Objekt
Klassen und Objekte
Instanzierung
•
Die Erzeugung eines Objekts mittels des in der Klasse
beschriebenen Konstruktionsplanes heißt Instanzierung der Klasse.
•
Entsprechend handelt es sich bei dem Objekt um eine Instanz der Klasse.
Definition:
class CName {
public Cname() { }
public methode1() {
Benutzung:
CName cobj;
cobj = new CName();
cobj.Methode1();
Klasse: einfaches Autos
Objektbeispiel: Auto
Attribute Methoden
farbe Fahren
position Lenken geschwindigkeit Parken
kfzKennzeichen Big Mac holen
… …
Sinnvolle Nomenklatur
•
Klassennamen werden am Anfang groß geschrieben
•
Variablennamen werden am Anfang klein geschrieben
•
Methodennamen werden am Anfang klein geschrieben
class Auto { // Attribute color farbe;
float x;
float y;
float vX;
float vY
// Methoden
void fahren() { x += vx;
y += vy;
}
// Methoden
void lenken(float winkel) { float w = radians(winkel);
float u = vX;
float v = vY;
vX = u*cos(w) - v*sin(w);
vY = v*cos(w) + u*sin(w);
}
} // class Auto
Klassen und Objekte
•
Konvention:
•
Klassennamen beginnen immer mit einem Großbuchstaben
•
Methoden folgen den Namenskonventionen von Funktionen
•
Klassen sind nutzerdefinierte Datentypen.
•
In Processing sollten Klassen in einem separatem Tab/eigenem Editorfenster deklariert werden.
•
In Java werden Klassen in einer eigenen Datei deklariert, wobei der Dateiname mit dem Klassennamen
übereinstimmen muss.
•
Dann muss die Klasse als „public“ definiert werden
•
Alternativ kann man alles in einer Datei schreiben
Signatur von Methoden
•
Die Signatur einer Methode besteht aus dem Methodennamen und den Datentypen der Parameter in der gegebenen
Reihenfolge.
•
Der Rückgabewert einer Methode ist nicht Teil der Signatur.
•
Methoden in einer Klasse müssen sich durch ihre Signatur unterscheiden.
•
Das heisst, solange die Parameterzahl oder Parametertypen unterschiedlich sind, können Methoden denselben Namen haben.
•
Solche Methoden heißen überladen.
class A {
float methode() { .... }
float methode(int i) { .... }
Welche Methoden haben keine unterschiedliche Signatur?
class A {
1 int calc(int i) { ... }
2
float calc(int i) { ... } 3 float calc(float f) { ... }
4 int calc(int i, int j) { ... }
5
int calc(int i, int k) { ... } 6 int calc(int i, float f) { ... } 7 int calc(float f, int i) { ... }
}
?
?
?
Welche Methoden haben keine unterschiedliche Signatur?
class A {
1 int calc(int i) { ... }
2
float calc(int i) { ... } 3 float calc(float f) { ... }
4 int calc(int i, int j) { ... }
5
int calc(int i, int k) { ... } 6 int calc(int i, float f) { ... } 7 int calc(float f, int i) { ... }
unterschiedlich,
Fehler
Fehler
Konstruktoren
•
Die Aufgabe eines Konstruktors ist es, die Attribute des Objekts mit (sinnvollen) Werten zu initialisieren.
•
Konstruktoren sind Methoden mit dem Namen der Klasse. Sie
können überladen werden, das heisst, es kann sie mehrfach geben.
Jedoch haben sie keinen Rückgabewert, auch nicht “void”.
class A { int i;
String s;
// default Constructor public A() {
i = 0;
s = "";
}
// 2. Constructor
public A(int i, String s){
this.i = i;
this.s = s;
}
} // class A
Konstruktoren
class A { int i;
String s;
// default Constructor
// Aufruf des 2. Construktors public A() {
this(0,"");
}
public A(int i, String s){
this.i = i;
this.s = s;
Konstruktoren
class A { int i;
String s;
// default Constructor
// Aufruf des 2. Construktor public A(int i, String s){
this.i = i;
this.s = s;
}
// Copy-Konstruktor public A(A a){
this.i = a.i;
this.s = a.s;
•
prog1
Instanzierung und Konstruktoren
•
A a1 = new A(); // default Constructor
•
A a2 = new A(a1); // copy Constructor
•
Das Schlüsselwort this:
•
this steht innerhalb der Methoden einer Klasse für eine Referenz auf die aktuelle Instanz des aktuellen Objekts.
public A(A a){
this.i = a.i;
this.s = a.s;
Klassenattribute
•
Es kommt vor, dass Attribute für alle Instanzen einer Klasse denselben Wert besitzen.
•
Dann ist es unnötig in jeder Instanz eine Kopie dieses Attributs zu haben.
•
Stattdessen möchte man diesen Wert direkt in der Klassendefinition speichern.
•
Dies geschieht mit dem Schlüsselwort static.
class A {
static int anzahlInstanzen = 0;
public A() {
anzahlInstanzen++;
....
}
Klassenmethoden
•
Analog kommt vor, dass Methoden sich nicht auf die Attributwerte einer Instanz beziehen.
•
Solche Methoden werden unabhängig von Instanzen über den Klassennamen aufgerufen. Sie werden mit dem Schlüsselwort static deklariert.
•
Häufig dienen diese dazu, Klassen mit „Basisfunktionalität“
auszustatten
•
statische Methoden dürfen nicht auf dynamische bzw.
allgemeine Variablen zugreifen.
•
Jede statische Methode ist für sich komplett separat.
•
Sie kann aber andere statische Methoden aufrufen.
class A {
// 3*x*x + 4*x + 2 = ((3*x + 4)*x + 2)
static float polynomKoeff = { 3.0f, 4.0f, 2.0f };
static float polynom(float x) { // Horner Schema float y = polynomKoeff[0];
for(int i=1; i<polynomKoeff.length; i++) { y = y*x + polynomKoeff[i];
}
return y;
} // polynom }
Aufruf:
float u = A.polynom(2.0f); // Klassenname !
Klassenmethoden
Finden Sie die Fehler:
class A {
static float z = 3.5f;
float x;
public void A(float x) { this.x = x;
}
public static func(float t) { return x * t + z;
}
} // class A Aufruf:
A a = new A();
class A {
static float z = 3.5f;
float x;
public void A(float x) { this.x = x;
}
public static func(float t) { return x * t + z;
}
} // class A Aufruf:
A a = new A();
float x =
a.func(0.3f) + A.z + A.x;
Konstruktor mit Rückgabetyp fehlender Rückgabetyp „float“
Bezug auf Attribut x in Klassenmethode
default Konstruktor nicht definiert
x ist kein Klassenattribut
Objektorientierte Programmierung und das Prinzip vom Verstecken der Information
•
Die Attribute einer Instanz beschreiben den inneren Zustand des Objektes.
•
Es ist vorteilhaft, diesen als “Black Box” anzusehen. Die
Veränderung des Objektzustandes erfolgt nur über eine (vom Programmierer) wohl definierte Schnittstelle, welche durch Methoden/Operationen implementiert wird.
•
In Java stehen hierfür die Schlüsselworte public, protected und private zur Verfügung. Sie erlauben den Zugriff von außerhalb einer Klasse auf Attribute und Methoden zu verhindern (private) oder zu erlauben (public).
Achtung: in Processing haben diese Schlüsselworte häufig keinen
Effekt. Hier dienen sie eher als Erinnerung an den Programmierer,
class A {
private int anzahl;
....
public A() { anzahl = 0;
}
public void setAnzahl(int n) { anzahl = n;
}
public int getAnzahl() { return anzahl;
}
} // class A
get- und set-Methoden
•
Methoden zum Lesen und Schreiben von Attributen heißen getter/setter Methoden. Ihre Namen folgen den Konventionen für Funktionen, wobei der erste Namensteil entweder set oder get ist, der zweite Namensteil ist der Name des Attributs.
•
In Eclipse kann man das automatisch generieren lassen
•
Das Attribut auf „private“ setzen.
•
Mit der Maus über das Attribut gehen.
•
Eintrag „Create getter and setter for 'alter' “ auswählen.
get- und set-Methoden
Allgemeine Anforderungen an zukünftige Abgaben:
•
Jede Datei enthält einen Kommentar-Header. Dieser enthält das Datum der
Erstellung, den Namen des Autors und die u-Nummer. Ebenso ist dort der Zweck der Datei zu dokumentieren.
•
Quellcode ist zu dokumentieren. Auf Lesbarkeit des Kodes ist zu achten (Einrückungen).
•
Der Programmierstil sollte den üblichen Konventionen folgen.
•
Ein gewählter Stil sollte konsistent eingehalten werden.
•
Insbesondere steht vor jeder Funktion/Methode (und Klasse) ein Kommentarblock
•
mit folgendem Inhalt:
•
Zweck der Funktion/Methode (bzw. Klasse)
•
Liste der Namen und des Zwecks der Parameter
•
Bedeutung des Rückgabewertes
•
Nebeneffekte der Funktion (z.B. verändert Inhalte übergebener Referenzparameter, gibt Werte auf die Konsole aus, etc.)
•
Beachten Sie: Kode wird nicht für den Compiler, sondern für einen
menschlichen Leser geschrieben.
Zusammenfassung
Problemlösungen:
•
iteratives Vorgehen mit fortlaufender Verbesserung der Lösung.
•
Barriere muss durch lernen bzw. finden einer geeigneten gedanklichen Darstellung überwunden werden.
•
Bsp: „Game of live“, Ameise
•
Objekte und Klassen: Vorerst vorgefertigt in Processing
•
Klassen haben mindestens einen Konstruktor
•
Klassen, Objekte haben Attribute und Methoden.
•
Bsp: String, PImage
•
Umgang mit Arrays:
•
Beispiele: direkte Manipulation der Pixel eines Bildes,
•
Bildverarbeitung, Filter (Kantenverstärkung, etc.)
Aufzählungen, enum
•
In der Programmierung tritt häufig der Fall auf, dass ein Attribut nur eine kleine Menge fester Werte annehmen kann. Diese
bezeichnet man als Aufzählungen.
•
In den meisten Programmiersprachen sind Aufzählungen ein durch den Programmierer definierter Datentyp mit durch
benannte Konstanten gegebenen Werten.
•
BREITE=100 HOEHE=100
•
In Java sind Aufzählungen „spezielle Klassen“.
•
Aufzählungen sind ein Ersatz für Konstanten
Processing kann mit Aufzählungen zwar umgehen, diese müssen jedoch in einem eigenen Tab oder einer eigenen Datei explizit mit
der Endung java definiert werden.
Beispiele für Aufzählungen, enum
Datei Jahreszeit.java enum Jahreszeit {
FRUEHLING, SOMMER, HERBST, WINTER }
Jahreszeit jzeit = Jahreszeit.SOMMER;
println("dieses Jahr war ein heisser "+jzeit);
Vorteil:
•
Gegenüber Konstanten hat man hier eine geschlossene Gruppe.
•
Mit der Funktion „ordinal“ erhält man den internen numerischen
Wert.
Beispiele für Aufzählungen, enum
Datei Jahreszeit.java enum Jahreszeit {
FRUEHLING, SOMMER, HERBST, WINTER }
Jahreszeit[] alleEnums = Jahreszeit.values();
for(int i=0; i<alleEnums.length; i++) { if(alleEnums[i] == Jahreszeit.SOMMER) {
println("heisser ");
}
println(alleEnums[i]);
}
Ausgabe:
•
FRUEHLING
•
heisser SOMMER HERBST
•