Regeln für Bezeichner Assoziativitäten (Klammerung) (annett.thuering@informatik.uni-halle.de / 2019) - Name für Variable, Methode, Datentyp rechtsassoziativ: Präfixoperatoren, bedingter Ausdruck, Aufbau eines Java-Programms Zuweisungsoperatoren public class Klassenname { - Folge von Buchstaben und Ziffern - beginnen mit einem Buchstaben linksassoziativ: alle anderen Operatoren public static void main(String[] args) { - $ und _ zählen als Buchstaben Prioritäten // Programmcode } - Groß- und Kleinschreibung wird unterschieden Pri Operatoren Bemerkung } - dürfen keine Schlüsselworte sein Variablendeklaration 1 o.a, i++,a[],f(),. Postfix-Operatoren Compiler Datentyp variablenname; 2 -x, !, ~, ++i Präfix-Operatoren javac Klassenname.java übersetzt Programm in Bytecode java Klassenname VM führt Bytecode aus z.B. int zahl; 3 new C(), Objekt-Erzeugung, Zu obigen Rahmenprogramm, muss der Dateiname int a, b, c; (type) x Cast dem Klassennamen entsprechen! Deklaration (Definition) mit Initialisierung 4 *, /, % Multiplikation, etc. int zahl = 5; Kommentare String name = "Rudi"; 5 +, - Addition, Subtraktion von // bis zum Ende der Zeile Daten einlesen 6 <<, >>, >>> Shift von /* bis */ eingeschlossener Block (mehrzeilig) Die Klasse Scanner 7 <, >, <=, >= kleiner, größer, etc. Ausgabe import java.util.Scanner; System.out.println(Ausgabe); mit Zeilenumbruch public class Klassenname { 8 ==, != gleich, verschieden System.out.print(Ausgabe); ohne Zeilenumbruch public static void main(String[] args) { 9 & bitweise UND z.B. Ausgabe: "Text1" + Variable + "Text2" Scanner ein = new Scanner(System.in); ganze Zahlen einlessen (Rückgabetyp int) 10 ^ bitweise XOR Primitive Datentypen - sind in die Sprache integriert z.B. izahl = ein.nextInt(); 11 | bitweise ODER - Größe, Wertebereich und Operationen sind definiert gebrochene Zahlen einlessen (Rückgabetyp double) z.B. dzahl = ein.nextDouble(); 12 && logisches UND Name Größe in Byte Wertebereich Zeichenketten einlessen (Rückgabetyp String) 13 || logisches ODER byte 1 (8 Bit) -27 - 27-1 z.B. wort = ein.next(); Zeile einlessen; inklusive Leerzeichen (Rückgabetyp String) 14 ?: bedingter Ausdruck short 2 (16 Bit) -215 - 215-1 z.B. zeile = ein.nextLine(); 15 ** Fehlerhafter Zuweisungen int 4 (32 Bit) -231 - 231-1 Die Klasse BufferedReader Ausdruck ** long 8 (64 Bit) -263 - 263-1 import java.io.*; public class Klassenname { float 4 (32 Bit) ±3.4*1038 public static void main(String[] args) Kontrollstrukturen throws IOException { Bedingte Anweisung (Falls … sonst ...) double 8 (64 Bit) ±1.79 * 10308 if (Bedingung) { BufferedReader ein = new BufferedReader char 2 (16 Bit) Unicode (new InputStreamReader(System.in)); // Anweisungen werden ausgeführt, Zeile einlessen; inklusive Leerzeichen (Rückgabetyp String) // falls Bedingung wahr ist boolean 1 (8 Bit) true, false } z.B. zeile = ein.readLine(); Automatische Typkonvertierung else { byte → short → int → long → float → double Zeichenketten (String) in Zahlen umwandeln // Anweisungen werden ausgeführt, String in ganze Zahl umwandeln (int izahl) char z.B. izahl = Integer.parseInt(zeile); // falls Bedingung nicht wahr ist Konstanten String in gebrochene Zahl umwandeln (double dzahl) } final Datentyp KONSTANTE = Wert; z.B. dzahl = Double.parseDouble(zeile); vorzeitiges Beenden einer Schleife - Elemente sind alle vom gleichen Datentyp 1/5 Fallunterscheidung (Auswahl) continue // Deklaration der Referenzvariablen switch (Variable) { - springt zum Ende des Schleifenrumpfes int [] zahlenfeld; case Wert1: // Einstiegspunkt für den Fall break (Abbruch) // Variable == Wert1 // Speicherplatz für Array anlegen - Schleife / switch wird an dieser Stelle verlassen und nächste zahlenfeld = new int[Länge]; // oder break; Anweisung hinter der Schleife / dem switch wird ausgeführt case Wert2: // Einstiegspunkt für den Fall // Variable == Wert2 Exceptions int [] zahlenfeld = new int[Länge]; break; - ArrayIndexOutOfBoundsException (ungültiger Index) … - StringIndexOutOfBoundsException (ungültige Position) // Deklaration + Initialisierung default: // Anweisungen, falls die - NullPointerException (Zugriff auf null – Referenz) int [] gerade = { 2, 4, 6, 8, 10 }; // Variable keinen der zur - NumberFormatException (String enthält keine Zahl) Länge des Arrays // Auswahl stehenden Werte - ArithmeticException (z.B. Division durch 0) zahlenfeld.length // enthält Exceptionbehandlung: Zugriff auf ein Element des Arrays } try { - Zugriff über Index Der Datentyp von Variable darf nur ein primitiver // Anweisungsblock - kleinster Index: 0; größter Index: Länge-1 Datentyp, String oder eine Wrapperklasse sein. } z.B. zahlenfeld[index] = 7; Wert1, Wert2, … sind Konstanten! catch (Ausnahme1) { mehrdimensionale Arrays Wiederholungen // Anweisungen zur Fehlerbehandlung In Java ist ein zweidimensionales Array eigentlich ein while – Schleife (solange ...) } eindimensionales Array, das selbst wieder Referenzen while (Bedingung) { catch (Ausnahme2) { auf eindimensionale Arrays als Elemente enthält. // Anweisungen, welche ausgeführt werden, // Anweisungen zur Fehlerbehandlung // solange die Bedingung erfüllt ist } - Anzahl der Klammerpaare bestimmen die Dimension } … int [][] matrix; // Deklaration 2 dim. do while – Schleife (mindestens einmal aber solange …) finally { int [][][] quader; // Deklaration 3 dim. do { // wird, wenn vorhanden, immer ausgeführt // Anweisungen, werden mindestens einmal } matrix = new int[5][10]; // 2 dim. // ausgeführt, und dann so oft wiederholt, Quader = new double[5][10][2]; // 3 dim. // solange die Bedingung erfüllt ist Methoden überladen } while (Bedingung); - überladene Methoden = Methoden mit gleichem Namen aber Länge des Arrays mit unterschiedlichen Parameterlisten innerhalb einer Klasse matrix.length // Größe der 1. Dimension for – Schleife (Spezialfall: Zählschleife) matrix[2].length // Länge der 2. Zeile for (Initialisierung;Bedingung;Schrittweite){ 1. Variante: unterschiedliche Anzahl der Parameter der 2. Dimension // Anweisungen 2. Variante: mindestens ein Parameter hat anderen Datentypen Zugriff auf ein Element des Arrays } matrix[0][0] = 7; // 2 dim - Zweck: semantisch ähnliche Aktionen für unterschiedliche quader[0][0][0] = 7; // 3 dim Beispiel: Schleife wird 10 mal durchlaufen Datentypen (Siehe Methode System.out.println(...)) for (int i = 0; i < 10; i++) { Kommandozeilenparameter // Anweisungen public void println() - werden beim Start des Programms an dieses übergeben } public void println(String s) - können über das Array args der main-Methode for each – Schleife für Arrays public void println(int x) abgerufen werden double[] a = new double[10]; ... java Programmname param1 param2 ... for (double x : a) { Referenztypen public static void main(String[] args) { System.out.println(x); Arrays eindimensionale Arrays System.out.println(args[0]); → param1 } Eigenschaften: - Elemente liegen im Speicher hintereinander System.out.println(args[1]); → param2 2/5 ... Methode und gibt den Wert des Ausdrucks zurück Konzepte der Objektorientierten Programmierung Zugriff auf Komponenten eines Objektes // Konstruktor - Zugriff erfolgt über den Operator . NamederKlasse (Parameterliste) { 1. Konzept: Kapselung von Daten und deren verarbeitenden … Funktionen (Klassen) Aufbau einer Klasse Objektname.Attribut bzw. } class NamederKlasse { Objektname.Methode(Parameterliste) Zugriffsrechte // Attribute (Variablen/Eigenschaften/ Die Klasse Object - stehen direkt (private, public) / oder indirekt // Instanzvariablen) - Basisklasse für alle Klassen des Programms (package default) vor jedem Attribut // Methoden (Verarbeiten der Attribute) private } - enthält folgende wichtigen Methoden: - erlaubt den Zugriff nur für Objekte dieser Klasse Kopie eines Objektes erzeugen package default Klasse ist ein Datentyp (gibt vor, wie der Speicher für eine protected Object clone() - erlaubt den Zugriff für alle Objekte aus dem gleichen Paket Instanz (Objekt) aussehen soll) Vergleich zweier Objekte public boolean equals(Object o) - erlaubt den Zugriff für Objekte aus einem beliebigen Paket Klasse = eine Schablone für viele Objekte! this @Override - enthält eine Referenz auf das Objekt selbst Objekte / Instanzen einer Klasse public boolean equals (Object o) { Über diese kann auf alle Komponenten des Objektes Referenzvariable deklarieren if (o == null) {return false;} zugegriffen werden. NamederKlasse objektname; if (! (o instanceof NamederKlasse)) {return false;} this.Attribut bzw. Objekt erzeugen und der Refernzvariablen zuweisen: objektname = new NamederKlasse(); if (o == this) {return true;} this.Methode(Parameterliste) Klassenattribute/Klassenmethoden (static) Referenzvariable: Objekt: // Typumwandlung von o mit (cast) - existieren nur einmal für alle Objekte einer Klasse NamederKlasse oneu = (NamederKlasse) o; - existieren auch dann, wenn es kein einziges Objekt 1234 // Attribute der Klasse gibt // Eigener Vergleich mit oneu Objektname // Methoden ... static-Methoden können nur auf andere } static- Komponenten zugreifen! 1234 (Adresse) Operator new: Reservieren des Speicherplatzes Liefert String-Darstellung eines Objektes class NamederKlasse { Methoden String toString() int zahl1; - dienen hauptsächlich zur Kommunikation mit dem Objekt static int zahl2; @Override (z.B. Werte an das Objekt übergeben [Zustand des Objektes ... ändern] oder Attribute aus dem Objekt auslesen [Zustand des public String toString() { return "Zeichenkette"; } Objektes abfragen]) → bestimmen das Verhalten } A = new NamederKlasse(); Rückgabetyp Methodenname(Parameterliste){ Konstruktoren B = new NamederKlasse(); // Anweisungen - spezielle Methoden C = new NamederKlasse(); - dienen zum Initialisieren eines Objektes (der Attribute // bei Bedarf Rückgabe eines Wertes bzw. des Speicherplatzes) A B C // return Ausdruck; - werden direkt beim Erzeugen des Objektes aufgerufen } - Klasse kann mehrere Konstruktoren enthalten zahl1 zahl1 zahl1 Methode gibt keinen Wert zurück Eigenschaften: zahl2 → Rückgabetyp = void 1. besitzen keinen Rückgabetyp 2. haben den gleichen Namen wie die Klasse Zugriffsmöglichkeiten auf das gemeinsame Klassenattribut: return-Anweisung wertet den Ausdruck aus, beendet die A.zahl2 B.zahl2 3/5 C.zahl2 NamederKlasse.zahl2 Fahrzeug F1 = new Auto(); // Polymorphie Klasse nicht mehr überschrieben werden Vererbung / Erweitern Konstruktoren - final definierte Klassen können nicht vererbt werden 2. Konzept: Übertragen von Attributen und Methoden auf - Konstruktoren der Basisklasse sind in der Subklasse nicht Überschreiben von Methoden eine andere Klasse sichtbar, obwohl sie enthalten und public sind - Anpassen der Methode an die Anforderungen der Zugriffsrechte – Fortsetzung - Es werden immer die Konstruktoren der Basisklasse Subklassen protected (bzw. der gesamten Hierarchie) aufgerufen - Methode muss in der Subklasse die gleiche Signatur - erlaubt den Zugriff für Objekte aus dem gleichen Paket und - Reihenfolge: Konstruktor der Basisklasse zuerst, dann die (gleicher Name, Parameterliste) und einen kompatiblen für Objekte der Subklassen aus anderen Paketen Konstruktoren entlang der Hierarchie Rückgabetyp besitzen Basisklasse (Oberklasse) - expliziter Aufruf eines Konstruktors der Basisklasse erfolgt - Überschriebene Methoden der Basisklasse sind nur noch class BasisKlasse { mit super(Parameterliste); aus den Methoden der Subklasse und dort über die - Der explizite Aufruf des Konstruktors der Basisklasse ist explizite Angabe von super erreichbar private Komponenten immer die erste Anweisung im Konstruktor der Subklasse class BM { protected Komponenten Referenz super public int zb; - erlaubt in einem Objekt einer Subklasse den Zugriff auf die public BM() {zb = 2;} package default Komponenten geerbten Komponenten der unmittelbar übergeordneten @Override public String toString () { Basisklasse return "zb = " + zb; } public Komponenten - erlaubt somit den Zugriff auf Konstruktoren, } } überschriebe Methoden und verdeckte Attribute class SM extends BM { Subklasse (Unterklasse) verdeckte Attribute public int zs; Eine Subklasse erweitert die Basisklasse um zusätzliche - Attribute der Subklasse, welche den gleichen Namen haben, public SM() {zs = 20;} Attribute und Methoden. wie Attribute der Basisklasse, verdecken in den Methoden der @Override public String toString () { Subklasse die geerbten Attribute der Basisklasse return super.toString() + class SubKlasse extends BasisKlasse { class B { "\n zs = " + zs; } zusätzliche Attribute und Methoden public int a; } public B() {a = 5;} SM testSM = new SM(); } Zugriff auf Komponenten der Basisklasse System.out.println(testSM); zb = 2 class S extends B { public int a; // Polymorphie zs = 20 protected Komponenten public int basis_a; BM testBMSM = new SM(); package default Komponenten public S() { System.out.println(testBMSM); a = 10; abstrakte Basisklassen public Komponenten basis_a = super.a;} - Definieren von Grundeigenschaften in einer Basisklasse } } - von einer abstrakten Klasse können keine Instanzen Beispiel: Realisierung von Hierarchien S testS = new S(); erzeugt werden System.out.println(testS.a); → 10 - abstrakte Basisklasse kann abstrakte Methoden = Methoden ohne Implementierung enthalten Fahrzeug System.out.println(testS.basis_a); → 5 abstract class Abasis { ist ein // Polymorphie int z; B testBS = new S(); Bus Auto Motorrad ... Traktor System.out.println("\n " + testBS.a);→ 5 abstract public void print (int a); public int get_z () {return z;} Ein Bus ist ein Fahrzeug. final - Modifikator } - final definierte Methoden können in der abgeleiteten - Klasse mit abstrakten Methoden, muss selbst als Jede Instanz der Subklasse ist auch eine Instanz der Basisklasse abstract definiert werden ArrayList<Datentyp> aliste; > 0 falls Objekt selbst größer als obj2 - eine abstrakte Methode kann nicht private sein aliste = new ArrayList<Datentyp>(); class Kl implements Comparable<Kl>{ generische Klassen 4/5 Methoden der Klasse ArrayList private int wert; - Schablone für eine Menge von Klassen Element an einer bestimmten Position ausgeben ... aliste.get(Position) @Override - Klassen der Menge unterscheiden sich nur im Datentyp einiger Attribute (generische Attribute) Element am Ende der Liste einfügen public int compareTo(Kl obj2) { aliste.add(Element) ... class A { class B { class C { } Element mit Positionsangabe einfügen int att; String att; Person att; } ... ... ... aliste.add(Position, Element) } } } Alle Elemente einer anderen Liste einfügen Verwendung z.B. Sortieren: aliste.addAll(Position, liste2) import java.util.Collections; Instanz erzeugen: Element an Position verändern ... A aobj = B bobj = C cobj = aliste.set(Position, Element) ArrayList<Kl> klliste; new A(); new B(); new C(); Element löschen / Liste leeren klliste = new ArrayList<Kl>(); aliste.remove(Element) / aliste.clear() ... - in generischer Klasse wird ein Platzhalter für einen Datentyp Collections.sort(klliste); an betroffenen Stellen eingefügt Element bestimmter Position löschen aliste.remove(Position) ... class<Platzhalter> ABCgen { Gibt Größe des Arrays zurück Klassen für Zeichenketten Platzhalter att; aliste.size() String ... Prüft, ob bestimmtes Element enthalten ist (liefert true, false) Inhalt kann nicht mehr verändert werden! public Platzhalter getAtt () {return att;} aliste.contains(Element) (Methoden replace, toLowerCase ... erzeugen public void setAtt (Platzhalter w) { Liefert den Index eines Elementes neue Strings) att = w; } aliste.indexOf(Element) @Override public boolean equals(Object o){ if(o instanceof ABCgen<?>) { Interfaces / Schnittstellen String satz = "Viel Spaß!"; ABCgen<?> p = (ABCgen<?>) o; - Interface schreibt einer Klasse vor, welche Methoden die Zugriff auf ein Zeichen / Länge des Strings ... Klasse implementieren muss char charAt(int index) / int length() } - Methoden sind immer öffentlich und abstrakt (ohne Liefert 1. Position, von ch (Zeichen) / st (String) im String } Schlüsselworte public, abstract) int indexOf(int ch) bzw. (String st) - deklarierte Attribute sind implizit static, final und true, falls die Zeichenkette st im String enthalten ist - generische Klasse kann nur eingeschränkt Funktionalitäten public und müssen Initialisiert werden (→ Konstanten) boolean contains(String st) auf generischen Attributen bereitstellen - Interfaces können auch an andere Interfaces vererbt werden Vergleich zweier Strings; true, falls beide Strings gleich - bei Erzeugung einer Instanz von einer generischen Klasse muss der Datentyp, für welchen der Platzhalter steht, - durch Interfaces wird Mehrfachvererbung möglich boolean equals (Object anObject) angegeben werden Subklassen können nur eine Basisklasse erweitern, aber Liefert Teilstring (ohne das Zeichen an Position end) - Datentyp muss selbst ein Referenztyp sein mehre Interfaces implementieren! String substring(int begin, int end) Beispiel für generisches Interface: Ersetzen eines Zeichens ABCgen<Integer> aobj =new ABCgen<Integer>(); String replace(char old, char new) ABCgen<String> bobj = new ABCgen<String>(); Vergleich zweier Objekte: Umwandeln in Kleinbuchstaben / Großbuchstaben ABCgen<Person> cobj = new ABCgen<Person>(); String toLowerCase() / toUpperCase() interface Comparable<T> { ArrayList int compareTo (T obj2); Stringbuilder / StringBuffer - speichert Elemente in einem internen Array - veränderbare Zeichenketten } - Größe im Vergleich zu Arrays veränderbar import java.lang.StringBuilder; import java.util.ArrayList; Rückgabewert: 0 bei Gleichheit ... ... < 0 falls Objekt selbst kleiner als obj2 StringBuilder satz; satz = new StringBuilder("Viel Spaß!"); 5/5