Typisch Männer
Nach dem, was ich von der letzten Vorlesungsstunde gehört habe, wird die Klausur sehr einfach. Das soll natürlich niemanden in seinem Lernen bremsen. Ich habe den ganzen Kram schließlich schon ein paar Mal öfter gehört. Und die eine oder andere Frage scheint doch schon spezieller zu werden. Liskovsches Substitutionsprinzip und Synchronisation (niemals auf Immutables synchronisieren, wenn die verändert werden...) sollte man kennen, glaube ich. Generics sollten nach der heutigen Erklärung sogar Blondinen Männer verstanden haben.
Jetzt hoffe ich bloß noch, dass ich bei der Korrektur eine jungfräuliche Aufgabe erhalte und mich nicht nicht bei einer schon teilweise bearbeiteten dazusetzen muss. Das wäre schlimm, ich bewerte doch so gerne streng.
Rangoo in Info-B(log)
30.06.10, 22:17 Uhr
kein Kommentar - kommentieren
Ein bisschen farblos
Rangoo in Info-B(log)
26.06.10, 14:31 Uhr
kein Kommentar - kommentieren
Eine kleine Rotations-Daumenregel
Daher eine kleine Daumenregel für die Teil-Rotationsmatrizen, wenn man um eine beliebige Achse rotieren soll:
- Der Kosinus steht auf der Hauptdiagonalen (altbekannt).
- Die Achse, um die rotiert wird, hat einen 1-Eintrag (altbekannt).
- Das Minus beim Sinus steht in der Zeile, die hinterher 0 sein soll.
- Die Koordinate, die 0 werden soll, ist die Gegenkathete.
Rangoo in Info-B(log)
05.06.10, 13:02 Uhr
kein Kommentar - kommentieren
Generics, Wildcards und Bounds
Es können zwei Arten von Typeinschränkungen (Bounds) unterschieden werden:
1. Upper Bounds (in Java durch Verwendung von "extends"): Der Typ muss der angegebenen Bound entsprechen oder eine Subklasse davon sein. Die Bound ist also in der Klassenhierarchie eine Beschränkung nach oben.
2. Lower Bounds (z.B. in Java: Box<? super Person>): Der Typ muss der angegebenen Bound entsprechen oder eine Superklasse dazu sein. Im Java-Beispiel wäre an der Stelle des ? der Typ Person oder die Superklasse Object möglich.
Hierbei wird der Eindruck erweckt, es sei möglich, den parametrisierenden Typen einer Klasse sowohl durch eine obere (upper) als auch eine untere (lower) Klasse in seiner Vererbungshierarchie beschränken. Dies ist nicht der Fall. Der Einsatz von Bounds bei der Klassendeklaration (public class Klasse<T>) ist beschränkt auf Upper Bounds. Es ist also nur möglich, das extends-Schlüsselwort zu verwenden. Auf diese Weise kann die Klasse zum Beispiel sicherstellen, dass sie bestimmte Methoden an den parametrisierten Objekten aufrufen kann. [Bounded Type Parameters]
Der Einsatz des super-Schlüsselwortes in seiner hier genutzten Bedeutung ist beschränkt auf die Erstellung von Referenzen parametrisierter Klassen. Hier ist es möglich, durch Klasse<? super Ding> k; eine Einschränkung zu erzwingen. Das benutzte ? nennt sich hierbei Wildcard. Solche Wildcards werden immer dann eingesetzt, wenn man mit parametrisierten Klassen arbeitet, von denen man sich nicht sicher sein kann, welchen Parameter sie besitzen werden.
Nötig sind solche Wildcards, weil die Auswertung von Generics statisch zur Compile-Zeit geschieht. Entsprechend muss ein Entwickler die Möglichkeit haben, die Typhierarchie weiter gefasst zu beschreiben, denn die Parameter werden auf Identität getestet. Das bedeutet, dass eine Codezeile wie Klasse<Object> k = new Klasse<Integer>(); zu einem Fehler führt. Korrekt muss es Klasse<? extends Object> k = new Klasse<Integer>(); oder Klasse<? super Integer> k = new Klasse<Integer>();heißen.
Die praktischen Anwendungen für eine lower bound sind eher rar gesät. Upper bounds hingegen werden bei dynamischer Programmierung häufiger benötigt, wie schon das kurze Beispiel eben belegt. Der Fall einer upper bound wird wahrscheinlich der passendere sein.
Sun Java Tutorials hat geschrieben:Specifically, you learned that generic type declarations can include one or more type parameters; you supply one type argument for each type parameter when you use the generic type. You also learned that type parameters can be used to define generic methods and constructors. Bounded type parameters limit the kinds of types that can be passed into a type parameter; they can specify an upper bound only. Wildcards represent unknown types, and they can specify an upper or lower bound. During compilation, type erasure removes all generic information from a generic class or interface, leaving behind only its raw type.
Rangoo in Info-B(log)
02.06.10, 20:19 Uhr
kein Kommentar - kommentieren
Das kann nur eine 1,0 werden
Mit der Markteinführung des iPhones von Apple rückte im Smartphone-Markt ein neuer Aspekt in Bezug auf die Nutzerbindung in den Fokus der Öffentlichkeit: Der App-Store, eine von Apple betriebene und moderierte Verkaufsplattform für Drittanbieter-Software, ermöglichte es Besitzern eines Apple-Mobilgeräts - iPhone, iPod oder iPad -, dieses mit einer Vielzahl von zusätzlichen Funktionen zu erweitern, indem sie dort entsprechende Programme herunterladen konnten.
Die Eröffnung des App-Stores ging einher mit der Bereitstellung des iPhone-SDKs, das es Entwicklern ermöglicht, auf Basis eines umfangreichen Frameworks auf die besondere Hardware zugeschnittene Anwendungen zu entwerfen. Die Idee einer explizit auf Mobilgeräte zugeschnittenen API war nicht neu, schon zuvor war auf vielen Handys die Java Micro Edition verfügbar. Der App-Store ermöglichte allerdings eine zentrale Sammelstelle für die verfügbare Software, die zudem noch bequem über das Gerät selbst erreicht werden konnte. Zusammen mit dem überwältigenden kommerziellen Erfolg des iPhones sind dies die Grundlagen, weshalb die Entwicklung von Software für Mobilgeräte in den letzten Jahren einen bedeutenden Einfluss auf die Softwareentwicklung genommen hat.
Also ganz ehrlich, wenn in den ersten zwei Absätzen meiner Diplomarbeit so oft die Wort Apple und i... fallen wie in Nuebauers halber Bachelorarbeit, kann ich doch quasi nur eine 1,0 bekommen. Eigentlich bräuchte ich gar nicht mehr abgeben als diese paar Sätze.
Rangoo in Info-B(log)
29.05.10, 13:24 Uhr
3 Kommentare - kommentieren
Sie haben Ihr Ziel erreicht
Rangoo in Info-B(log)
27.05.10, 19:02 Uhr
1 Kommentar - kommentieren
Ein Update? Wehe!
Rangoo in Info-B(log)
20.05.10, 22:33 Uhr
kein Kommentar - kommentieren
Eclipse in Tastaturkürzeln
Organize Imports (Strg + Shift + O)
Kein Mensch weiß heute noch, dass Collections im Paket java.util liegen. Die Funktion, Klassenimporte automatisiert durchzuführen, ist wahrscheinlich nach dem Speichern die am häufigsten durchgeführte. Ein kurzer Tastendruck und die unbekannten Klassen sind plötzlich bekannt. Bei Namenskonflikten bietet Eclipse außerdem eine Auswahl an. Hat man nur eine Klasse zu importieren, kann man sich auch mit Strg + Shift + M behelfen.
Format Source Code (Strg + Shift + F)
Im Gegensatz zum Import wird der Code-Formatter viel zu selten benutzt, dabei sollte er eigentlich am besten immer direkt vor dem Speichern einmal ausgeführt werden. Die Tastenkombination formatiert den Quelltext nach den Voreinstellungen des Programms oder persönlichen Wünschen (Window / Preferences / Java / Code Style / Formatter / Edit). Endlich könnte man sich an Code-Konventionen halten...
Zeilen auskommentieren (Strg + / oder Strg + Shift + C)
Die richtige Kombination für den Speedprogrammierer. Oder den Anfänger. Wenn man mal wieder Mist gebaut hat (oder testen möchte, ob man Mist gebaut hat), kann man, statt jede Zeile einzeln auszukommentieren, einfach die gewünschten Zeilen markieren und mit einer dieser Kombinationen auskommentieren. Oder wieder einkommentieren.
Refactoring: Rename (Alt + Shift + R)
Richtig: Sprechende Variablennamen, jeder Tutor will sie. Was tun, wenn man aber mal wieder nur die Variablen a bis bz im Code hat? Einfach mit dem Cursor draufgehen, Alt+Shift+R drücken, einen vernünftigen Namen eintippen und mit Enter übernehmen. Funktioniert mit Variablen, Methoden und Klassen und ändert den Namen an allen Stellen im Quelltext.
Content Assist (Strg + Leertaste)
Welche Methoden hat noch mal ein String? Zum Glück blendet Eclipse ein Fenster mit Methodenvorschlägen ein. Aber wenn man einmal nicht richtig aufpasst, ist es weg. Was tun? Einfach diese Tastenkombination nutzen und Eclipse zeigt, Was man an dieser Stelle alles sinnvoll eintippen konnte.
Das waren die Top 5 der beliebtesten Eclipse-Shortcuts. Traurig aber wahr: Ein Shortcut für "Generate Javadoc with meaningful description" existiert leider nicht. Aber mit Alt + Shift + J kann man wenigstens das Grundgerüst erstellen lassen.
Rangoo in Info-B(log)
19.05.10, 18:12 Uhr
2 Kommentare - kommentieren
Das Liskovsche Substitutionsprinzip
Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.
Wann kommt nun der gemeine Programmierer mit dem Liskovschen Substitutionsprinzip in Berührung? Fragte man ihn, würde er müde mit dem Kopf schütteln und bestreiten, jemals etwas mit so einem Konstrukt zu tun gehabt zu haben. In Wirklichkeit hat er es aber wahrscheinlich einfach nur nicht gemerkt.
Was genau sagt das Substitutionsprinzip jetzt eigentlich aus?
Kurz zusammengefasst lässt es sich so sagen: Jeder Untertyp muss alle Funktionalitäten erhalten, die bereits der Obertyp bereitgestellt hat. Er kann also keine Fähigkeiten und Eigenschaften verlieren, sondern ausschließlich dazulernen. Sprechen wir nun über die Javawelt, fordert Frau Liskov also, dass jede Unterklasse mindestens die Methoden (strenger: Funktionalitäten) ihrer Elternklasse bereitstellen muss.
Wieso sollte man sowas tun?
Auch in der Welt der Javaprogramme ist es so, dass nicht immer alles gehalten wird, was man so verspricht. Die Möglichkeit, an die Stelle einer Klasse auch immer Instanzen von Subklassen treten zu lassen, zwingt uns praktisch dazu, uns im Codegerüst an das Substitutionsprinzip zu halten. Sähe unser Verstand vor, dass man mit einem Hund spazierengehen muss, käme es sicher zu einem Fehler, wenn wir dies mit einer Subklasse Chihuahua plötzlich gar nicht mehr ginge.
Und es geht gar nicht ohne?
Der B.Sc. würde sagen: Alles kann, nichts muss. Das Substitutionsprinzip ist - ja richtig - ein Prinzip, kein Gesetz. Nur eine strikte Vererbung würde die Umsetzung wirklich erzwingen können. In Java können wir durch Überschreiben die internen Funktionalitäten immer ändern: Gilt "Beim Spazierengehen entleert der Hund seine Blase" (schöner Euphemismus) für alle Hunde, können wir dennoch das Spazierengehen beim Chihuahua so gestalten, dass er nur bellt und nicht pinkelt.
Anders ist es mit den "Grundfunktionen", die ein Objekt zur Verfügung stellt, also den definierten Operationsschnittstellen. Ich kann in Java zwar, wie schon gesagt, interne Funktionalitäten entfernen, nicht aber die öffentlichen Deklarationen (um im Beispiel zu bleiben: auch wenn er nicht pinkelt, Spazierengehen muss man auch mit einem Chihuahua können). Eine einmal bereitgestellte Methodensignatur muss auch in allen Unterklassen des Objekts vorhanden sein.
Was sind Kovarianz, Kontravarianz und Invarianz?
Im Zusammenhang mit dem Substitutionsprinzip betrachtet man meistens die Varianzen in Eingabe und Rückgabe von Methoden. Was ist nun die genaue Bedeutung dieser Varianztypen?
Kovarianz bedeutet, dass sich ein Eingabeparameter (oder die Rückgabe) der Methode mit der Vererbungshierarchie ändert. Anders gesagt: Betrachte ich eine Subklasse meiner Klasse, so ist auch der Parameter eine Subklasse meines Eingabeparameters.
Kontravarianz ist das genau Gegenteil. Betrachte ich wieder den Eingabeparameter einer Methode, so ist dieser kontravariant, wenn in meiner Subklasse als Eingabeparameter eine Oberklasse meines Eingabeparameters benutzt wird. Für die Rückgabetypen gilt es analog.
Invarianz ist der einfachste Fall. Der Rückgabetyp (oder Typ des Parameters) einer Methode bleibt auch in der Subklasse exakt der gleiche.
Wo ist der Bezug zum Substitutionsprinzip?
Mit Hilfe der Varianzen lässt sich beschreiben, wie sich Eingabe und Rückgabe einer überschriebenen Methode ändern dürfen, ohne das Substitutionsprinzip zu verletzen, wenn wir Klassen ableiten. Es gilt dabei immer zu beachten, dass die Subklasse mit ihrer Methode genauso eingesetzt werden soll wie die Oberklasse.
Zuerst die Eingabeparameter: Bleibt der Parametertyp unverändert, ist natürlich alles in Ordnung, denn die Methode der Unterklasse kann exakt das verarbeiten, womit schon die Oberklasse umgehen konnte. Bei Kontravarianz ist dies ähnlich, hier hat man sogar einen Funktionszuwachs. Konnte die Methode zuvor nur eine bestimmte Klasse verarbeiten, kommen jetzt außerdem die Oberklasse und alle Schwesterklassen in Frage. Anders ist es bei der Kovarianz: Konnte ich zuvor alle Objekte einer bestimmten Klasse übergeben, ist es mir jetzt nur noch möglich, die Objekte einer bestimmten Subklasse bearbeiten zu lassen. Das würde das Substitutionsprinzip verletzen.
Beim Return-Typ verhält es sich ein wenig anders. Auch hier muss die Invarianz nicht näher betrachtet werden. Kovarianz und Kontravarianz hingegen vertauschen ihre Rollen. Hat mir die Methode der Oberklasse ein Objekt einer bestimmten Klasse zurückgegeben, bekomme ich bei der Kontravarianz nur noch ein allgemeineres Objekt. Wenn ich nun weiterarbeiten möchte, könnten mir plötzlich Methoden fehlen, die früher wie selbstverständlich vorhanden waren. Bei Kovarianz dagegen bekomme ich eine Unterklasse des ursprünglichen Rückgabetyps. Das bedeutet, alle ursprünglichen Methoden sind vorhanden, mit etwas Glück bekomme ich sogar ein Objekt, das noch viel mehr kann als zuvor. Kovarianz in der Rückgabe erfüllt also das Substitutionsprinzip.
Unterstützt denn Java das Substitutionsprinzip bei Ein- und Rückgabe?
Auf jeden Fall. Java ist bei den Eingabeparametern allerdings noch strenger als nötig. Eine Methode wird nur dann wirklich überschrieben, wenn die Methoden-Parameter in der Subklasse exakt mit denen in der Oberklasse übereinstimmen. Bei Kontravarianz liegt für Java eine unterschiedliche Signatur vor, weshalb die Methode nur überladen wird.
Rangoo in Info-B(log)
06.05.10, 18:15 Uhr
1 Kommentar - kommentieren
(M)ein kleiner Java-Style-Guide
- Variablen und Konstanten
- Die Namen von Konstanten, Klassenvariablen, Attributen und Parametern sollten ihren Inhalt und Verwendungszweck beschreiben - "sprechende" Variablennamen, wie man so schön sagt: name, source. Ein-Buchstaben-Bezeichnungen sind für Wegwerfvariablen reserviert.
- Variablennamen beginnen immer mit einem Kleinbuchstaben. Ist der Variablenname aus mehreren Wörtern zusammengesetzt (listenerList, myLittleBrother), so werden die Worte ab dem zweiten mit einem Großbuchstaben begonnen.
- Konstantennamen werden durchgehend groß geschrieben: PI. Besteht die Konstante aus mehrern Worten, wird sie durch Unterstriche verbunden: MAX_VALUE.
- Pakete, Klassen, Interfaces, Methoden
- Paketnamen sollten durchgehend klein geschrieben werden und immer nur aus einzelnen Wörtern bestehen. Bei großen Projekten wird die "umgedrehte Domain" des Herstellers als Top-Packages empfohlen: de.monarchy.
- Klassen- und Interfacenamen sollten immer Substantive sein und mit einem Großbuchstaben beginnen (Classname). Auch Klassennamen sollten ihren Zweck beschreiben und bei zusammengesetzten Wörtern jedes Wort mit einem Großbuchstaben beginnen, z.B. PersonalChangeListener.
- Methodennamen sind Verben. Wie bei Variablen sollten sie mit einem Kleinbuchstaben beginnen und bei Wortzusammensetzungen wie buttonClicked die inneren Worte mit einem Großbuchstaben beginnen lassen.
- Formatierung
- Beim Aufbau einer Javaklasse sollte man sich an folgende Reihenfolge halten: Paketname, Imports, Klassendeklaration, Klassenvariablen und -Konstanten, Instanzvariablen, Konstruktoren, Methoden. Variablen und Methoden sollten dabei in logischer Hinsicht gruppiert werden.
- Zeilen sollten maximal 80 Zeichen lang sein. Passt ein Ausdruck nicht in eine Zeile, so kann man (in dieser Reihenfolge) an folgenden Punkten einen Umbruch machen: nach einem Komma, nach einem Punkt, vor einem Operator. Eine umgebrochene Zeile sollte immer vier Zeichen weiter eingerückt sein als ihre "Elternzeile".
- Einrückungen jedes Block sollten immer zwei Leerzeichen betragen.
- Klammern von Methoden werden ohne Leerzeichen an die Methode angefügt (doIt()). Eine öffnende geschweifte Klammer sollte in der gleichen Zeile wie das zugehörige Statement stehen (mit einem Leerzeichen getrennt: if (true) {, die zugehörige schließende Klammer steht allein und ist ebenso weit eingerückt wie die öffnende Zeile.
- Nach Operatoren sollte immer ein Leerzeichen stehen: int x = a + add(i, j);
- Kommentare
- Klassen, Konstanten, Klassen- und Instanzvariablen und Methoden müssen mit Javadoc kommentiert werden. Dabei sollte der erste Satz eine zusammenfassende Beschreibung sein, Details folgen danach.
- Die Funktion einzelner Blöcke im Code sollte jeweils kurz in einem Kommentar erklärt werden.
- Normale Kommentare sollten entweder in eigener Zeile stehen oder weit genug nach rechts eingerückt werden, um aus dem umstehenden Code leichter herausgesehen werden zu können.
Rangoo in Info-B(log)
14.04.10, 19:46 Uhr
3 Kommentare - kommentieren
Spannung, Spiel und Schokolade
Meine erste Aussage: Nuebauer hat in Computergrafik bereits vor der ersten Vorlesung das erste Aufgabenblatt veröffentlicht. Das setzt neue Maßstäbe in Sachen Geschwindigkeit, speziell wenn man vorher hin und wieder mal das Gefühl hatte, dass ein DBS-Blatt erst mit mehrtägiger Verspätung erschienen ist (fieser Seitenhieb, musste sein).
Rangoo in Info-B(log)
06.04.10, 00:07 Uhr
2 Kommentare - kommentieren
