In einem Javaprogramm gibt Klassen mit unterschiedlichsten Aufgaben. Einige Klassen haben alles: Daten und Funktionen/Prozeduren um komplexe Aufgaben zu meistern. Andere Klassen haben nur statische Methoden und sind nicht instanzierbar – dies sind Utility-Klassen. Und es gibt Klassen, die nur zum Daten erfassen bestimmt sind, nur aus Feldern mit ihren getter/setter-Methoden bestehen und allenfalls einige Zusatzmethoden für einfache Berechnungen haben.
Für die sogenanten Attribute eine Klasse – also deren Felder – gibt es in Java die Konvention: Felder privat – nur über getter/setter von außen erreichbar!
// ...
// In Klasse "MyObject"
private Color color = Color.BLACK;
public Color getColor() { return color; }
public void setColor(Color color)
{ this.color = color; }
// ...
MyObject object = new MyObject();
myobject.setColor(Color.RED);
System.out.println("Color: " + myobject.getColor());
(Anmerkung: Es kann sinnvoll sein, auch innerhalb der Klasse auf ein Attribut mit getAttribut() zuzugreifen anstatt direkt. Z. B. wenn die Klasse vererbt wird und getAttribut() sinnvoll überschrieben wird.)
Was aus OOP-Sicht durchaus sinnvoll erscheint, führt im praktischen Einsatz zu Klassen mit ellenlangen getter/setter Methodenauflistungen die meist nicht viel mehr machen, als das Attribut einfach nur zu setzen, bzw. zurück zu geben. Schließlich könnte man ja Zuge des Zugriffs auf ein Attribut noch irgend etwas anderes sinnvolles machen (Attribut der GUI setzen; GUI repaint();
). Und ich bin OOP-Puristen begegnet, die auf nur ein vorhandenes public boolean Attribut mit stundenlangen Vorträgen reagierten, warum man so etwas nicht macht!
Anders sieht dies z. B. bei der Entwicklung von Android-Apps aus. Hier wird in vielen Tutorials dazu ermuntert, „unnötige“ getter/setter zu vermeiden um Geschwindigkeitsvorteile zu erlangen.
Das es sinnvoller geht zeigen Programmiersprachen wie C# oder Swift. Dort sieht das so aus:
// ...
// In Klasse "MyObject"
var color : UIColor
{
get { return _color }
set(c) { _color = c }
}
private var _color : UIColor = UIColor.blackColor
var color2 : UIColor = UIColor.greenColor
// ...
var object = MyObject()
object.color = UIColor.redColor
object.color2 = UIColor.yellowColor
println("Colors: \( object.color ) \( object.color2 )")
Das Attribut color wird hier zum Property, indem man direkt nach seiner Deklaration in geschweiften Klammern get und/oder set nach dem Muster in Zeilen 3-8 definiert. Von außen kann man dann auf das Property genau wie ein Attribut (hier color2) zugreifen, siehe Zeilen 18-21.
Der Nachteil, daß man von außen nicht mehr reine Attribute und Properties unterscheiden kann wird durch die natürliche Anwendung wieder ausgeglichen. Es scheint logisch, auf eine Eigenschaft ganz einfach mit den Punktoperator zuzugreifen, ohne das dies einem Methodenaufruf gleicht. Und eine Zuweisung mit dem Istgleich-Operator hat sich seit Ewigkeiten in den Programmiersprachen festgesetzt, nicht einmal Sprachen wie Pascal konnten ihn mit dem zugegebenen sinnvolleren := Operator verdrängen.
Der Vorteil liegt nun auch darin, daß viele Attribute lediglich gesetzt bzw. gelesen, ohne daß weitere Aktionen durchgeführt werden müssen. Hierbei genügt es, nach dem Schema wie bei color2 zu verfahren. Sollten nun wirklich weitere Aktionen nötig sein, so kann man ganz einfach ein Attribut in ein Property umwandeln – auch nachträglich irgendwann sehr viel später im Projekt – ohne daß sich die API von außen ändert!
Man ist auch nicht gezwungen, get und set immer zu benutzen. Läßt man z. B. set weg, so hat man das Property automatisch in einem von außen Nur-Lesen-Status versetzt.
Properties stellen meiner Ansicht nach eine sinnvolle Weiterentwicklung der OOP dar, um Code schlanker und damit besser lesbar zu machen. Dies alleine spricht schon dafür, daß sie auf meiner Java-Wunschliste stehen.
Kleine Anmerkung: Es gibt Möglichkeiten Properties in Java zu simulieren, z. B. so:
class IntProperty // TODO: z. B. von Number erben, Comparable implementieren, ...
{
private int value;
public void set(int value) { this.value = value; }
public int get() { return value; }
}
// ...
class IrgendEineKlasse
{
public final IntProperty anzahl = new IntProperty();
// ...
}
// ...
IrgendEineKlasse iek = new IrgendEineKlasse();
iek.anzahl.set(4);
System.out.println("Anzahl: " + iek.anzahl.get());
Damit bleibt zwar das OOP-Konzept einigermaßen gewahrt, jedoch ist es immer noch umständlich und man hat nicht die schöne einfach Nutzung mit dem Istgleich-Operator, etc.
Du muss angemeldet sein, um einen Kommentar zu veröffentlichen.