einfache Frage zu private

ernst

Top Contributor
Hallo allerseits,
Bei Java gibt es den Zugriffsschutz private.
Dies bedeutet, dass von ausserhalb nicht auf ein private Member zugegriffen werden darf.
Deswegen verstehe ich nicht, warum (siehe unten) in der Methode vergleiche mit
if(k1.kontostand < k2.kontostand){
auf das private Member kontostand zugegriffen werden kann.


PS:
Unten ist das ganze Programm.
mfg
Ernst



Java:
package konto1;

public class MainKonto1 {
    public static void main(String[] args) {
        int x;
        Konto ko1 = new Konto(100,1);
        Konto ko2 = new Konto(200,2);
        Konto ko3 = new Konto(300,3);
        x=ko3.vergleiche(ko1, ko2);
        x=ko1.vergleiche(ko1,ko2);
        x=ko1.vergleiche(ko2);
        System.out.println("x="+x);
    }
}

class Konto{
    private double kontostand;

    public Konto(double pKontostand, double pZinssatz) {
        kontostand = pKontostand;
        zinssatz = pZinssatz;
    }

    public int vergleiche(Konto k1, Konto k2){
        int erg;
        if(k1.kontostand < k2.kontostand){
            erg=-1;
        }
        else if(k1.kontostand == k2.kontostand){
            erg=0;
        }
        else{
            erg=1;
        }
        return erg;
    }

    public int vergleiche(Konto pKo){
        int erg;
        if(this.kontostand < pKo.kontostand){
            erg=-1;
        }
        else if(this.kontostand == pKo.kontostand){
            erg=0;
        }
        else{
            erg=1;
        }
        return erg;
    }

}
 
private heist, dass keine andere Klasse zugriff auf die variablen/methoden hat. Diese variablen/methoden werden aber von Objekten dieser Klasse aufgerufen. Da es sich immernoch um die gleiche Klasse handelt, ist das möglich.
 
private heist, dass keine andere Klasse zugriff auf die variablen/methoden hat. Diese variablen/methoden werden aber von Objekten dieser Klasse aufgerufen. Da es sich immernoch um die gleiche Klasse handelt, ist das möglich.

Ich verstehe das nicht.
I)
int main(){
k1 = new Konto(100);
k1.kontostand = 100;
}
ist nicht erlaubt.

II)
Aber warum ist erlaubt
int main(){
k1 = new Konto(100);
k2 = new Konto(200);
k1.verkleiche(k1,k2);
}

k1.verkleiche(k1,k2);
ruft intern auf
k1.kontostand
Aber
k1.kontostand ist nicht erlaubt
siehe oben bei I)

mfg
Ernst
 
weil deine methode [c]vergleiche[/c] von der Klasse Konto definiert wurde. Diese Klasse kennt nunmal auch die privaten Attribute deiner Objekte und kann diese darum verwenden. Letztendlich greifst du auf diese Werte also innerhalb deiner Klasse zu.

Kurz: eine private Methode ist nur innerhalb der Klasse sichtbar. Wären sie nur innerhalb von Objekten sichtbar, dürfte das nicht gehen. Du setzt hier Objekte mit Klassen gleich, da gibt es aber unterschiede.
 
>weil deine methode vergleiche von der Klasse Konto definiert wurde.
>Diese Klasse kennt nunmal auch die privaten Attribute deiner Objekte
>
Das private Attribut heisst kontostand
>
>und kann diese darum verwenden.
>Letztendlich greifst du auf diese Werte also innerhalb deiner Klasse zu.
>
K1 und k2 sind aber Parameter in vergleiche(...) und keine Attribute
>
>Kurz: eine private Methode ist nur innerhalb der Klasse sichtbar.
>Wären sie nur innerhalb von Objekten sichtbar, dürfte das nicht gehen.
>Du setzt hier Objekte mit Klassen gleich, da gibt es aber unterschiede.
>
Ein Objekt wird nach dem Bauplan einer Klasse konstruiert.

mfg
Ernst
 
Ja das ist alles soweit richtig, nichts desto trotz hat Tomate_Salat recht.
Ist in deiner Antwort jetzt noch irgendwoe ne Frage versteckt?
 
Alle Methoden, die du innerhalb von einer Klasse definierst haben Zugriff auf alle Attribute aller Objekte der Klasse.

Java:
class Test {
	private int value;

	public boolean vergleiche(Test t, Test t2) {
		return t.value == t2.value; // Die Methode wird innerhalb der Klasse Test
									// definiert, also hat sie Zugriff auf alle
									// Attribute aller Objekte der Klasse, geht
									// also!
	}
}

class Test2{
	public void demoe(){
		Test t = new Test();
		Test t2 = new Test();
		
		boolean vergleich  = t.value == t2.value; // Die Werte sind private, die Klasse hat keinen Zugriff darauf.
		boolean vergleich = t.vergleiche(t, t2); // Die Methode vergleiche ist public, das geht also!
	}
}
 
Ja das ist alles soweit richtig, nichts desto trotz hat Tomate_Salat recht.
Ist in deiner Antwort jetzt noch irgendwoe ne Frage versteckt?
1)
Wenn in der Klasse vergleiche(...) nur das Attribut
kontostand verwendet werden würde, wie z.B.
kontostand = kontostand + 10;
dann wäre dies ein Zugriff innerhalb der Klasse.
Das würde funktionieren. So weit so klar.

2)
Wenn in der Klasse vergleiche(...) nun ein Objekt einer anderen Klasse verwendet werden würde (wie z.B. fussball), und in diesem Objekt dann (mit z.B. fussball.gewicht) auf ein Attribut zugegriffen wird, dann würde dies nur funktionieren, wenn das Attribut gewicht der zum Objekt fussball zugehörigen Klasse Fussball private wäre.
Ist dies richtig?

3)
Wenn in der Klasse vergleiche(...) nun das Objekt k1 der Klasse Konto verwendet wird,
und darin mit k1.kontostand auf ein private Attribut zugegriffen wird, dann
wird auf kontostand innerhalb der Methode vergleiche(...), also innerhalb der Klasse zugegriffen.
Und ein Zugriff innerhalb einer Klasse funktioniert immer.
Ist dies richtig?

mfg
Ernst
 
2)
Wenn in der Klasse vergleiche(...) nun ein Objekt einer anderen Klasse verwendet werden würde (wie z.B. fussball), und in diesem Objekt dann (mit z.B. fussball.gewicht) auf ein Attribut zugegriffen wird, dann würde dies nur funktionieren, wenn das Attribut gewicht der zum Objekt fussball zugehörigen Klasse Fussball private wäre.
Ist dies richtig?
Äh, ich glaube nicht. Wenn Du eine Klasse Fussball mit dem privaten Attribut gewicht hast, dann können nur Instanzen der Klasse Fussball direkt darauf zugreifen. Kann aber sein, dass ich die Frage nicht richtig verstanden habe.

3)
Wenn in der Klasse vergleiche(...) nun das Objekt k1 der Klasse Konto verwendet wird,
und darin mit k1.kontostand auf ein private Attribut zugegriffen wird, dann
wird auf kontostand innerhalb der Methode vergleiche(...), also innerhalb der Klasse zugegriffen.
Und ein Zugriff innerhalb einer Klasse funktioniert immer.
Ist dies richtig?
Ja, das ist richtig.
 
>>
>> Wenn in der Klasse vergleiche(...) nun ein Objekt einer anderen Klasse verwendet werden
>>würde (wie z.B. fussball), und in diesem Objekt dann (mit z.B. fussball.gewicht) auf ein
>>Attribut zugegriffen wird, dann würde dies nur funktionieren, wenn das Attribut gewicht
>>der zum Objekt fussball zugehörigen Klasse Fussball private wäre.
>> Ist dies richtig?
>>
>
>Äh, ich glaube nicht. Wenn Du eine Klasse Fussball mit dem privaten Attribut gewicht hast,
>dann können nur Instanzen der Klasse Fussball direkt darauf zugreifen.
>Kann aber sein, dass ich die Frage nicht richtig verstanden habe.
>
Aber nur, wenn die entsprechenden Member public sind.
Deshalb ist das obige Zitat von mir falsch.
Ich verbessere es:
...
wird, dann würde dies nur funktionieren, wenn das Attribut gewicht der zum Objekt fussball
zugehörigen Klasse Fussball _PUBLIC_ (private ist falsch) wäre.

mfg
Ernst
 
Auch wenn die meisten Getter wohl so ausschauen:
[java=42]
public Object getObject()
{
return this.myObject;
}
[/code]

weiß man nie, ob man nicht iwann mal hier eine Prüfung einbauen muss/sollte. Das ist so der Hauptgrund, wieso ich auch in der Klasse selbst mit gettern arbeite. Das gleiche gilt für Setter.
 
und der getter sebst muss natürlich auch den getter verwenden ???:L

Ich hoffe, dass dies ein Witz war 😉 Natürlich darf der Getter sogar je nach dem zwei Zugriffe haben, wenns einen Default Value geben soll:
Java:
public Object getX() {
    if (x == null) {
        setX(new SomeObj());
    }
    return x;
}

public void setX(Object x) {
    this.x = x;
}
Aber sonst hab ich noch nirgens einen direkten Zugriff benötigt.
 
Ich hoffe, dass dies ein Witz war 😉
Das der getter den getter verwendet? Ja das war ein Witz.

Kein Witz war, dass ich intern nie getter vewende, wenn da nur
Code:
return xxx;
drin steht - das wäre mehr als pervers.

Logisch habe ich auch ab und zu getter die mehr machen ... ;-)

Edit:
Jetzt lese ich gerade noch etwas von "nachträglich einbauen" - da kräuseln sich mir die Haare und ich kriege Gänsehaut - wenn man auch nur einigermassen ein Design hat, werden höchstens Prüfungen ausgebaut - das ist sogar hier (in der nicht genannten Firma) so und da läuft längst nicht alles optimal!

Auch hier Ausnahmen und Regeln - sollte ich was einbauen kann ich immer noch im Zuge des Refactoring getter-aufrufe einbauen, aber ich glaube das musst ich bis dato noch nie.
 
Zuletzt bearbeitet:
Naja, der Alltag im Beruf sollte doch zeigen, wie schnell so ein Design mal über den Haufen geworfen werden kann ;-)

Wenn schon ein Getter existent ist, sehe ich eigentl. keinen Grund, diesen nicht auch zu verwenden (außer man hat wirklich eine Sonderregelung aktiv, die nicht mit der Funktionalität des Getters vereinbar ist).
 
Naja, der Alltag im Beruf sollte doch zeigen, wie schnell so ein Design mal über den Haufen geworfen werden kann ;-)
klar, aber auch dann bist du nur in deiner klasse aktiv und das ist mehr als ueberschaubar.

v.a. bei getter verlaesst mich meine kreativitaet um zu ueberlegen welche checks da kommen sollen. Wenn eine Variable einer Pruefung unterzogen werden muss, dann dort wo sie gesetzt wird. Dies beim getter zu tun halte ich fuer den falschen platz.
 
Finde ich auch. Wenn ich z.B. für ein PLZ-Feld in einem Getter prüfen soll, ob es das richtige Format hat, ist meiner Meinung nach die bessere Lösung, gleich eine entsprechende Wrapper-Klasse zu schreiben.
 
Wenn du aber überall den Setter verwenden willst, und darum die Sichtbarkeit einschränkst, musst du zumindest von aussen wieder mit dem Getter arbeiten. Warum dann nicht noch in der Klasse selbst? Eine allgemeine Gültigkeit (Coding Standards?) macht hier doch viel mehr Sinn.

Edit: Welche Checks?
Manchmal ist der "Getter" einfach schlichtweg kein reales Feld der Klasse. Na gut, ist vielleicht nicht ein klassischer Getter, z.B. Kreis mit getRadius(), getUmfang() und getFlaeche().
Ansonsten könnte man vielleicht bei einem Getter noch was auslösen wollen. Z.B. ein Zugriffscounter, Debuginformationen oder gar das Laden von Daten erst wenn man sie benötigt - so was mein ich:
Java:
public BigObject getX() {
    if (x == null) {
        setX(initVeryVeryBigObject());
    }
    return x;
}
 
Zuletzt bearbeitet:
faetzminator, ich glaube die meisten hier reden von Gettern im klassischen Sinne. Die Definition, die ich davon kenne besagt dass es dort keinerlei Seiteneffekte gibt, demnach ist es dort tatsächlich egal ob man über den Getter geht oder einen Direktzugriff. Wobei ich den Punkt der Debuginformation tatsächlich einsehe. Deine Beispiele würde ich persönlich aber nicht wirklich als Getter bezeichnen, auch wenn sie etwas zurückliefern und mit get anfangen.

Was man aber auf jeden Fall nicht machen sollte ist das, was Tomate_Salat gepostet hat:

Java:
public Object getObject() 
{
    return this.myObject;
}

Gewisse Automatismen (Java Beans) laufen hier ins Leere, wenn sie die Variable "object" suchen und nicht finden. (Oder andersrum: Auf "myObject" zugreifen wollen, aber keine Methode getMyObject() finden)
 
... braucht keinen weiteren Kommentar als der der drin steht ;-)

Java:
public class PrimitivesBeispiel {

	private int a;
	private int b;

	public void setA(int value) {
		a = value;
	}

	public int getA() {
		return a;
	}

	public void setB(int value) {
		b = value;
	}

	public int getB() {
		return b;
	}

	public int summe() {
		// sorry, aber wer hier getA() und getB() verwendet ist päpstlicher als der Papst
		return a + b;
	}
}

und im nächsten Release wird die Klasse möglicherweise umgestellt, dass die Summe immer schon beim Setzten von Werten berechnet wird, um beim holen der Summe Zeit zu sparen ..... tja ...
 
[...]
Java:
public class PrimitivesBeispiel {

	private int a;
	private int b;

//something

	public int summe() {
		// sorry, aber wer hier getA() und getB() verwendet ist päpstlicher als der Papst
		return a + b;
	}
}
[...]

Naja, hab auchschon sowas gesehen:
Java:
public class PureTest {

	public static void main(final String[] args) {
		String start = "1313131313131313";
		while (start.contains("3")) {
			start = start.replaceFirst("3", "2");
		}
		System.out.println(start);
	}

}
Is zwar nur nen Beispiel, da ich das original nicht mehr auf die Reihe bekomme, aber so ähnlich sah es aus, als ich das dann inner Schule bei einem gesehen hab musste ich ersma lachen :toll:

PS:
faetzminator, ich glaube die meisten hier reden von Gettern im klassischen Sinne. Die Definition, die ich davon kenne besagt dass es dort keinerlei Seiteneffekte gibt, demnach ist es dort tatsächlich egal ob man über den Getter geht oder einen Direktzugriff. Wobei ich den Punkt der Debuginformation tatsächlich einsehe. Deine Beispiele würde ich persönlich aber nicht wirklich als Getter bezeichnen, auch wenn sie etwas zurückliefern und mit get anfangen.

Was man aber auf jeden Fall nicht machen sollte ist das, was Tomate_Salat gepostet hat:

Java:
public Object getObject() 
{
    return this.myObject;
}

Gewisse Automatismen (Java Beans) laufen hier ins Leere, wenn sie die Variable "object" suchen und nicht finden. (Oder andersrum: Auf "myObject" zugreifen wollen, aber keine Methode getMyObject() finden)

Jupp, hatte ich bei Spring relativ oft, hat immer gedauert bis ich rausgefunden hab woran es lag, dachte immer ich geb nen falschen Typ zurück xD
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben