Montag, 23. November 2015

 

OOP in Java, Beispiel Geld/Währungstabelle (POS1: 2CHIF)

Laut Wikipedia kann Objektorientierte Programmierung definiert werden als:

Die objektorientierte Programmierung (kurz OOP) ist ein auf dem Konzept der Objektorientierung basierendes Programmierparadigma. Die Grundidee besteht darin, die Architektur einer Software an den Grundstrukturen desjenigen Bereichs der Wirklichkeit auszurichten, der die gegebene Anwendung betrifft. Ein Modell dieser Strukturen wird in der Entwurfsphase aufgestellt. Es enthält Informationen über die auftretenden Objekte und deren Abstraktionen, ihre Typen. Die Umsetzung dieser Denkweise erfordert die Einführung verschiedener Konzepte, insbesondere Klassen, Vererbung, Polymorphie und spätes Binden.

Alan Kay, der Erfinder der Programmiersprache Smalltalk und des Begriffs „object oriented“, definierte ihn im Kontext von Smalltalk folgendermaßen:

1. Everything is an object, 2. Objects communicate by sending and receiving messages (in terms of objects), 3. Objects have their own memory (in terms of objects), 4. Every object is an instance of a class (which must be an object), 5. The class holds the shared behavior for its instances (in the form of objects in a program list), 6. To eval a program list, control is passed to the first object and the remainder is treated as its message

„1. Alles ist ein Objekt, 2. Objekte kommunizieren durch das Senden und Empfangen von Nachrichten (welche aus Objekten bestehen), 3. Objekte haben ihren eigenen Speicher (strukturiert als Objekte), 4. Jedes Objekt ist Instanz einer Klasse (welche ein Objekt sein muss), 5. Die Klasse beinhaltet das Verhalten aller ihrer Instanzen (in der Form von Objekten in einer Programmliste), 6. Um eine Programmliste auszuführen, wird die Ausführungskontrolle dem ersten Objekt gegeben und das Verbleibende als dessen Nachricht behandelt“
– Alan Kay: The Early History of Smalltalk (1993)

Beispielanwendung

Anhand des folgenden Beispiels soll ein kurzer Einblick in die Objektorientierte Programmierung gegeben werden.

Es soll Geld implementiert werden. Da es in verschiedenen Ländern unterschiedliche Währungen gibt, muss unsere Klasse neben dem Betrag auch die Währung beinhalten. Um rechnen zu können wird noch eine Währungstabelle mitgespeichert.

Die Währungstabelle wechselkurs könnte natürlich auch wieder in eigenen Klassen/Objekten realisiert werden (im Java-Code ist das auch tatsächlich der Fall).

Die Attribute (Eigenschaften) sind alle öffentlich (public), da damit das Beispiel kürzer wird. Tatsächlich werden normalerweise die Attribute nach außen unsichtbar gemacht (private) und nur Methoden (Methoden-Aufrufe entsprechen Alan Kays "Nachrichten") öffentlich gemacht, um den Zugriff auf das Innere der Objekte zu verhinden (Information Hiding oder Datenkapselung).

Die Methode getEuro() liefert den auf Euro umgerechneten Geldbetrag.
Die Methode add(geld) addiert den Wert des Parameters geld zum Wert des aktuellen Objekts und erzeugt ein neues Objekt mit der Summe und liefert es als Returnwert zurück.

Der Konstruktor wird in diesem Klassendiagramm nicht angegeben. Durch ihn wird aber die Währung der Betrag festgelegt. Der Konstruktor wird ausgeführt, wenn ein Objekt erzeugt wird.

Die Umsetzung in Java:

In Java heißt die Referenz auf das aktuelle Objekt this. this wird nicht als Parameter deklariert (anders als in Python). Den Methoden fehlt ein this-Parameter (bzw. self in Python). Dieser Parameter existiert nur intern.
Dennoch kann man this beim Zugriff auf Attribute (und Methoden) angeben. Im folgenden Beispiel wird das auch gemacht.

Man muss this nur dann angeben, wenn es sonst zu Mehrdeutigkeiten käme (in unserem Beispiel beim Konstruktor, bi dem die Parameter genauso benannt sind wie die Attribute).

Der Kunstruktor heißt in Java immer so wie die Klasse, in unserem Fall Geld().

Die Währungstabelle wechselkurs wird als Array einer eigenen Klasse Wechselkurs realisiert. Zusätzlich benötigt man mangels Dictionary eine Methode, die zu einer gegebenen Währung den Kurs liefert: getKurs()

class Geld {
    final class Wechselkurs { // final nur für's scrapbook
        String waehrung;
        double kurs;

        public Wechselkurs(String waehrung, double kurs) {
            this.waehrung = waehrung;
            this.kurs = kurs;
        }
    }

    private Wechselkurs[] wechselkurs = { 
        new Wechselkurs("USD", 1.505),  // US-$ (1EUR sind 
                                        // 1.505 USD)
        new Wechselkurs("GBP", 0.908),  // Britische Pfund
        new Wechselkurs("EUR", 1.0),  
        new Wechselkurs("CHF", 1.509),  // Schweizer Franken
        new Wechselkurs("JPY", 130.582),// Japanische Yen
    };

    String waehrung;
    double betrag;

    public Geld(String waehrung, double betrag) {
       this.waehrung = waehrung;
       this.betrag = betrag;
    }

    public double getEuro() {
       return this.betrag / this.getKurs();
    }

    private double getKurs() {
        for (Wechselkurs kurs : this.wechselkurs) {
            if (kurs.waehrung.equals(this.waehrung)) {
                return kurs.kurs;
            }
        }
        return 0.0;
    }

    public Geld add(Geld geld) {
        double summeInEuro = this.getEuro() + geld.getEuro();
        Geld summe = new Geld(this.waehrung, 
                              summeInEuro * this.getKurs());
        return summe;
    }
}

/*** Testaufrufe ***/
Geld hotelrechnung = new Geld("EUR", 560);
Geld mietwagen = new Geld("USD", 760);
Geld summe = mietwagen.add(hotelrechnung);
System.out.printf("Summe: %s%.2f, %s%.2f\n", summe.waehrung, 
    summe.betrag, "EUR", summe.getEuro());

Testausgabe:

Summe: USD1602,80, EUR1064,98

Scrapbook oop.jpage zum Download.

Labels: , ,


 

Java Arrays

Folgendes Beispiel zeigt ein zweidimensionales Array, bei dem die zweite Dimension für jede Zeile unterschiedlich lang ist. In der Animation ist sichtbar, wie dieses Array von Arrays im Speicher organisiert ist.

hier finden Sie die Animation direkt am Python-Tutor.

Labels: ,


Dienstag, 17. November 2015

 

Java-for Schleife wie in Python

Python arbeitet mit Sequenzen. Manchmal ist es praktisch, wenn man eine Sequenz direkt bei der for-Schleife hin schreiben kann. Ein Beispiel:
for i in [1, 3, 2, 5, 10, -3]:
    print(i, end=" ")
print()
In Java ist das ganz ähnlich möglich. Hier ein zwei Varianten:
class T {
    // helper method
    public static int[] list(int... values) {
        return values;
    }
    public static void main(String[] args) {
        // use helper to generate array
        for (int i : list(1, 3, 2, 5, 10, -3)) {
            System.out.printf("%d ", i);
        }
        System.out.println();

        // use locally defined array
        for (int i : new int[] { 1, 3, 2, 5, 10, -3 }) {
            System.out.printf("%d ", i);
        }
        System.out.println();
    }
}
Die Ausgabe sind dann die Zahlen in der Liste:
1 3 2 5 10 -3 
1 3 2 5 10 -3 

Die Hilfsmethode helper() nützt das Java-Feature der variablen Parameterliste, die dann in eine Sequenz (Array) umgewandelt wird.

Die zweite Variante verwendet die Initialisierung von Arrays.

Auch mit beliebigen Objekten ist das Prinzip machbar:

for o in [1, "a", 23.3, "hallo", 3]:
    print(o, end=" ")
print()
public class ListsInForLoop {
    // helper
    public static Object[] olist(Object... objects) {
        return objects;
    }

    public static void main(String[] args) {
        // different kinds of Objects
        for (Object o : olist(1, "a", 23.3, "hallo", 3)) {
            System.out.print(o);
            System.out.print(" ");
        }
        System.out.println();

        // use locally defined Object array
        for (Object o : new Object[] { 1, "a", 23.3, "hallo", 3 }) {
            System.out.print(o);
            System.out.print(" ");
        }
        System.out.println();
    }

}
Die Ausgabe ist dann so:
1 a 23.3 hallo 3 
1 a 23.3 hallo 3

Labels:


Dienstag, 10. November 2015

 

Aufgabe Java Wurzelberechnung (POS1: 2CHIF)

Man kann die Wurzel einer Zahl berechnen mit folgender Formel

xn = (xn-1 + a / xn-1) / 2

Man beginnt damit, dass a und x0 gleich der Zahl, aus der man die Wurzel ziehen will, setzt und x1 berechnet. Dann berechnet man x2 usw. bis sich die beiden letzten Werte nur mehr gering unterscheiden (z.B. die Differenz kleiner 0,0000001 ist).

Schreiben Sie eine Methode (Funktion) wurzel(zahl, genauigkeit), welche nach obigem Verfahren die Wurzel berechnet.

Erstellen Sie eine Klasse SquareRoot.java, welche eine Tabelle der Wurzeln der Zahlen 1 bis 20 bei den Genauigkeiten 0.01, 0.0001 sowie 0.0000001 ausgibt:
 1:  1.0000000  1.0000000  1.0000000
 2:  1.4142157  1.4142136  1.4142136
 3:  1.7320508  1.7320508  1.7320508
 4:  2.0000001  2.0000000  2.0000000
 5:  2.2360689  2.2360680  2.2360680
 6:  2.4494944  2.4494897  2.4494897
 7:  2.6457670  2.6457513  2.6457513
 8:  2.8284271  2.8284271  2.8284271
 9:  3.0000000  3.0000000  3.0000000
10:  3.1622777  3.1622777  3.1622777
11:  3.3166248  3.3166248  3.3166248
12:  3.4641017  3.4641016  3.4641016
13:  3.6055514  3.6055513  3.6055513
14:  3.7416576  3.7416574  3.7416574
15:  3.8729837  3.8729833  3.8729833
16:  4.0000006  4.0000000  4.0000000
17:  4.1231067  4.1231056  4.1231056
18:  4.2426425  4.2426407  4.2426407
19:  4.3589018  4.3588989  4.3588989
20:  4.4721402  4.4721360  4.4721360

Stellen Sie fest, wie viele Iterationen benötigt werden. Wie kann man die Anzahl der Iterationen bestimmen, ohne die Parameter bzw. den Returntyp bzw. -wert von wurzel(zahl, genauigkeit) zu ändern?

Labels: , ,


 

Aufgaben zu Java (POS1: 2CHIF)


  1. Schreiben Sie ein einfaches Java Programm, welches "Hello World" ausgibt. Nennen Sie das Programm Hello.java. Verwenden Sie dazu einen Texteditor und übersetzen Sie das Programm auf der Kommandozeile.
  2. Schreiben Sie ein einfaches Java-Programm, welches das kleine Einmaleins ausgibt. Welchen Namen könnte das Programm haben?
     X  1  2  3  4  5  6  7  8  9 10
     1  1  2  3  4  5  6  7  8  9 10 
     2  2  4  6  8 10 12 14 16 18 20 
     3  3  6  9 12 15 18 21 24 27 30 
     4  4  8 12 16 20 24 28 32 36 40 
     5  5 10 15 20 25 30 35 40 45 50 
     6  6 12 18 24 30 36 42 48 54 60 
     7  7 14 21 28 35 42 49 56 63 70 
     8  8 16 24 32 40 48 56 64 72 80 
     9  9 18 27 36 45 54 63 72 81 90 
    10 10 20 30 40 50 60 70 80 90 100
    

    Verwenden Sie wieder einen Texteditor und den Java-Compiler auf der Kommandozeile.
  3. Erstellen Sie mit eclipse ein Java-Projekt java-intro. Erzeugen Sie ein package intro1 ("intro eins").
    Erstellen Sie in diesem Paket die beiden Klassen von oben (in das Projekt-Verzeichnis kopieren und an das package anpassen). Starten Sie die beiden Klassen von eclipse aus.
  4. Starten Sie die beiden Klassen von der Kommandozeile aus. Wo sind die Class files zu finden, wie sieht der Aufruf aus?
  5. Erstellen Sie im package intro1 eine Klasse Schleife, die (im main) eine Zahl einliest und dann alle Zahlen von 1 bis zu der gegebenen Zahl ausgibt. Beispielaufruf:
    Grenze ? 10
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
  6. Erweitern Sie die Klasse Schleife so, dass zwei Zahlen eingegeben werden. Es sollen dann die Zahlen von der ersten bis zur zweiten ausgegeben werden. Wenn die zweite Zahl kleiner ist, dann soll eine absteigende Folge ausgegeben werden. Beispielaufruf:
    von? 15
    bis? 10
    15
    14
    13
    12
    11
    10
    

Labels: , ,


 

eclipse einrichten (POS1: 2CHIF)

Machen Sie sich mit der Entwicklungsumgebung eclipse vertraut!
  1. Richten Sie den "Formatter" ein, sodass nur Leerzeichen für die Einrückung verwendet werden:
  2. Richten Sie sich ein File-Template mit einem Header nach unseren Programmierrichtlinien ein:
  3. Richten Sie sich ein Code-Template mit einem Header für Klassen nach unseren Programmierrichtlinien ein:

Labels: ,


This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]