Java Classes
Kleines Beispiel
Ein Interface, darf nur abstrakte Methoden und Konstanten enthalten
* My Interface
*/
package mypackage;
/**
* @author John Doe
*
*/
public interface MyInterface
{
/**
* @param number The number which is added
* @return The new sum
*/
public double add(final int number);
/**
* The limit for the result after the mathematical operations
*/
final static double maxValue=10000;
}
Eine abtrakte Klasse, enthält mindestens eine abstrakte Methode
* An abstract class which will be used for things which are
* not allowed in an Interface
*/package mypackage;
/**
* @author John Doe
*
*/
public abstract class MyAbstractClass
{
/**
* Constructor
*/
public MyAbstractClass()
{
this.value=0;
}
/**
* This is the current value which will be modified by the
* mathematical operations which are offered
*/
protected double value;
}
Eine normale Klasse, darf höchsten von einer anderen Klasse erben, aber von beliebig vielen Interfaces implementieren.
* This class shows that you can implement multiple Interfaces
*/
package mypackage;
/**
* @author John Doe
*
*/
public class MyClass extends MyAbstractClass
implements MyInterface, MyOtherInterface
{
/* (non-Javadoc)
* @see mypackage.MyInterface#add(int)
*/
public double add(final int number)
{
System.out.println("The maxvalue is " + AdderInterface.maxValue);
double res=this.value+=number;
this.value=res;
return res;
}
}
instanceof
b = ( str instanceof String ); // (1)
b = ( str instanceof Object ); // (2)
b = ( str instanceof Foo ); // (3)
(1) und (2) sind beide wahr, (3) nicht
So kann man eine Objekt in eine gewünschte Klasse casten, falls möglich
if(desiredClass.isAssignableFrom(object.getClass())) {
@SuppressWarnings("unchecked")
final T casted=(T) object;
return Optional.of( casted );
}
return Optional.empty();
}
Clone
Flache Kopie von Objekten erzeugen:
x=new Foo();
y=x.clone();
Konstruktor
Anderen Konstruktor der eigenen Klasse aufrufen
muss die erste Anweisung des Konstruktors sein, keine Objektvariablen übergebbar
Wenn man eine Klasse hat, von der es nur wenige Ausprägungen gibt, wie z.B. Boolean. Dann macht es oft keinen Sinn, dass man mit new beliebig viele verschiedene Objekte dieser Klasse erzeugen kann. Eine besser Variante ist es dann, statt einem Konstruktor eine valueOf() Methode anzubieten
Diese liefert dann immer wieder die wenigen Objekte zurück die es geben kann, hier z.B. entweder Boolean.TRUE oder Boolean.FALSE. Es darf dann natürlich keine Methode geben, ob den Wert eines solchen Objektes zu verändern, weil sonst auch alle anderen Nutzer dieses Objektes davon betroffen wären.
Exemplarinitialisierern
Initialisieren von Variablen in allen Konstruktoren
{
int j=1; // (1)
Foo()
{
this.k=0;
}
Foo( int i )
{
this.k = j;
}
}
entspricht
{
int j; // (1)
Foo()
{
this.j=1; // (1)
this.k=0;
}
Foo( int i )
{
this.j = 1; // (1)
this.k = i;
}
}
Bei statischen Variablen
{
static int x = 2;
}
entspricht
{
static int x;
static
{
x = 2;
}
}
Super
Konstruktor des Vaters aufrufen
Methode des Vaters aufrufen
public void foo( int alter ) {
super.foo();
...
}
Innere Klassen
Siehe auch Innere Klassen in Java mehr als eine Insel
{
class Bar
{
}
}
Zum Erzeugen eines Objekts der inneren Klasse, braucht man ein Objekt der äußeren Klasse (Ausnahme statische innere Klassen). Versucht man z.B. in einer statischen Methode der äußeren Klasse ein Objekt der inneren Klasse zu erzeugen würde das fehlschlagen
Nur innere Klassen dürfen Private oder Protected sein. Wenn sie es sind, hat es Einfluss darauf, wer sie benutzen darf.
Statische Klasse
Statische Klassen werden auch nested top-level class genannt. Sie benötigen kein Exemplare der äußeren Klasse, um erzeugt zu werden. Eine statische Klasse kann auf alle statischen Attribute und Methoden der umgebenden Klasse zugreifen. Auf nicht statische Attribute oder Methoden hingegen ist kein direkter Zugriff möglich.
{
static String s = "HELLO WORLD";
int i = 1;
static class Bar
{
void test()
{
System.out.println(s);
// System.out.println( i ); // (1)
}
}
}
Mitglieds- oder Elementklassen
Auch member class genannt. Kann auch alle Attribute (inklusiver privater) der äußeren Klasse zugreifen. Allerdings benötigt man ein Exemplar der äußeren Klasse, um ein Exemplar der inneren Klasse von außen zu erzeugen.
{
String s = "Hello World";
class Bar
{
void test1()
{
System.out.println( s );
}
//static void test2() { } // (2)
}
}
Von aussen erzeugen
Bar b = a.new Bar();
Die Mitgliedsklasse darf selbst keine statischen Attribute oder Methoden haben.
Lokale Klassen
Klassen, die innerhalb von Methoden der äußeren Klasse definiert werden. Die lokalen Klassen können auf die Methoden der äußeren Klassen zugreifen und auf deren Elemente, die mit final markiert sind. Wird die lokale Klasse in einer static Methode definiert ist ein Zugriff auf nicht statische Elemente und Methoden hingegen nicht möglich.
{
public static void main( String[] args )
{
int i = 1;
final int j = 2;
class Bar
{
Bar() {
System.out.println( j );
//System.out.println( i ); // (3) Fehler, da i nicht final
}
}
new Bar();
}
}
Anonyme innere Klassen
Anonyme innere Klassen erben entweder von einer anderen Klasse oder implementieren eine Schnittstelle
{
// ...
}
interface Bar()
{
// ...
}
class Blub{}
{
new Foo()
{
...
}
new Bar()
{
...
}
}
Serialisierung
Eine kleine Testklasse, die serialisiert werden soll:
import java.io.Serializable;
public class PersistMe implements Serializable
{
private static final long serialVersionUID = 291L; // == 0x123
byte variableA=127; // == 0111 1111 == 0x7f
int variableB=1092; // == 0000 1000 1000 1000 == 0x0444
String variableC="Hallo Welt";
}
So kann man ein Objekt der Klasse speichern:
{
FileOutputStream fos = new FileOutputStream(pFileName);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(pDemo);
out.close();
}
So kann man ein Objekt der Klasse wiederherstellen:
{
FileInputStream fos = new FileInputStream(pFileName);
ObjectInputStream in = new ObjectInputStream(fos);
PersistMe d = (PersistMe) in.readObject();
in.close();
return d;
}
Mit einem Hexeditor kann man in der Datei
00000010: 656c 2e4a 6176 6144 656d 6f2e 5365 7269 el.JavaDemo.Seri
00000020: 616c 697a 652e 5065 7273 6973 744d 6500 alize.PersistMe.
00000030: 0000 0000 0001 2302 0003 4200 0976 6172 ......#...B..var
00000040: 6961 626c 6541 4900 0976 6172 6961 626c iableAI..variabl
00000050: 6542 4c00 0976 6172 6961 626c 6543 7400 eBL..variableCt.
00000060: 124c 6a61 7661 2f6c 616e 672f 5374 7269 .Ljava/lang/Stri
00000070: 6e67 3b78 707f 0000 0444 7400 0a48 616c ng;xp....Dt..Hal
00000080: 6c6f 2057 656c 74 lo Welt
dann relativ leicht die Informationen des Objektes wiederfinden:
Klassenname:
652e 5065 7273 6973 744d 65
d e . t g u n k e l . J a v a D e m o . S e r i a l i z e
. P e r s i s t M e
serialVersionUID:
291
Variablennamen:
B v a r i a b l e A
4900 0976 6172 6961 626c 6542
I v a r i a b l e B
4c00 0976 6172 6961 626c 6543 7400 124c 6a61 7661 2f6c 616e 672f 5374
7269 6e67
L v a r i a b l e C L j a v a / l a n g / S t r
i n g
Variablenbelegung:
127
0444
1092
48 616c 6c6f 2057 656c 7
H a l l o W e l t