uio--WebPageMain-Module

JAVA-B1 Klassen public class instance System.out.println() {@link Klasse} {@param Klasse} getClass().getSimpleName() extends Objekte Interfaces FAQ classes Erweitern von Klassen mit extends finale Konstanten (@see Finalisierung von Klassen ) Polymorphismus Nested Classes @Override Annotation innere Klassen lokale Klassen anonyme Klassen Lamda Expressions FAQ Nested Classes

Klassen im Detail Overview return-Statements return & void return bei primitiven Typen return bei Objekten return-Statements von Methoden mit/ohne return Rückkehr ohne return Rückkehr über return throws Exception Kopie oder Referenz Covariant Return Types this this mit Objekt-Feldern this mit Methoden und im Konstuktor Zugriffsmodifikatoren public protected private Class Member static public static final PI Initialisierung Initialisierung von Feldern Initialisierung von Klassenfeldern Static Block Lambda-Expressions Methoden-Referenzen

Enumerationen und enum-Types Enumerationskonstanten Enumerationen mit Werten Samstag/Sonnabend Example @! Enumerationen FAQ Enum @!Descr/Exmpl/Index

Interfaces Einfache Interfaces (Marker) Interfaces mit Methoden Default-Methoden static Interfaces FAQ Vererbung / Inheritance Vererbung / Inheritance super Keyword method-overriding-and-hiding hiding-of-fields object-as-superclass Finalisierung Finale Klassen und Methoden Finale Methoden Finale Utility-Klasse "IdGenerator" "Template-Methode"-Pattern DataProcessor process(){ r(), p(), w() } Composition-over-Inheritance abstract Abstrakte Klassen und Methoden Beispiel Abstrakte Klassen und Methoden abstract Implementierungsklassen FAQ Vererbung Kein this in super(..) Verhindern Überschreiben von Membern

Generics Generische Programmierung Generische Typparameter Generische Klassen Generische Interfaces Generische Methoden Generische Felder Generische Collection (ArrayList) Diamond Operator Generische Arrays Example Beispiel "GenerischerSpeicher" Ring-Speicher-Algorithus mit generischem Array Beispiel: GenerischePerson mit Berufsgruppe Beispiel: Berufsgruppe mit Static/Non-Static Nested Classes

Modularisierung Package Overview Package Structure Package Info

Modules Overview Setup Setup Module Info

Java New Features Java 8+ Java Record Record Syntax Record Demo Herkömmliche POJOs Lösung mit Records Records Zusammenfassung

INDEX

Overview

Klassen | Klassen im Detail

Lambda-Expressions sind seit JAVA 15 in der Entwicklung nicht mehr wegzudenken, ermögliche Sie doch eine leichtere Lösung von Problemstellungen die mit einer herkömmlichen, auf Klassen basierten Objektorientierung so nicht möglich war.

In diesem Themenblock befasen wir uns mit einer Liste von Ansätzen, wie und wann man letztendlich zu Lambda-Ausdrücken kommt und diese erfolgreich einsetzen kann.

return-Statement

Klassen | return-Statement von Methoden

Methoden kehren, nachdem man die aufgerufen hat, immer zu dem Code zurück, von welchem diese Methode aufgerufen wurde.

Diese Rückkehr erfolgt in folgenden Varianten:


Vollständiger Durchlauf der Methode

java-return-statement-of-methods-without-return

Das ist im Prinzip der Regelfall jeder Methode und sinngemäß auch jedes Lambda-Ausdrucks: Alle Zeilen des Programmcodes werden durchlaufen.


 
class A {

 public static void main(String[] args) {
 A.a(); // (1)
 }

 // Methode wird von (1) angesprungen. 
 // Lokale Variablern werden lexikalisch im Scope angemeldet. 
 // Alle Statements der Methode werden durchlaufen.
 // Einen Rückgabetyp gibt es wegen void gar nicht.
 // Die Methode kehrt zu (1) zurück. 
 // Wert lokale Wert von a geht verloren.
 
 public void a() {
 int a=12; 
 System.out.println("a:"+a); // 12
 } 
}

 

Methoden | Erreichen eines return-Statements

java-return-statement-of-methods-reaching-return

Mit return können wir die Methode vorzeitig verlassen, müssen aber dann sicherstellen, dass die Methode immer einen Wert des korrekten Typs zurückgibt. Im Falle von void allerdings keinen: Dort steht nur return gefolgt von einem Semikolon.

Der Versuch, bei void einen Wert mit return zu liefern, führt zu einem Compiler Error.


 
class B {

 public static void main(String[] args) {
 B.b(12); // (1)
 }

 // Methode wird von (1) mit einem Parameter angesprungen.
 // Die Prüfungbedingung 12 > 10 bewirkt einen Rücksprung.
 // "Fail-Fast"-Ansatz
 // Das Ende der Methode wird gar nicht mehr erreicht. 
 
 public void b(int b) {
 
 if(b>10) {
 return;
 }
 
 System.out.println("b:"+b); 
 } 
}

 

throws Exception

java-return-by-throws-exception

Als Alternative zu einem Rückgabewert des im Header der Methode angegebenen return-Typs kann eine Methode dann vorzeitig beim Auswerfen (throw) einer Exception zurückkehren.

Da in diesem Fall, wenn man negative denkt, aber nicht der erwartete Rückgabe-Typ int mit dem Wert 100 zurückgegeben wird sondern ein Exception-Objekt, muss das bei der Definition der Methode entsprechend angegeben werden.

Methoden müssen jede Exception, die auftreten könnte, als Typ nach throws angeben, dh. wenn es mehrere sind werden diese schlichtweg durch Komma getrennt.

Exceptions und try-catch-finally-Konstrukte sind ein eigenständiger Themenbereich.


 
class C {

 public static void main(String[] args) {
 try {
 int punkte = C.thinkPositive("negative");
 } catch(Exception ex) {
 System.out.println("Dein Gedanke war negativ.");
 } 
 System.out.println("Du hast " + punkte +"!"); 
 }
 
 public int thinkPositive(String s) 
 throws DoNotThinkNegativeException {
 
 if(!s.equals("positive")) {
 throw new DoNotThinkNegativeException();
 }
 
 System.out.println("You think positive!"); 
 return 100;
 } 
}

 

Methoden | Rückgabe Kopie oder Referenz

java-return-by-throws-exception

Werte primitiver Datentypen werden als Kopie zurückgegeben. Das gilt mitunter für int, double und dergleichen.

Objekte werden als Referenz zurückgegeben, dh. jede Variable, die den Wert vom Typ eines bestimmten Objekts hat, der entweder über = zugewiesen wurde oder von einer Methode kommend übergeben oder dieser als Parameter gegeben wurde, zeigt auf das selbe Objekt im Speicher.

Dieses Thema «Copy-by-Reference» und «Copy-by-Value» wurde im Themenbereich Object erläutert.


 
class Objekt {
 public int id = -1;
}

class ObjektKiste {

 public static void main(String[] args) {
 Objekt o1 = new Objekt();
 o.id = 10;
 
 ObjektKiste k = new ObjektKiste();
 k.put(o);
 Objekt o2 = k.get();
 
 System.out.println(o1.id); // 11
 System.out.println(o2.id); // 11
 }
 
 private Objekt a;
 
 public void put(Objekt a) {
 this.a=a;
 this.a.id+=1; 
 }
 
 public Objekt get() {
 return this.a;
 }

}

 

Covariant Return Type

Methoden | Covariant Return Type

Eine Methode, welche einen bestimmten Rückgabetyp wie z. B. ein Tier zurückgeben soll, kann tatsächlich aber auch einen Affe oder Fisch zurückgeben.

Die Variation von Typen, die der Wert haben darf, entspricht der selben Richtung wie im Falle von Subklassen / Unterklassen.

Hinweis: Mehr hierzu im Themenbereich "Extending Classes" bzw. Erweitern von Klassen sowie auch Inheritage / Vererbung.


 
package com.stuelken.java.b1.classindetail;

class Tier {
	public String typ = "Tier";
}

class Fisch extends Tier {
	public String typ = "Fisch";
}

class Affe extends Tier {
	public String typ = "Affe";
}

/**
 * Öffentliche Klasse {@link Zoo} als Container für {@link Tier} Objekte.
 * 
 * @author t2m *
 */
public class Zoo {

	public Tier[] tiere;

	public Zoo() {
		this.tiere = new Tier[2]; // Array
		this.tiere[0] = new Affe();
		this.tiere[1] = new Fisch();
	}

	public Tier getTier(int i) {
		return this.tiere[i];
	}

	public static void main(String[] args) {

		Zoo z = new Zoo();
		
		Tier t0 = z.getTier(0);
		System.out.println(t0.typ); // Tier, nicht Affe
		System.out.println(t0); // com.stuelken.java.b1.classindetail.Affe@156643d4
		
		Tier t1 = z.getTier(1);
		System.out.println(t1.typ); // Tier, nicht Fisch
		System.out.println(t1); // com.stuelken.java.b1.classindetail.Fisch@123a439b

		if (t0 instanceof Affe) {
			Affe a = (Affe) t0; // "cast"
			System.out.println(a.typ); // Affe
			System.out.println(a); // com.stuelken.java.b1.classindetail.Affe@156643d4
		}
		if (t1 instanceof Fisch) {
			Fisch f = (Fisch) t1; // "cast"
			System.out.println(f.typ); // Fisch
			System.out.println(f); // com.stuelken.java.b1.classindetail.Fisch@123a439b

		}

	}
}

 

this mit Feldern

Methoden | this mit Feldern

this ist ein geschützter Name als Variablenname in JAVA mit welchem ein Objekt auf sich selbst verweisen kann.

Um zwischen dem variablen Wert eines Parameters x und z auf der einen und dem Feld-x und Feld-y der Klasse für das Objekt zu unterscheiden, bekommen# die Felder eigentlich die Adressierung über this.x und this.y

Wenn der Parameter aber anders heißt als das Feld, kann man das this.z durch z ersetzen.

Hinweis: Wird allerdings nachträglich noch lokal eine Variable z geschaffen, gibt es hierbei keine Fehlermeldung: Der this.z wird dann nicht belegt sondern zWert überschreibt dann die lokale z-Variable.


 
public class Punkt {
 public int x = 0;
 public int y = 0;
 public int z = 0;
 
 //constructor
 public Punkt(double x, double y, double zWert) {
 // z = 3 führt dazu, dass this.z nicht belegt wird!
 this.x = x;
 this.y = y;
 z = zWert;
 }
}

 

Lokale Variablen und Parameter verdecken Felder und damit Objektvariablen und Klasseneigenschaften. Wenn also eine Variable lokal mit einem Bezeichner lexikalisch angemeldet wird und es den gleichen Bezeichner auch für ein Feld der Klasse gibt, kann in der Methode das Feld erst wieder adressiert werden, wenn this verwendet.

this im Methoden

Methoden | this mit Methoden

this ermöglich die Adressierung auch anderer Member, dh. neben Feldern auch Methoden.

Wir können also innerhalb einer Klasse nicht nur Eigenschaften wie hier x mit this.x adressieren sondern auch aus einer Methode wie dem Konstruktor die Methode setX(..).

Für die Adressierung eines Konstruktors innerhalb der selben Klasse wird nur this(..) mit den Parametern verwendet.


 
public class Wert {
 private int x = 0;
 
 public Wert(x) {
 this.setX(x);
 }
 
 public Wert() {
 this(100); // "explicit constructor invocation"
 }
 
 public void setX(int x) {
 this.x = x;
 }
}

 

Zugriffsmodifikatoren

Methoden | Zugriffsmodifikatoren

Mit public, protected und private kann man den Zugriff auf Member wie Felder und Methoden ebenso anpassen wie auch für den Zugriff auf Klassen, Interfaces, Enumerationen und dergleichen auch.


 

Access Level 
------------------------------------------------ 
 |
Zugriff aus: | Class Package Subclass World
 |
------------------------------------------------ 
 |
Modifikator | 
 |
public | JA JA JA JA
protected | JA JA JA NEIN
(nothing) | JA JA NEIN JA
private | JA NEIN NEIN NEIN
------------------------------------------------ 


 


Sichtbarkeit von Klassen, Tipps und Tricks: Siehe Links.

Man sollte grundsätzlich immer erst einmal alles auf private setzen bis zu dem Zeitpunkt, wo man einen guten Grund hat, warum man es nicht macht. In Beispielen wird oft mit public oder ohne Angabe gearbeitet, weil es schneller geht; in der Praxis sollte man das so nicht machen.

https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

Class Members

Klassen | Class Members

Klassenmethoden und Klassenfeldern oder im Sinne der Objektorientierung auch Klassenattribute: Diese bezeichnet man als Class Member.

Sie werden definiert mit Hilfe von static.


 
class A {
 public static void main(String[] args) {
 A.machwas(); // Adressierung über Klasse
 machwas(); // Geht auch ohne, wenn es keine Objektmethode gibt.
 }
 
 public static void machwas() {
 System.out.println("Ich mache etwas.");
 }
}

// Ich mache etwas.
// Ich mache etwas.


... class Methods > public static int getNumberOfObjects() { ... }
... class Field > private static int numberOfInstances = 0;
... class Constants > public static final double PI = static final double PI = 3.141592653589793;


 

Klassenmember haben den Vorteil, dass man die ähnlich wie globale Variablen oder Funktionen in anderen Sprachen nutzen, ohne dass man vorher ein Objekt erzeugen muss.

Im Falle der Verwendung von Threads und paralleler Datenverarbeitung muss man aber aufpassen, dass man korrekt synchronisiert hat.


Konstanten:

public static final double PI = static final double PI = 3.141592653589793;;


Mehr zum Thema: https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

Initialisierung

Klassen | Initialisierung

Klassemethoden und Klassenfeldern oder im Sinne der Objektorientierung auch Klassenattribute: Diese bezeichnet man als Class Member.

Sie werden definiert mit Hilfe von static.


 
class A {
 public static String description = "Ich bin ein A";
}

class B {
 // Ein Static Initizalion Block schafft Ordnung im Code.
 static {
 // ...
 }
}

// Dieses Beispiel macht mitunter Sinn in Verbindung mit Arrays oder Objekten
class C {
 public static int value = initValue();
 private static int initValue() {
 C.value = 42;
 }
}


class D {

 // Initalizer Blocks dienen für Instanz-Variablen und damit Objekte
 // Diesen Blöcken fehlt das static davor.
 {
 int a;
 int b;
 }
}



Mehr zum Thema: https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

Zusammenfassung

Klassen | Initialisierung

Sie werden definiert mit Hilfe von static.


 
package com.stuelken.java.b1.classindetail;

public class ClassMethodFieldCompact {
	public static void main(String[] args) {
		A a = new A();
		System.out.println(a.toString()); // Instance of A

	}
}

//@formatter:off
class A { 

 // === Konstruktor	 
	 public A() { } 

 // === Statische Methoden	 
	 public static int as() { return 1; } 
	 protected static int bs() { return 1; } 
	 private static int cs() { return 1; } 
	 static int ds() { return 1; } 
	 
 // === Instanzmethoden	 
	 public int ai() { return 1; } 
	 protected int bi() { return 1; } 
	 private int ci() { return 1; } 
	 int di() { return 1; } 

	 // === Felder ohne Initialisierung (Klasse)
	 public static int as; 
	 protected static int bs; 
	 private static int cs; 
	 static int ds;
	 
 	 // Felder ohne Initialisierung (Instanz)
	 public int ai; 
	 protected int bi; 
	 private int ci; 
	 int di;

 // Felder mit Initialisierung (Klasse)

	 public static int asi = 1;
	 protected static int bsi = 1; 
	 private static int csi = 1;
	 static int dsi = 1;
	 
 // Felder mit Initialisierung (Instanz)
	 public int aoi = 1;
	 protected int boi = 1;
	 private int coi = 1;
	 int doi = 1;
	 
	 // === Konstanten (statisch) 
	 
	 public static final int A = 1;

	 // === Unveränderliche Instanzwerte
	 public final int B = 1; // Unverändlicher Objektwert. 
	 
	 // === Methoden mit Parametern und Overloading
	 public void doA() { this.ai = 1; }
	 public void doB(int b) { this.bi = b; } // Overloading: int vs.
	 public void doB(double b) { this.bi = (int)b; } // double
	 
	 public int doAInt(int a) { return a + 1; }
	 public int doAInt(int[] a) { return a[0] + 1; }
	 
	 // === Parameter als final (unveränderlich)
	 public int doA(final int a) { return a + 1; }
	 public int doA(final int[] a) { return a[0] + 1; }
	 
	 
	 
 // === synchronized: Methode und Code-Block zur Synchronisation
	 public synchronized void syncMethod() {
	 // synchronisierter Zugriff innerhalb der Methode
	 }
	 
	 public void methodWithSyncBlock() {
	 synchronized(this) { // Beginn
	 // synchronisierter Block innerhalb der Methode
	 } // Ende
	 }
	 
	 
	 // === volatile: Sichert die Sichtbarkeit von Änderungen über Threads hinweg
	 private volatile int shareableValue;	 
	 
	 
 // === Annotations wie @Override (weitere Annotationen folgen in ihrem Kapitel)
	 // Weitere Annotationen finden sich im Kapitel JAVA-B1 Annotations
	 @Override
	 public String toString() {
	 return "Instance of A";
	 }
	 
	 // === @Serializable, falls definiert (entspricht @Serial)
	 // Dient für Klassen als Markerinterface. 
	 
	 
	 // === Anonymer Runnable in einem neuen Thread
	 // Nebenläufige Programmierung mit java.lang.Thread
	 public void startNewThread() {
	 Thread t = new Thread(new Runnable() {
	 @Override
	 public void run() {
	 System.out.println("Running in new thread");
	 }
	 });
	 t.start();
	 }	 
	 

	 // === Lambda-Ausdruck (seit Java 8) für Runnable
	 public void startLambdaThread() {
	 new Thread(() -> System.out.println("Lambda thread running")).start();
	 }	 
	 
	 
	// Hinweis: Für bessere Performance im Concurrent-Bereich eignen sich spezielle Collections,
	 // z.B. CopyOnWriteArrayList, ConcurrentHashMap etc., die in einem speziellen Kapitel erläutert werden.	 
	 
}
//@formatter:on

Mehr zum Thema:

https://docs.oracle.com/javase/tutorial/java/javaOO/summaryclasses.html

https://docs.oracle.com/javase/tutorial/java/javaOO/QandE/creating-questions.html

https://docs.oracle.com/javase/tutorial/java/javaOO/QandE/objects-questions.html

FootNotes, Keywords, Tags


    Hinweise, Rechte, Marken

    UI ORGANIZED.

    UIO3 Es ist einfacher als Du denkst.

    Stelle noch heute Deine Anfrage.

    uio--WebPageFooter-Module