- Klassen | Klassen im Detail
- Klassen | return-Statement von Methoden
- Methoden | Rückkehr ohne return-Statemen
- Methoden | Erreichen eines return-Statements
- Methoden | Rückkehr über throws Exception
- Methoden | Rückgabe Kopie oder Referenz
- Methoden | Covariant Return Type
- Methoden | this mit Feldern
- Methoden | this mit Methoden
- Methoden | Zugriffsmodifikatoren
- Klassen | Class Members
- Klassen | Initialisierung
- Klassen | Zusammenfassung
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-returnDas 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-exceptionAls 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-exceptionWerte 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
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
UIO3 Es ist einfacher als Du denkst.
Stelle noch heute Deine Anfrage.

