Scala Tutorial für Java Programmierer
|
|
- Oswalda Ursler
- vor 6 Jahren
- Abrufe
Transkript
1 Scala Tutorial für Java Programmierer Version März 2011 Michel Schinz, Philipp Haller Übersetzung Ulrich Jordan PROGRAMMING METHODS LABORATORY EPFL SWITZERLAND
2 2 1 Einleitung Dieses Dokument ist eine kurze Vorstellung der Sprache Scala und des Scala-Compilers. Es ist für Leser gedacht, die schon Programmiererfahrung haben und die sich einen Überblick über Scala verschaffen wollen. Dabei werden Grundkenntnisse in objektorientierter Programmierung und speziell in Java vorausgesetzt. 2 Ein erstes Beispiel Als ein erstes Beispiel verwenden wir traditionsgemäß das Hello-World-Programm. Es ist nicht sehr faszinierend, demonstriert aber die Verwendung einiger Scala-Werkzeuge, ohne dass man viel über die Sprache wissen muss. Und so sieht es aus: object HelloWorld { def main(args: Array[String]) { println("hello, world!") Die Struktur dieses Programms wird jedem Java-Programmierer bekannt vorkommen. Das Programm besteht aus einer Methode namens main mit den Befehlszeilenargumenten in Form eines String Arrays als Parameter. Im Methodenrumpf wird die vordefinierten Methode println ausgeführt, der noch eine freundliche Begrüßung als Argument übergeben wird. Die main-methode ist eine prozedurale Methode, hat also keinen Rückgabewert. Deshalb muß auch kein Rückgabetyp deklariert werden. Was Java-Programmierer weniger vertraut sein dürfte, ist die object Deklaration, die die main-methode einschließt. Eine solche Deklaration beschreibt eine Klasse mit einer einzigen Instanz. So eine Klasse nennt man Singleton-Objekt. Die Deklaration beschreibt also eine Klasse namens HelloWorld und gleichzeitig eine Instanz dieser Klasse mit demselben Namen. Die Instanz wird beim ersten Aufruf erzeugt. Der aufmerksame Leser hat vielleicht bemerkt, dass die main-methode nicht als static deklariert wurde. Dies liegt daran, das es in Scala keine statischen Klassenmitglieder (Methoden oder Felder) gibt. Statt statische Methoden oder Felder zu deklarieren, werden diese innerhalb eines Singleton-Objektes deklariert. 2.1 Das Beispiel wird compiliert Zum Compilieren dieses Beispiels rufen wir scalac auf, den Scala-Compiler. scalac arbeitet wie die meisten Compiler. Aus einer Quelldatei als Argument und gegebenenfalls noch weiteren Optionen werden eine oder mehrere Zieldateien erzeugt. Die Zieldateien sind normale Java-Klassendateien. Wenn wir das obige Programm in einer Datei namens HelloWorld.scala speichern,
3 2.2 Das Beispiel wird ausgeführt 3 können wir es mit dem folgenden Befehl compilieren (Das Größer-Zeichen > steht für den Shell Prompt und wird nicht eingegeben.): > scalac HelloWorld.scala Dadurch werden mehrere Klassendateien im aktuellen Verzeichnis generiert. Die Datei HelloWorld.class enthält eine Klasse, die durch den scala Befehl direkt ausgeführt werden kann. 2.2 Das Beispiel wird ausgeführt Einmal compiliert, kann das Scala-Programm mit dem Befehl scala ausgeführt werden. Die Verwendung von scala ähnelt der des java Befehls, mit dem Java-Programme ausgeführt werden und scala akzeptiert die gleichen Optionen. Das obige Beispiel wird also mit folgendem Befehl ausgeführt und liefert das zu erwartende Ergebnis: > scala -classpath. HelloWorld Hello, world! 3 Interaktion mit Java Einer der Stärken von Scala ist es die einfache Interaktion mit Java-Programmen. Alle Klassen des Pakets java.lang werden defaultmäßig importiert, alle anderen können explizit importiert werden. Schauen wir uns dazu ein Beispiel an. Wir wollen ein aktuelles Datum erzeugen und dies formatiert gemäß den Konventionen eines bestimmten Landes, hier Frankreich 1, ausgeben. Die Java-Klassenbibliotheken definieren dafür leistungsfähige Klassen, nämlich Date und DateFormat. Da Scala nahtlos mit Java interagiert, besteht nicht die Notwendigkeit, vergleichbare Klassen in der Scala-Klassenbibliothek zu definieren. Wir können einfach die Klassen der entsprechenden Java-Pakete importieren: import java.util.{date, Locale import java.text.dateformat import java.text.dateformat._ object FrenchDate { def main(args: Array[String]) { val now = new Date 1 Auch in andere Regionen wie dem französisch sprechenden Teil der Schweiz wird dasselbe Format verwendet.
4 4 val df = getdateinstance(long, Locale.FRANCE) println(df format now) Die Scala import-anweisung ähnelt sehr dem Äquivalent in Java, ist aber mächtiger. Verschiedene Klassen aus dem gleichen Paket können, wie in der ersten Zeile zu sehen ist, importiert werden, indem sie in geschweifte Klammern gesetzt werden. Ein weiterer Unterschied ist, dass beim Import aller Namen eines Pakets oder einer Klasse der Unterstrich (_) anstelle des Sternchens ( * ) verwendet wird. Das ist so, weil das Sternchen ein gültiger Scala Bezeichner ist und als Methodenname verwendet wird. Dazu später mehr. Die import-anweisung in der dritten Zeile importiert also alle Klassenmitglieder der DateFormat-Klasse. Dies macht die statische Methode getdateinstance und das statische Feld LONG sichtbar. Innerhalb der main-methode erzeugen wir zuerst eine Instanz der Java-Klasse Date, die per default das aktuelle Datum enthält. Als nächstes definieren wir ein Datumsformat mit der statischen getdateinstance-methode, die wir zuvor importiert haben. Schließlich geben wir das aktuelle Datum formatiert gemäß der lokalisierten DateFormat-Instanz aus. Diese letzte Zeile zeigt eine interessante Eigenschaft der Scala Syntax. Methoden, die nur ein Argument verwenden, können in Infix-Notation geschrieben werden. Das heißt, der Ausdruck df format now ist nur ein anderer Ausdruck für: df.format(now) Dies mag nur wie ein unwichtiges syntaktisches Detail erscheinen, hat aber weitreichende Konsequenzen, die im nächsten Kapitel untersucht werden. Zum Schluss dieses Kapitels zur Interaktion mit Java sei anzumerken, dass es auch möglich ist, direkt in Scala Java-Klassen zu beerben bzw. Java-Interfaces zu implementieren. 4 Alles ist ein Objekt Scala ist eine reine objektorientierte Sprache in dem Sinne, dass wirklich alles ein Objekt ist, einschließlich Zahlen und Funktionen. In dieser Hinsicht unterscheidet Scala sich von Java, da in Java zwischen primitive Typen (wie boolean und int) und Referenz-Typen unterschieden wird. Auch ist es in Java nicht möglich, Funktionen wie Werte zu behandeln.
5 4.1 Zahlen sind Objekte Zahlen sind Objekte Da Zahlen Objekte sind, haben sie auch Methoden. Und in der Tat besteht ein arithmetischer Ausdruck wie der folgende: * 3 / x ausschließlich aus Methodenaufrufen. Er ist äquivalent zum folgenden Ausdruck, wie wir schon im letzten Kapitel gesehen haben: (1).+(((2).*(3))./(x)) Dies bedeutet auch, dass +, *, etc. gültige Bezeichner in Scala sind. Die Klammern um die Zahlen in der zweiten Version sind notwendig, da der Scala Scanner nach der Regel verfährt, jeweils den längsten möglichen Token zu ermitteln. Gemäß dieser Regel wird folgender Ausdruck: 1.+(2) in die Token 1., + und 2 aufgeteilt. Weil 1. ein gültiger Token ist und er länger als 1 ist, wird diese Aufteilung gewählt. Der Token 1. steht für das Literal 1.0, ist also von der Klasse Double und nicht Int. Bei dem Ausdruck: (1).+(2) verhindern die Klammern, dass 1 als Double interpretiert wird. 4.2 Funktionen sind Objekte Vielleicht noch überraschender für Java-Programmierer ist die Tatsache, das Funktionen in Scala auch Objekte sind. Es ist daher möglich, Funktionen als Argumente zu übergeben, sie in Variablen zu speichern und sie von anderen Funktionen zurückgeben zu lassen. Diese Eigenschaft, Funktionen als veränderliche Werte zu behandeln, ist einer der Grundpfeiler eines äußerst interessanten Programmier- Paradigmas, nämlich dem der funktionalen Programmierung. Als ein sehr einfaches Beispiel dafür, warum es nützlich sein kann, Funktionen als Werte zu behandeln, wollen wir eine Timer-Funktion betrachten, die pro Sekunde eine bestimmte Aktion durchführt. Wie geben wir diese Aktion vor? Logischerweise als eine Funktion. Diese sehr einfache Art der Funktionsübergabe wird vielen Programmierern vertraut sein. Sie wird häufig verwendet, um in User-Interface- Programmen Call-Back-Funktionen zu registrieren, die bei Eintritt eines Ereignisses ausgeführt werden. In dem folgenden Programm wird die Timer-Funktion oncepersecond definiert, und zwar mit einer Call-Back-Funktion als Argument. Die Art der Funktion wird beschrieben durch () => Unit und damit ist eine Funktion gemeint, die keine Argu-
6 6 mente verwendet und keinen Wert zurückgibt. (Der Typ Unit ist vergleichbar mit void in C/C++.) Die main-funktion dieses Programms ruft lediglich diese Timer- Funktion mit einer Call-Back-Funktion, die einen Satz ausgibt, auf. Anders ausgedrückt gibt dieses Programm jede Sekunde den Satz time flies like an arrow aus, und zwar ohne zu stoppen. object Timer { def oncepersecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 def timeflies() { println("time flies like an arrow...") def main(args: Array[String]) { oncepersecond(timeflies) Weiter sei noch angemerkt, dass hier die vordefinierte Methode println verwendet wird, um den Satz auszugeben, nicht die Methode des System.out-Objekts Anonyme Funktionen Dieses Programm ist leicht zu verstehen, kann aber auch noch ein wenig verfeinert werden. Zunächst ist zu bemerken, dass die Funktion timeflies nur definiert wird, um sie später an die Funktion oncepersecond weiterzugegeben. Da man diese Funktion nur einmal verwendet, scheint es unnötig zu sein, ihr einen Namen zu geben. Und es wäre schöner, wenn man die Funktion gerade dort definieren könnte, wo sie an oncepersecond übergeben wird. Dies ist in Scala durch Verwendung anonymer Funktionen, also Funktionen ohne Namen, möglich. Die überarbeitete Version unseres Timer-Programms mit anonymer Funktion anstelle von timeflies sieht so aus: object TimerAnonymous { def oncepersecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 def main(args: Array[String]) { oncepersecond(() => println("time flies like an arrow...")) Das Vorhandensein einer anonymen Funktion wird in diesem Beispiel durch den Pfeil nach rechts => angezeigt, welcher die Liste der Argumente vom Rumpf der
7 5 Klassen 7 Funktion trennt. In diesem Beispiel ist das Argument leer, was durch das leere Paar Klammern links vom Pfeils angedeutet wird. Der Funktionsrumpf ist der gleiche wie der von timeflies oben. 5 Klassen Wie wir oben gesehen haben, ist Scala eine objektorientierte Sprache, und dazu gehört das Konzept der Klasse 2. Klassen werden in Scala mit einer Syntax deklariert, die der von Java sehr ähnlich ist. Ein wichtiger Unterschied besteht darin, dass Klassen in Scala Parameter haben können. Dieses wird in folgender Definition der komplexen Zahlen verwendet. class Complex(real: Double, imaginary: Double) { def re() = real def im() = imaginary Die Klasse Complex hat zwei Argumente, den Real- und den Imaginärteil der komplexen Zahl. Diese Argumente müssen übergeben werden, wenn eine Instanz der Klasse Complex erzeugt werden soll, und zwar wie folgt: new Complex(1.5, 2.3). Die Klasse enthält weiter zwei Methoden re und im, die den Zugriff auf Real- und Imaginärteil beschreiben. Anzumerken ist, dass der Rückgabetyp der beiden Methoden nicht explizit angegeben wird. Dieser wird automatisch durch den Compiler ermittelt, der aus der rechten Seite der Zuweisung folgert, dass die Methode einen Wert vom Typ Double zurück gibt. Der Compiler ist nicht immer in der Lage, auf den Typen zu folgern. Und leider gibt es auch keine einfache Regel, nach der genau zu ermitteln ist, wann es dem Compiler möglich ist und wann nicht. In der Praxis ist dies kein Problem, da der Compiler sich beschwert, wenn er nicht in der Lage ist, auf den Typ zu folgern, falls dieser nicht explizit angegeben wird. Als Anfänger in der Scala Programmierung sollten man nach folgender einfachen Regel verfahren. Man lässt den Typ der Deklarationen in Fällen, in denen er einfach aus dem Kontext abzuleiten scheint, weg und wartet ab, ob der Compiler dies genauso sieht. Nach einiger Zeit wird man ein Gefühl dafür entwickeln, wann man den Typ weglassen kann und wann man ihn explizit angeben muss. 5.1 Methoden ohne Argumente Ein kleines Problem bei der Verwendung der Methoden re und im ist es, dass man bei jedem Aufruf ein leeres Paar Klammern hinter ihrem Methodennamen schrei- 2 Vollständigerweise sollte angemerkt werden, dass es objektorientierte Sprachen gibt, die nicht das Konzept der Klasse kennen. Scala gehört aber nicht dazu.
8 8 ben muss, wie das folgende Beispiel zeigt: object ComplexNumbers { def main(args: Array[String]) { val c = new Complex(1.2, 3.4) println("imaginary part: " + c.im()) Es wäre netter auf realen und imaginärem Teil zuzugreifen, wie wenn sie Felder wären - also ohne das leere Paar Klammern. Dies ist in Scala leicht möglich, einfach durch die Definition von ihnen als Methode ohne Argumente. Solche Methoden unterscheiden sich von Methoden mit null Argumenten dadurch, dass sie nach dem Namen keine Klammern stehen, weder bei der Definition noch beim Zugriff. Unsere Klasse Complex kann damit wie folgt umgeschrieben werden: class Complex(real: Double, imaginary: Double) { def re = real def im = imaginary 5.2 Vererbung und Überschreibung Alle Klassen in Scala erben von einer Super-Klasse. Wenn kein Super-Klasse angegeben wird, wie beim Complex Beispiel im letzten Kapitel wird implizit scala.anyref verwendet. Es ist natürlich auch in Scala möglich, Methoden, die von einer Super-Klasse geerbt wurden, zu überschreiben. Es muss dann jedoch explizit angeben werden, dass eine Methode eine andere überschreibt, um ein versehentliches Überschreiben zu verhindern. Dies geschieht durch Verwendung des override Modifizierers. Als Beispiel wird in unserer Complex-Klasse die tostring-methode, die von Object geerbt wurde, überschrieben. class Complex(real: Double, imaginary: Double) { def re = real def im = imaginary override def tostring() = "" + re + (if (im < 0) "" else "+") + im + "i" 6 Case-Klassen and Pattern Matching Eine Datenstruktur, die oft in Programmen Verwendung findet, ist der Baum. So werden Programme von Interpretern und Compilern in der Regel intern als Baum
9 6 Case-Klassen and Pattern Matching 9 repräsentiert. XML-Dokumente sind Bäume und verschiedene Containern basieren auf Bäumen, etwa Rot-Schwarz-Bäumen. Wir werden nun untersuchen, wie solche Bäume in Scala repräsentiert und verändert werden können. Und zwar am Beispiel eines kleinen Taschenrechner-Programms. Das Ziel dieses Programms ist es, einfache arithmetische Ausdrücke, die aus Summierung, Integer-Konstanten und -Variablen zusammengesetzt sind, auszuwerten. Zwei Beispiele für solche Ausdrücke sind und (x + x) + (7 + y). Wir müssen uns zuerst für eine Darstellung von solchen Ausdrücken entscheiden. Die natürlichste ist die durch einen Baum, bei dem die Knoten Operationen (hier die Summierung) und die Blätter Werte (hier Konstanten und Variablen) sind. In Java würde ein solcher Baum dargestellt werden durch eine abstrakten Super- Klasse für den Baum und je eine konkrete Unterklasse pro Knoten und Blatt. In einer funktionalen Programmiersprache würde man einen algebraischen Datentyp für den gleichen Zweck verwenden. Scala bietet das Konzept der Case-Klasse an, das irgendwo zwischen den beiden Konzepten liegt. Und so könnte man mit Case- Klassen den Baum für unser Beispiel definieren: abstract class Tree case class Sum(l: Tree, r: Tree) extends Tree case class Var(n: String) extends Tree case class Const(v: Int) extends Tree Weil die Klassen Sum, Var und Const als Case-Klassen deklariert werden, unterscheiden sie sich von anderen Klassen in folgender Weise: Das new Keyword muß nicht mehr angegeben werden, um Instanzen dieser Klasse zu erzeugen. (Man kann also Const(5) schreiben, anstelle von new Const(5).) Es werden automatisch Getter-Funktionen für die Parameter des Konstruktors erzeugt. (Man erhält also etwa den Konstruktor Parameter v einer Instanz c einfach indem man c.v schreibt.) Standard-Definitionen für Methoden equals und hashcode werden erzeugt. Diese berücksichtigen die Struktur der Instanzen. (Und nicht nur die Identität.) Eine Standard-Definition für die Methode tostring wird erzeugt. Diese liefert einen String, der so auch im Quellcode stehen könnte. (Der Baum für den Ausdruck x + 1 liefert etwa Sum(Var(x),Const(1))) Instanzen dieser Klassen können durch Pattern Matching zerlegt werden, wie wir weiter unten sehen werden. Da wir nun den Datentyp, der unsere arithmetischen Ausdrücke darstellen wird, definiert haben, können wir nun Operationen auf diesem Datentyp definieren. Beginnen wir mit einer Funktion, die einen Ausdruck in einer Umgebung auswertet.
10 10 In einer Umgebung werden Variablen Werte zugewiesen. So wird der Ausdruck x +1 in einer Umgebung, die der Variablen x den Wert 5 zuordnet (geschrieben {x 5), zu 6 ausgewertet. Wir müssen also in irgendeiner Weise eine Umgebung repräsentieren. Wir könnten dafür natürlich eine assoziative Datenstruktur (wie etwa eine Hash-Tabelle) verwenden - oder wir verwenden gleich eine Funktion! Eine Umgebung ist nämlich nichts anderes als eine Funktion, die einen Wert mit einem (Variablen-)Namen verknüpft. Die obige Umgebung {x 5 kann einfach folgendermaßen in Scala definiert werden: { case "x" => 5 Diese Schreibweise definiert eine Funktion, die die Zahl 5 zurück gibt, wenn an sie der String x übergeben wird. Bei allen anderen Übergabewerten wird eine Ausnahme ausgelöst. Vor dem Schreiben der Bewertungsfunktion wollen wir noch für den Typ der Umgebung einen Namen vergeben. Wir können natürlich auch die Umgebungen immer als vom Typ String => Int definieren. Aber es würde das Programm vereinfachen, wenn wir für diesen Typ einen Namen vergeben könnten. Außerdem werden zukünftige Änderungen dadurch erleichtert. Dies wird in Scala mit der folgenden Notation erreicht: type Environment = String => Int Damit kann Environment als eine Art Alias für Funktionen vom Typ String => Int verwendet werden. Wir kommen jetzt zur Definition der Bewertungsfunktion. Konzeptionell ist es einfach: Der Wert einer Summe von zwei Ausdrücken ist einfach die Summe aus den Werten dieser Ausdrücke; der Wert einer Variablen wird direkt aus der Umgebung genommen; und der Wert einer Konstanten ist die Konstante selbst. Dies ist leicht in Scala zu formulieren: def eval(t: Tree, env: Environment): Int = t match { case Sum(l, r) => eval(l, env) + eval(r, env) case Var(n) => env(n) case Const(v) => v Diese Bewertungsfunktion wendet Pattern Matching auf den Baum t an. Intuitiv ist die Bedeutung obiger Definition klar: 1. Zunächst wird geprüft, ob der Baum t eine Summe ist und wenn er es ist, wird der linke Teilbaum an eine Variable l gebunden und der rechte Teilbaum an eine Variable r. Dann wird der Ausdruck rechts vom Pfeil ausgewertet. Dabei werden die durch das Pattern Matching gebundenen Variablen l und r ver-
11 6 Case-Klassen and Pattern Matching 11 wendet. 2. Wenn die erste Überprüfung nicht erfolgreich ist, wenn also der Baum keine Summe ist, geht es weiter mit einer Prüfung, ob t eine Variable ist. Ist dies der Fall, wird der Name des Var-Knotens an die Variable n gebunden und der rechten Ausdruck wird ausgewertet. 3. Wenn auch die zweite Prüfung nicht erfolgreich ist, also in dem Fall, dass t weder eine Summe noch ein Variable ist, wird überprüft, ob t eine Konstante ist. Und wenn dies so ist, wird der Wert in dem Const-Knoten an eine Variablen v gebunden. Dann wird wieder der rechte Ausdruck ausgewertet. 4. Schließlich, wenn alle Überprüfungen fehlschlagen, wird eine Ausnahme ausgelöst, um das Scheitern des Pattern Matching anzuzeigen. Dies könnte aber hier nur passieren, wenn inzwischen weitere Unterklassen deklariert wurden. Die Grundidee des Pattern Matching ist es also zu versuchen, einen Wert mit einer Folge von Mustern (Pattern) zu vergleichen und sobald ein passendes (matching) Muster gefunden wurde, dieses und andere Teile des Wertes zu extrahieren, um sie dann in der anschließenden Bearbeitung verwenden zu können. Ein in der Objektorientierung erfahrener Programmierer mag sich vielleicht fragen, warum wir die eval-methode nicht als eine Klassenmethode der Klasse tree und ihrer Unterklassen definiert haben. Dies hätten wir auch wirklich tun können, da Scala dies bei Case-Klassen erlaubt. Die Entscheidung, ob man das Pattern Matching direkt oder in einer Methoden verwendet, ist eine Geschmacksfrage, hat aber auch wichtige Auswirkungen auf die Erweiterbarkeit der Klasse: Bei der Verwendung von Methoden ist es leicht, eine neue Art von Knoten hinzuzufügen, und zwar durch die Definition einer Unterklasse von tree. Auf der anderen Seite ist das Hinzufügen einer neuen Operation für tree mühsam, da alle Unterklassen von tree angepasst werden müssen. Bei der Verwendung von Pattern Matching ist die Situation umgekehrt. Das Hinzufügen einer neuen Klasse von Knoten erfordert die Änderung aller Funktionen, die ein Pattern Matching auf tree anwenden, um den neue Knoten zu berücksichtigen. Auf der anderen Seite ist das Hinzufügen einer neuen Operation einfach, und zwar durch die Definition einer weiteren Funktion. Um das Pattern Matching weiter zu erkunden, definieren wir eine weitere Operationen auf den arithmetischen Ausdruck: die symbolische Ableitung. Der Leser kennt vielleicht noch die folgenden Regeln dieser Operation: 1. Die Ableitung einer Summe ist die Summe aus den Ableitungen. 2. Die Ableitung von einer Variablen v ist 1, wenn nach v abgeleitet wird, und 0 sonst.
12 12 3. Die Ableitung einer Konstanten ist 0. Diese Regeln können fast wörtlich in Scala übernommen werden. Damit erhalten wir die folgende Definition: def derive(t: Tree, v: String): Tree = t match { case Sum(l, r) => Sum(derive(l, v), derive(r, v)) case Var(n) if (v == n) => Const(1) case _ => Const(0) Diese Funktion verwendet zwei neue Konzepte zum Pattern Matching. Zunächst einmal hat der Ausdruck für die Variable eine zusätzliche Klausel. Der Ausdruck nach dem Schlüsselwort if wird in diesem Zusammenhang Guard genannt. Er beschränkt den Erfolg des Vergleichs auf die Fälle, in denen dieser Ausdruck wahr ist. Hier wird er verwendet, um sicherzustellen, dass wir die Konstante 1 nur zurückgeben, wenn der Name der Variablen der gleiche ist wie der, nach der abgeleitet wird. Das zweite neue Konzept, das hier verwendet wird, ist das der Wild-Card _. Dieses Muster passt auf jeden Wert. Wir haben damit noch längst nicht alle Möglichkeiten des Pattern Matching gesehen, werden hier aber aufhören, um dies Dokument kurz zu halten. Wir wollen noch zeigen, wie die beiden Funktionen auf ein reales Beispiel angewendet werden. Zu diesem Zweck schreiben wir eine einfache main-funktion, die mehrere Operationen auf den Ausdruck (x + x) + (7 + y) ausführt. Zuerst wird der Ausdrucks in der Umwelt {x 5, y 7 ausgewertet. Dann wird die Ableitung bzgl. x und y gebildet: def main(args: Array[String]) { val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y"))) val env: Environment = { case "x" => 5 case "y" => 7 println("expression: " + exp) println("evaluation with x=5, y=7: " + eval(exp, env)) println("derivative relative to x:\n " + derive(exp, "x")) println("derivative relative to y:\n " + derive(exp, "y")) Bei Ausführung dieses Programms erhalten wir die erwartete Ausgabe: Expression: Sum(Sum(Var(x),Var(x)),Sum(Const(7),Var(y))) Evaluation with x=5, y=7: 24 Derivative relative to x: Sum(Sum(Const(1),Const(1)),Sum(Const(0),Const(0))) Derivative relative to y: Sum(Sum(Const(0),Const(0)),Sum(Const(0),Const(1))) Bei Durchsicht der Ausgabe erkennen wir, dass das Ergebnis der Ableitung vereinfacht werden sollten, bevor man sie dem Anwender präsentiert. Die Definition ei-
13 7 Traits 13 ner allgemeinen Vereinfachungsfunktion mit Hilfe des Pattern Matching ist ein interessantes (aber überraschend kniffliges) Problem. Die Lösung sei dem Leser als Übung überlassen. 7 Traits Eine Klasse in Scala kann von ihrer Super-Klasse erben und zusätzlich auch von einem oder mehreren Traits. Der vielleicht einfachste Weg für ein Java-Programmierer Traits zu verstehen ist, sie einfach als Interface mit Programmteilen zu betrachten. Wenn in Scala eine Klasse von einem Trait erbt, implementiert sie das Interface des Traits und erbt alle Programmteile des Traits. Um die Nützlichkeit von Traits zu demonstrieren, wollen wir uns ein klassisches Beispiel ansehen: Objekte mit einer Ordnung. Es ist oft nützlich, Objekte einer bestimmten Klassen untereinander vergleichen zu können, etwa um sie zu sortieren. In Java implementieren Objekte, die vergleichbar sind, das Interface Comparable. In Scala können wir dies ein bisschen besser umsetzen, indem wir einen zu Comparable äquivalenten Trait einsetzen. Diesen Trait wollen wir Ord nennen. Beim Vergleich von Objekten können uns sechs verschiedene Prädikate nützlich sein: kleiner, kleiner-gleich, gleich, ungleich, größer oder größer-gleich. Allerdings ist es umständlich, alle zu definieren, zumal vier von den sechs mit Hilfe der anderen zwei ausgedrückt werden können. Das heißt, wenn etwa das gleich und das kleiner Prädikate vorhanden sind, können die anderen durch diese zwei ausgedrückt werden. In Scala wird dieser Sachverhalt gut in folgender Deklaration wiedergegeben: trait Ord { def < (that: Any): Boolean def <=(that: Any): Boolean = (this < that) (this == that) def > (that: Any): Boolean =!(this <= that) def >=(that: Any): Boolean =!(this < that) Diese Definition liefert einen neuen Trait namens Ord, der die gleiche Rolle spielt wie das Java Comparable-Interface und der die Standard-Implementierungen von drei Prädikate auf das vierte abstrakte Prädikat zurückführt. Die Prädikate für gleich und ungleich werden nicht deklariert, da sie per default in allen Objekten vorhanden sind. Der Typ Any, der oben verwendet wird, ist Super-Typ für alle anderen Typen in Scala. Er kann also als eine allgemeinere Version von Javas Object-Typ angesehen werden, da er auch einen Super-Typ zu den Basistypen wie int, float, u.a. darstellt. Um Objekte einer Klasse vergleichbar zu machen, reicht es jetzt aus, die Prädikate
14 14 für gleich und kleiner in der Klasse zu definieren und die Klasse Ord einzumischen. Als ein Beispiel definieren wir nun eine Date-Klasse, die das Datum des gregorianischen Kalenders repräsentiert. Solch ein Datum besteht aus einem Tag, einem Monat und einem Jahr, die wir alle durch ganze Zahlen repräsentieren werden. Wir beginnen also die Definition der Date-Klasse wie folgt: class Date(y: Int, m: Int, d: Int) extends Ord { def year = y def month = m def day = d override def tostring(): String = year + "-" + month + "-" + day Der wichtige Teil hier ist die extends Ord Klausel nach dem Klassennamen. So wird deklariert, das die Date-Klasse vom Ord-Trait erbt. Dann definieren wir die von der Object geerbte Methode equals, so dass sie Datums- Instanzen durch Vergleich ihrer Feldern durchführt. Die Default-Implementierung von equals ist nicht verwendbar, weil sie wie in Java Objekte über deren Identität vergleicht. Wir kommen auf folgende Definition: override def equals(that: Any): Boolean = that.isinstanceof[date] && { val o = that.asinstanceof[date] o.day == day && o.month == month && o.year == year Diese Methode verwendet die vordefinierten Methoden isinstanceof und asinstanceof. Die erste Methode isinstanceof entspricht dem Java instanceof-operator und liefert true, wenn und nur wenn das Objekt, auf den er angewandt wird, eine Instanz des angegebenen Typs ist. Die zweite Methode asinstanceof entspricht dem Java Cast-Operator. Wenn das Objekt eine Instanz des angegebenen Typs ist, wird es als ein solches behandelt. Andernfalls wird eine ClassCastException-Ausnahme ausgelöst. Schließlich ist noch die letzte Methode wie folgt zu definieren, die das Prädikat kleiner implementiert. Es nutzt eine weitere vordefinierte Methode error, die eine Ausnahme mit der angegebenen Fehlermeldung auslöst. def <(that: Any): Boolean = { if (!that.isinstanceof[date]) error("cannot compare " + that + " and a Date") val o = that.asinstanceof[date] (year < o.year) (year == o.year && (month < o.month (month == o.month && day < o.day)))
15 8 Generische Programmierung 15 Das ist die Definition der Date-Klasse. Instanzen dieser Klasse können als Datumsinstanzen betrachtet werden und auch als vergleichbare Objekte. Weiter definieren sie alle sechs erwähnten Prädikate: gleich und kleiner direkt in der Definition der Date-Klasse, die anderen durch Vererbung vom Ord-Trait. Traits sind natürlich auch in anderen als der hier gezeigten Situationen nützlich. Aber die Vorstellung aller Möglichkeiten kann dieses Dokument nicht leisten. 8 Generische Programmierung Als letztes in diesem Tutorial wollen wir die generische Programmierung in Scala vorstellen. Java-Programmierer kennen die Probleme, die ohne die Möglichkeit der generischen Programmierung entstehen. Dieser Mangel wurde in Java mit Version 1.5 behoben. Generische Programmierung ist die Möglichkeit, in Programme Typen-Parameter zu verwenden. Zum Beispiel steht ein Programmierer, der eine Bibliothek für verkettete Listen schreiben will, vor dem Problem zu entscheiden, welchen Typ die Elemente der Liste habe sollen. Da diese Liste in vielen verschiedenen Kontexten verwendet werden soll, ist es nicht möglich im voraus zu entscheiden, dass der Typ der Elemente etwa Int ist. Dies wäre eine willkürliche und restriktive Wahl. Java-Programmierern blieb die Möglichkeit auf Object zurückzugreifen, dem Super- Typ aller Objekte. Diese Lösung ist jedoch bei weitem nicht ideal, da sie nicht für primitive Typen (int, long, float, u.a.) funktioniert. Weiter impliziert diese Lösung, dass viele dynamischen Typumwandlungen durch den Programmierer vorgenommen werden müssen. In Scala ist es möglich, generische Klassen (und Methoden) zu definieren, um dieses Problem zu lösen. Betrachten wir dies an einem Beispiel einer einfachen Container- Klasse: ein Referenz, die entweder leer ist oder auf ein Objekt eines bestimmten Typs verweist. class Reference[T] { private var contents: T = _ def set(value: T) { contents = value def get: T = contents Die Klasse wird mit einem Referenz-Typ T, der den Typ des Elementes bezeichnet, parametrisiert. Dieser Typ wird im Rumpf der Klasse als Typ der Variablen contents, als Typ des Arguments der set-methode und als Rückgabetyp der get-methode verwendet. Das obige Programmbeispiel verwendet Variablen in Scala, was an sich keiner weiteren Erläuterung bedarf. Es ist jedoch interessant zu sehen, dass der ursprüngliche
16 16 Wert, der dieser Variablen gegeben wird, _ ist. Dies steht für den Default-Wert. Dieser Default-Wert ist 0 für numerische Typen, false für den Boolean-Typ, () für den Unit-Typ und null für alle Objekttypen. Zur Verwendung dieser Referenz-Klasse muss man angeben, welchen Typ man für den Typ-Parameter T verwenden will. Also von welchen Typ das Elements des Container sein soll. Um zum Beispiel einen Container mit einem Int-Wert zu verwenden, würde man folgendes schreiben: object IntegerReference { def main(args: Array[String]) { val cell = new Reference[Int] cell.set(13) println("reference contains the half of " + (cell.get * 2)) Wie aus diesem Beispiel ersichtlich, ist es nicht notwendig, den von der get-methode zurückgegebenen Wert zu casten, um ihn als Integer zu verwenden. Es ist natürlich auch nicht möglich, etwas anderes als einen Integer im Container zu speichern. 9 Schlussbemerkung Dieses Dokument gibt einen kurzen Überblick über die Sprache Scala und präsentiert einige grundlegende Beispiele. Der interessierte Leser kann im Begleitdokument Scala By Example weitere fortgeschrittene Beispiele finden. Zur weiteren Lekture sei die Scala Language Specification empfohlen.
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
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
Repetitorium Informatik (Java)
Repetitorium Informatik (Java) Tag 6 Lehrstuhl für Informatik 2 (Programmiersysteme) Übersicht 1 Klassen und Objekte Objektorientierung Begrifflichkeiten Deklaration von Klassen Instanzmethoden/-variablen
Java I Vorlesung 6 Referenz-Datentypen
Java I Vorlesung 6 Referenz-Datentypen 7.6.2004 Referenzen this, super und null Typkonvertierung von Referenztypen Finale Methoden und Klassen Datentypen in Java In Java gibt es zwei Arten von Datentypen:
Beispiel: Zwischen der Oberklasse und der abgeleiteten Klasse besteht eine ist ein Beziehung. Eine abgeleitete Klasse stellt eine Spezialisierung der
Vererbung Vererbung ist ein Konzept der objektorientierten Programmierung,, die es ermöglicht neue Klassen von bereits vorhandenen Klassen abzuleiten. In einer abgeleiteten Klasse (subclass) muss nur spezifiziert
1 Polymorphie (Vielgestaltigkeit)
1 Polymorphie (Vielgestaltigkeit) Problem: Unsere Datenstrukturen List, Stack und Queue können einzig und allein int-werte aufnehmen. Wollen wir String-Objekte, andere Arten von Zahlen oder andere Objekttypen
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,
Vererbung & Schnittstellen in C#
Vererbung & Schnittstellen in C# Inhaltsübersicht - Vorüberlegung - Vererbung - Schnittstellenklassen - Zusammenfassung 1 Vorüberlegung Wozu benötigt man Vererbung überhaubt? 1.Um Zeit zu sparen! Verwendung
Kapitel 3: Variablen
Kapitel 3: Variablen Thema: Programmieren Seite: 1 Kapitel 3: Variablen Im letzten Kapitel haben wir gelernt, bestimmte Ereignisse zu wiederholen solange eine Bedingung erfüllt ist. Nun möchten wir aber
Das Typsystem von Scala. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala
Das Typsystem von Scala 1 Eigenschaften Das Typsystem von Scala ist statisch, implizit und sicher 2 Nichts Primitives Alles ist ein Objekt, es gibt keine primitiven Datentypen scala> 42.hashCode() res0:
Einstieg in die Informatik mit Java
1 / 41 Einstieg in die Informatik mit Java Vererbung Gerd Bohlender Institut für Angewandte und Numerische Mathematik Gliederung 2 / 41 1 Überblick: Vererbung 2 Grundidee Vererbung 3 Verdeckte Variablen
Kapitel 8. Programmierkurs. Methoden. 8.1 Methoden
Kapitel 8 Programmierkurs Birgit Engels Anna Schulze Zentrum für Angewandte Informatik Köln Objektorientierte Programmierung Methoden Überladen von Methoden Der this-zeiger Konstruktoren Vererbung WS 07/08
Silke Trißl, Prof. Ulf Leser Wissensmanagement in der Bioinformatik. Jede Applikation braucht eine Klasse mit einer main-methode
Methoden und Klassen Silke Trißl, Prof. Ulf Leser Wissensmanagement in der Bioinformatik Wiederholung Jede Applikation braucht eine Klasse mit einer main-methode Eintrittspunkt in das Programm Die main-methode
Interfaces und Vererbung
Interfaces und Vererbung Einführung in Java Folie 1 von 31 12. Mai 2011 Ivo Kronenberg Inhalt Interfaces Statische und dynamische Typen Visiblitätsmodifier Vererbung Überschreiben von Methoden Konstruktoren
Objektorientierte Programmierung. Kapitel 12: Interfaces
12. Interfaces 1/14 Objektorientierte Programmierung Kapitel 12: Interfaces Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester 2012/13 http://www.informatik.uni-halle.de/ brass/oop12/
Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden.
Grundwissen Informatik Objekt Attribut Methoden Als Objekte bezeichnet man alle Gegenstände, Dinge, Lebewesen, Begriffe oder Strukturen unserer Welt ( Autos, Räume, Bakterien, Lehrer, Schüler, Kunden,
AuD-Tafelübung T-B5b
6. Übung Sichtbarkeiten, Rekursion, Javadoc Di, 29.11.2011 1 Blatt 5 2 OOP Klassen Static vs. Instanzen Sichtbarkeit 3 Stack und Heap Stack Heap 4 Blatt 6 1 Blatt 5 2 OOP Klassen Static vs. Instanzen Sichtbarkeit
Programmierung mit C Zeiger
Programmierung mit C Zeiger Zeiger (Pointer)... ist eine Variable, die die Adresse eines Speicherbereichs enthält. Der Speicherbereich kann... kann den Wert einer Variablen enthalten oder... dynamisch
Tutoraufgabe 1 (Zweierkomplement): Lösung: Programmierung WS16/17 Lösung - Übung 2
Prof. aa Dr. J. Giesl Programmierung WS16/17 F. Frohn, J. Hensel, D. Korzeniewski Tutoraufgabe 1 (Zweierkomplement): a) Sei x eine ganze Zahl. Wie unterscheiden sich die Zweierkomplement-Darstellungen
Einstieg in die Informatik mit Java
1 / 34 Einstieg in die Informatik mit Java Klassen mit Instanzmethoden Gerd Bohlender Institut für Angewandte und Numerische Mathematik Gliederung 2 / 34 1 Definition von Klassen 2 Methoden 3 Methoden
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
Kapitel 6. Vererbung
1 Kapitel 6 2 Ziele Das sprinzip der objektorientierten Programmierung verstehen Und in Java umsetzen können Insbesondere folgende Begriffe verstehen und anwenden können: Ober/Unterklassen Subtyping Überschreiben
Kapitel 6. Vererbung
1 Kapitel 6 2 Ziele Das sprinzip der objektorientierten Programmierung verstehen Und in Java umsetzen können Insbesondere folgende Begriffe verstehen und anwenden können: Ober/Unterklassen Subtyping Überschreiben
7. Schnittstellen Grundlagen zu Schnittstellen. 7. Schnittstellen
7. Schnittstellen Grundlagen zu Schnittstellen 7. Schnittstellen Eine Schnittstelle (Interface) ist eine Spezifikation eines Typs in Form eines Typnamens und einer Menge von Methoden, die keine Implementierungen
Programmieren I. Kapitel 5. Kontrollfluss
Programmieren I Kapitel 5. Kontrollfluss Kapitel 5: Kontrollfluss Ziel: Komplexere Berechnungen im Methodenrumpf Ausdrücke und Anweisungen Fallunterscheidungen (if, switch) Wiederholte Ausführung (for,
Einführung in den Einsatz von Objekt-Orientierung mit C++ I
Einführung in den Einsatz von Objekt-Orientierung mit C++ I ADV-Seminar Leiter: Mag. Michael Hahsler Syntax von C++ Grundlagen Übersetzung Formale Syntaxüberprüfung Ausgabe/Eingabe Funktion main() Variablen
Kapitel 9: Klassen und höhere Datentypen. Klassen und höhere. Objekte, Felder, Methoden. Küchlin/Weber: Einführung in die Informatik
Klassen und höhere Datentypen Objekte, Felder, Methoden Küchlin/Weber: Einführung in die Informatik Klassen Klasse (class) stellt einen (i.a. benutzerdefinierten) Verbund-Datentyp dar Objekte sind Instanzen
Programmierkurs Java
Programmierkurs Java Konstruktor, Statische Methoden Packages Prof. Dr. Stefan Fischer Institut für Telematik, Universität zu Lübeck http://www.itm.uni-luebeck.de/people/fischer Initialisierung von Datenstrukturen
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
3 Objektorientierte Konzepte in Java
3 Objektorientierte Konzepte in Java 3.1 Klassendeklarationen Fragen an die Klassendeklaration: Wie heißt die Klasse? Wer darf auf die Klasse und ihre Attribute/Methoden zugreifen? Ist die Klasse eine
Programmieren I. Kapitel 8. Vererbung
Programmieren I Kapitel 8. Vererbung Kapitel 8: Vererbung Ziel: Wesentliches objektorientiertes Konzept kennenlernen Subtypen Idee Probleme und Varianten Vererbung in Java dynamische Bindung abstrakte
Kapitel 6. Vererbung
Kapitel 6 Vererbung Vererbung 1 Ziele Das Vererbungsprinzip der objektorientierten Programmierung verstehen Und in Java umsetzen können Insbesondere folgende Begriffe verstehen und anwenden können: Ober/Unterklassen
Javakurs für Anfänger
Javakurs für Anfänger Einheit 02: Klassen & Objekte Lorenz Schauer Lehrstuhl für Mobile und Verteilte Systeme Heutige Agenda 1. Teil: Klassen Grundstruktur einer Java-Klasse Eigenschaften (Attribute) Variablen
Seminar Scala SS2010, Einführung. R. Schiedermeier Fakultät 07 für Informatik und Mathematik
Seminar Scala SS2010, Einführung R. Schiedermeier Fakultät 07 für Informatik und Mathematik Themen Ausführen von Scala-Code Werte und Variablen Methoden Typen 22.04.10 Seminar Scala, Einführung 2 Übersetzen
Programmieren in Java
Programmieren in Java objektorientierte Programmierung 2 2 Zusammenhang Klasse-Datei In jeder *.java Datei kann es genau eine public-klasse geben wobei Klassen- und Dateiname übereinstimmen. Es können
Primitive Datentypen und Felder (Arrays)
Primitive Datentypen und Felder (rrays) Primitive Datentypen Java stellt (genau wie Haskell) primitive Datentypen für Boolesche Werte, Zeichen, ganze Zahlen und Gleitkommazahlen zur Verfügung. Der wichtigste
Einführung in die Informatik
Einführung in die Informatik Jochen Hoenicke Software Engineering Albert-Ludwigs-University Freiburg Sommersemester 2014 Jochen Hoenicke (Software Engineering) Einführung in die Informatik Sommersemester
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
Autor: Michael Spahn Version: 1.0 1/10 Vertraulichkeit: öffentlich Status: Final Metaways Infosystems GmbH
Java Einleitung - Handout Kurzbeschreibung: Eine kleine Einführung in die Programmierung mit Java. Dokument: Autor: Michael Spahn Version 1.0 Status: Final Datum: 23.10.2012 Vertraulichkeit: öffentlich
Algorithmen und Datenstrukturen 07
5. Dezember 2011 1 Besprechung Blatt 6 Fragen 2 Vererbung Allgemein abstract Interfaces 3 Unified Modeling Language (UML) Ablaufdiagramme Klassendiagramme Anwendungsfalldiagramme 4 Vorbereitung Blatt 7
Javakurs 2013 Objektorientierung
Javakurs 2013 Objektorientierung Objektorientierte Programmierung I Armelle Vérité 7 März 2013 Technische Universität Berlin This work is licensed under the Creative Commons Attribution-ShareAlike 3.0
JAVA-Datentypen und deren Wertebereich
Folge 8 Variablen & Operatoren JAVA 8.1 Variablen JAVA nutzt zum Ablegen (Zwischenspeichern) von Daten Variablen. (Dies funktioniert wie beim Taschenrechner. Dort können Sie mit der Taste eine Zahl zwischenspeichern).
Überschreiben von Methoden
Vergleich der DoME Realisierungen: Methode ausgeben Version 1 (ohne Vererbung): Anzeigen aller Informationen CD: A Swingin Affair (64 Min)* Frank Sinatra Titelanzahl: 16 Mein Lieblingsalbum von Sinatra
3 Objektorientierte Konzepte in Java
3 Objektorientierte Konzepte in Java Bisherige Beobachtungen zu Objekten: werden in Klassen zusammengefasst besitzen Eigenschaften und Verhalten verbergen private Informationen werden geboren, leben und
Objektorientierte Programmierung. Objektorientierte Programmierung. Klasse. Objekt. Beispiel: Sportfest1. Methode. Eine Einführung mit BlueJ
Objektorientierte Programmierung Objektorientierte Programmierung Eine Einführung mit BlueJ stellt die Daten, ihre Struktur und ihre Beziehungen zueinander in den Vordergrund. Weniger im Blickpunkt: die
Einführung in die Programmierung 1
Einführung in die Programmierung 1 Einführung (S.2) Einrichten von Eclipse (S.4) Mein Erstes Programm (S.5) Hallo Welt!? Programm Der Mensch (S.11) Klassen (S.12) Einführung Wie Funktioniert Code? Geschriebener
Übersicht. Informatik 2 Teil 3 Anwendungsbeispiel für objektorientierte Programmierung
Übersicht 3.1 Modell Konto 3.2 Modell Konto - Erläuterungen 3.3 Benutzer Ein- und Ausgabe mit Dialogfenster I 3.4 Benutzer Ein- und Ausgabe mit Dialogfenster II 3.5 Klassen- und Objekteigenschaften des
Einstieg in die Informatik mit Java
Vorlesung vom 18.4.07, Grundlagen Übersicht 1 Kommentare 2 Bezeichner für Klassen, Methoden, Variablen 3 White Space Zeichen 4 Wortsymbole 5 Interpunktionszeichen 6 Operatoren 7 import Anweisungen 8 Form
5.5.8 Öffentliche und private Eigenschaften
5.5.8 Öffentliche und private Eigenschaften Schnittstellen vs. Implementierungen: Schnittstelle einer Klasse beschreibt, was eine Klasse leistet und wie sie benutzt werden kann, ohne dass ihre Implementierung
Einführung in die Programmierung
Skript zur Vorlesung: Einführung in die Programmierung WiSe 2009 / 2010 Skript 2009 Christian Böhm, Peer Kröger, Arthur Zimek Prof. Dr. Christian Böhm Annahita Oswald Bianca Wackersreuther Ludwig-Maximilians-Universität
Java Einführung VARIABLEN und DATENTYPEN Kapitel 2
Java Einführung VARIABLEN und DATENTYPEN Kapitel 2 Inhalt dieser Einheit Variablen (Sinn und Aufgabe) Bezeichner Datentypen, Deklaration und Operationen Typenumwandlung (implizit/explizit) 2 Variablen
JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML.
JavaScript JavaScript wird direkt in HTML-Dokumente eingebunden. Gib folgende Zeilen mit einem Texteditor (Notepad) ein: (Falls der Editor nicht gefunden wird, öffne im Browser eine Datei mit der Endung
Repetitorium Informatik (Java)
Repetitorium Informatik (Java) Tag 8 Lehrstuhl für Informatik 2 (Programmiersysteme) Übersicht 1 Vererbung Vererbung Statischer Typ Dynamischer Typ 2 Polymorphie Overloading: Methoden überladen Overriding:
Anwendungsentwicklung mit Java. Grundlagen der OOP, Vererbung, Schnittstellen, Polymorphie
Anwendungsentwicklung mit Java Grundlagen der OOP, Vererbung, Schnittstellen, Polymorphie Vererbung (1) 2 Problem: Objekte mit gleichen Attributen/Methoden, aber nicht völlig identisch, z.b., LKW, PKW,
Grundzüge der Programmierung. Wiederverwendung VERERBUNG
Grundzüge der Programmierung Wiederverwendung VERERBUNG Inhalt dieser Einheit Syntax: Vererbung in Java Superklassen - Subklassen Konstruktorenaufruf in Subklassen super, abstract und final 2 Code-Reuse
Java für Computerlinguisten
Java für Computerlinguisten 2. Objektorientierte Programmierung Christian Scheible Institut für Maschinelle Sprachverarbeitung 28. Juli 2009 Christian Scheible Java für Computerlinguisten 28. Juli 2009
Java I Vorlesung Objektorientiertes Programmieren
Java I Vorlesung 3 Objektorientiertes Programmieren 10.5.2004 Die restlichen Kontrollstrukturen Grundlagen des OOP Klassen und Objekte switch Syntax: switch ( expr ) { case const 1 : case const 2 :...
Präsentation Interfaces
Einführung in Java Präsentation Interfaces Nozar Delassaei Marvi Inhalt 1. Erinnerung Klasse Objekte Beispiel Klasse Abstrakte Klasse Beispiel Abstrakte Klasse Mehrfachvererbung-1 Mehrfachvererbung-2 2.
Übersicht. Vorstellung des OO-Paradigmas
Java, OO und UML Vorstellung des OO-Paradigmas Übersicht Umsetzung des OO-Paradigmas in Java Einführung (seeeeeehr rudimenter) in UML zur graphischen Darstellung von OO Grammatik und Semantik von Java
Javakurs zu Informatik I. Henning Heitkötter
Javakurs zu Informatik I Arrays vergleichen Implementieren Sie folgende Methode, die prüft, ob die Elemente der beiden Arrays an jeder Position übereinstimmen: public static boolean identisch(int[] a,
Algorithmen und Programmierung II
Algorithmen und Programmierung II Vererbung Prof. Dr. Margarita Esponda SS 2012 1 Imperative Grundbestandteile Parameterübergabe String-Klasse Array-Klasse Konzepte objektorientierter Programmierung Vererbung
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,
Die Programmiersprache C Eine Einführung
Die Programmiersprache C Eine Einführung Christian Gentsch Fakutltät IV Technische Universität Berlin Projektlabor 2. Mai 2014 Inhaltsverzeichnis 1 Einführung Entstehungsgeschichte Verwendung 2 Objektorientiert
Inhaltsüberblick. I. Grundbegriffe - Objekte und Klassen. Organisatorisches. I. Grundbegriffe - Objektorientierte Konzepte
Grundkonzepte Objektorientierter Programmierung Nicole Himmerlich FSU Jena mit Java, Oberon-2, Object-Pascal und Python Inhaltsüberblick I. Grundbegriffe 1) Kopplung 2) Datenkaspelung 3) Konstruktor 4)
Java Kurs für Anfänger Einheit 5 Methoden
Java Kurs für Anfänger Einheit 5 Methoden Ludwig-Maximilians-Universität München (Institut für Informatik: Programmierung und Softwaretechnik von Prof.Wirsing) 22. Juni 2009 Inhaltsverzeichnis Methoden
Prof. W. Henrich Seite 1
Klasse - ist ein benutzerdefinierter Datentyp (Referenztyp) - hat Datenelemente - hat Methoden - Konstruktor ist spezielle Methode zum Erstellen eines Objektes vom Typ der Klasse (Instanz) - jede Klasse
Programmierkurs C++ Abstrakte Klassen und Methoden
Programmierkurs C++ Abstrakte Klassen und Methoden Prof. Dr. Stefan Fischer Institut für Telematik, Universität zu Lübeck http://www.itm.uni-luebeck.de/people/fischer #2 Vererbungshierarchie Obst double
13 OOP MIT DELPHI. Records und Klassen Ein Vergleich
13 OOP MIT DELPHI Delphi war früher "Object Pascal". Dieser Name impliziert eine Funktionalität, welche in der Welt der Programmierung nicht mehr wegzudenken ist: die objektorientierte Programmierung,
Programmieren I + II Regeln der Code-Formatierung
Technische Universität Braunschweig Dr. Werner Struckmann Institut für Programmierung und Reaktive Systeme WS 2016/2017, SS 2017 Programmieren I + II Regeln der Code-Formatierung In diesem Dokument finden
Einführung Datentypen Verzweigung Schleifen. Java Crashkurs. Kim-Manuel Klein May 4, 2015
Java Crashkurs Kim-Manuel Klein (kmk@informatik.uni-kiel.de) May 4, 2015 Quellen und Editoren Internet Tutorial: z.b. http://www.java-tutorial.org Editoren Normaler Texteditor (Gedit, Scite oder ähnliche)
Vererbung. Martin Wirsing. Ziele. Vererbung
2 Ziele Martin Wirsing en Begriff der einfachen verstehen und Redefinition von Oberklassenmethoden verstehen spolymorphie verstehen ie Klasse Object kennenlernen in Zusammenarbeit mit Michael Barth, Philipp
Faustregeln zu Zusicherungen
Faustregeln zu Zusicherungen Zusicherungen sollen stabil sein (vor allem an Wurzel der Typhierarchie) keine unnötigen Details festlegen explizit im Programm stehen unmissverständlich formuliert sein während
Javakurs für Anfänger
Javakurs für Anfänger Einheit 14: Generics Lorenz Schauer Lehrstuhl für Mobile und Verteilte Systeme Heutige Agenda Generische Klassen (Generics) Motivation Java Typ-Prüfung Warum also Generics? Generische
Klassen und Objekte. Einführung in Java. Folie 1 von Mai Ivo Kronenberg
Klassen und Objekte Einführung in Java Folie 1 von 28 12. Mai 2011 Ivo Kronenberg Inhalt Objekte Klassendefinitionen Datenelemente (Klassenattribute) Instanzieren von Objekten Konstruktoren Vergleich primitive
Grundlagen von Python
Einführung in Python Grundlagen von Python Felix Döring, Felix Wittwer November 17, 2015 Scriptcharakter Programmierparadigmen Imperatives Programmieren Das Scoping Problem Objektorientiertes Programmieren
Java Schulung (Java 2 Java Development Kit 5 / 6)
2. Grundlagen der Objektorientierung 2.1 Klassen, Attribute, Methoden Klassen Eine Klasse beschreibt als Bauplan Gemeinsamkeiten einer Menge von Objekten ist also ein Modell, auf dessen Basis Objekte erstellt
Einführung in die Programmierung mit VBA
Einführung in die Programmierung mit VBA Vorlesung vom 07. November 2016 Birger Krägelin Inhalt Vom Algorithmus zum Programm Programmiersprachen Programmieren mit VBA in Excel Datentypen und Variablen
Objektorientierte Programmierung
Stefan Brass: OOP (Java), 15. Überladene Methoden 1/22 Objektorientierte Programmierung Kapitel 15: Überladene Methoden Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester 2013/14 http://www.informatik.uni-halle.de/
Computeranwendung und Programmierung (CuP)
Computeranwendung und Programmierung (CuP) VO: Peter Auer (Informationstechnologie) UE: Norbert Seifter (Angewandet Mathematik) Organisatorisches (Vorlesung) Vorlesungszeiten Montag 11:15 12:45 Freitag
Elementare Konzepte von
Elementare Konzepte von Programmiersprachen Teil 1: Bezeichner, Elementare Datentypen, Variablen, Referenzen, Zuweisungen, Ausdrücke Kapitel 6.3 bis 6.7 in Küchlin/Weber: Einführung in die Informatik Bezeichner
Programmierung WS12/13 Lösung - Übung 1 M. Brockschmidt, F. Emmes, C. Otto, T. Ströder
Prof. aa Dr. J. Giesl Programmierung WS12/13 M. Brockschmidt, F. Emmes, C. Otto, T. Ströder Tutoraufgabe 1 (Syntax und Semantik): 1. Was ist Syntax? Was ist Semantik? Erläutern Sie den Unterschied. 2.
Vererbung. Vererbung von Methoden und Instanzvariablen. Vererbung als Realisierung einer is-a Beziehung.
Vererbung Unterklassen einer Klasse Vererbung von Methoden und Instanzvariablen Überschreiben von Methoden Vererbung als Realisierung einer is-a Beziehung. Informatik II: Objektorientierte SW-Entwicklung,
Deklarationen in C. Prof. Dr. Margarita Esponda
Deklarationen in C 1 Deklarationen Deklarationen spielen eine zentrale Rolle in der C-Programmiersprache. Deklarationen Variablen Funktionen Die Deklarationen von Variablen und Funktionen haben viele Gemeinsamkeiten.
Einführung in die Java- Programmierung
Einführung in die Java- Programmierung Dr. Volker Riediger Tassilo Horn riediger horn@uni-koblenz.de WiSe 2012/13 1 Wichtig... Mittags keine Pommes... Praktikum A 230 C 207 (Madeleine + Esma) F 112 F 113
Methoden (fortgeschritten) in C# - 1
Methoden (fortgeschritten) in C# - 1 Marc Satkowski 20. November 2016 C# Kurs Gliederung 1. Opertatoren Überladung 2. delegate 3. Anonyme Methoden delegate Lamda Ausdruck-Lamdas Anweisung-Lamdas Variablenbereich
7. Objektorientierte Softwareentwicklung/3. Informatik II für Verkehrsingenieure
7. Objektorientierte Softwareentwicklung/3 Informatik II für Verkehrsingenieure Überblick FOLGENDE BEGRIFFE/PRINZIPIEN SOLLTEN BEKANNT SEIN Objekte Klasse Attribute Fähigkeiten ZIEL DER HEUTIGEN LEHRVERANSTALTUNG
Java Einführung Abstrakte Klassen und Interfaces
Java Einführung Abstrakte Klassen und Interfaces Interface Interface bieten in Java ist die Möglichkeit, einheitliche Schnittstelle für Klassen zu definieren, die später oder/und durch andere Programmierer
VIII: Vererbung. Unterklassen einer Klasse. Vererbung von Methoden und Instanzvariablen. Überschreiben von Methoden
VIII: Vererbung Unterklassen einer Klasse Vererbung von Methoden und Instanzvariablen Überschreiben von Methoden Vererbung als Realisierung einer is-a Beziehung. Informatik I VIII: Vererbung 259 Beispiel:
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
Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein (kmk@informatik.uni-kiel.
Java Crashkurs Kim-Manuel Klein (kmk@informatik.uni-kiel.de) May 7, 2015 Quellen und Editoren Internet Tutorial: z.b. http://www.java-tutorial.org Editoren Normaler Texteditor (Gedit, Scite oder ähnliche)
Java Einführung Methoden in Klassen
Java Einführung Methoden in Klassen Lehrziel der Einheit Methoden Signatur (=Deklaration) einer Methode Zugriff/Sichtbarkeit Rückgabewerte Parameter Aufruf von Methoden (Nachrichten) Information Hiding
Objektorientierte Programmierung mit Python Polymorphismus und Vererbung. Eltern
Objektorientierte Programmierung mit Python Polymorphismus und Vererbung Eltern Kind Kind Kind Kind Prinzipien der objektorientierten Programmierung Vererbung Strukturierung von Klassen. Oberbegriffe beschreiben
Tutorium Java Ein Überblick. Helge Janicke
Tutorium Java Ein Überblick Helge Janicke 26. Oktober 2000 1 VORRAUSSETZUNGEN ZUM PROGRAMMIEREN MIT JAVA. 1 1 Vorraussetzungen zum Programmieren mit Java. Was braucht man, wenn man mit Java programmieren
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
Objekt-Orientierte Programmierung
Objekt-Orientierte Programmierung Ein OO-Programm modelliert eine Anwendung als eine Welt von Objekten, die miteinander in Beziehung stehen ( später). Ein Objekt kann andere Objekte erzeugen. Ein Objekt
8 Baum in perfekter Komposition
8 Baum in perfekter Komposition Die Implementierung des Binärbaums im letzten Kapitel wird mithilfe des Entwurfsmusters Kompositum optimiert. Knoten und Abschluss Bei der einfach verketteten Liste wurde
Werkzeuge zur Programmentwicklung
Werkzeuge zur Programmentwicklung B-15 Bibliothek Modulschnittstellen vorübersetzte Module Eingabe Editor Übersetzer (Compiler) Binder (Linker) Rechner mit Systemsoftware Quellmodul (Source) Zielmodul
Java Einführung Methoden. Kapitel 6
Java Einführung Methoden Kapitel 6 Inhalt Deklaration und Aufruf von Methoden Lokale und globale Namen (Bezeichner) Sichtbarkeit und Lebensdauer von Variablen in Methoden Überladen von Methoden 2 Methoden
Javaprogrammierung mit NetBeans. Variablen, Datentypen, Methoden
Javaprogrammierung mit NetBeans Variablen, Datentypen, Methoden Programmieren 2 Java Bezeichner Bezeichner: Buchstabe _ $ Buchstabe _ $ Ziffer Groß- und Kleinbuchstaben werden strikt unterschieden. Schlüsselwörter
Objective-C CheatSheet
App-Templates: Erstellt automatisch einen Navigation Controller mit editierbarem UITableView und DetailView, der bei Klick auf einzelne UITableViewCell angezeigt wird. Kreiert einen GLKitViewController