PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java Problem mit private



jph83
23-09-2004, 10:23
Hallo zusammen,
ich lerne gerade JAVA. Soweit ich das verstanden habe ist es ja so, dass wenn ich eine Variable innerhalb einer Klasse oder Funktion als private deklariere, dass ich diese von außen nicht sehe, aber warum passiert dann bei dem Code hier folgendes:
class Counter{
private int min,max,z;
public Counter(int startwert, int min, int max) throws Exception
{
if(max>=min)
{
if(startwert>=min && startwert <=max)
{
this.max=max;
this.min=min;
this.z= startwert;
}
else
{
throw new Exception("Der Startwert liegt nicht zwischen Min und Max Wert");
}

}
else
{
throw new Exception("Der Maximale Wert muss größer als der Minimale Wert sein");
}

}


public static void main(String[]arg)
{
try{
Counter c=new Counter(33,1,40);
System.out.println(c.min);
}
catch(Exception c)
{
System.out.println(c);
}
}
}

Wenn ich System.out.println(c.min); ausgebe (ganz unten. Dann wird der Inhalt der Variable min ausgegeben, auch wenn es sich dabei um eine (ganz oben) als private deklarierte handelt. Was mache ich da falsch

Sym
23-09-2004, 14:51
Ich denke mal, dass liegt daran, dass Du die Main-Methode mit in der Klasse hast. Aber normalerweise sollte das eigentlich nicht möglich sein.

peschmae
23-09-2004, 19:41
Etwas explizites dazu habe ich nicht gefunden. In Core Java 2 steht:
"Das Schlüsselwort private stellt sicher, dass ausschliesslich Methoden der Klasse selbst auf diese Instanzfelder zugreifen können. Von aussen kann keine Methode diese Felder lesen oder schreiben."
Da auch eine static-Methode eine Methode der Klasse ist ist das also normal.

Allerdings hätte ich das zugegebenermassen auf den ersten Blick auch nicht gerade erwartet.

MfG Peschmä

anda_skoa
24-09-2004, 17:25
Wie gesagt ist main hier genau so eine Methode der Klasse, darf also auf private zugreifen.
Sogar eine Methode einer anderen Instanz der selben Klasse dürfte das, da kommt es auch manchmal zu Missverständnissen :)

Ciao,
_

Sym
25-09-2004, 07:34
Wie gesagt ist main hier genau so eine Methode der Klasse, darf also auf private zugreifen.
Sogar eine Methode einer anderen Instanz der selben Klasse dürfte das, da kommt es auch manchmal zu Missverständnissen :)

Ciao,
_
Ob ich das nun gut finde, weiß ich noch nicht.

mwanaheri
27-09-2004, 08:21
Ob ich das nun gut finde, weiß ich noch nicht.


Aber das muss doch so sein. Eine Klasse muss doch auf ihre eigenen Variablen
zugreifen können, sonst könnte sie nicht damit arbeiten und die privaten Variablen wären für die Klasse vollkommen nutzlos. Und wenn du für die Klasse eine Methode vorsiehst, die die Variable ausgibt, wäre es doch idiotisch, wenn die Variable nicht ausgegeben werden würde. Da die Ausgabemethode public ist, kann sie auch aufgerufen werden. Die Variable selbst allerdings kannst du nicht von einer anderen Methode aus bearbeiten.

peschmae
27-09-2004, 09:11
Ich denke die Idee war eher dass nur Methoden die zu einem Objekt "gehören" auf private Variablen desselben Objekts zugriff haben.

MfG Peschmä

mwanaheri
27-09-2004, 11:50
Jo, aber hier gehört doch main dem Objekt.

Sym
27-09-2004, 13:39
Jo, aber hier gehört doch main dem Objekt.
Nein, sie gehört nicht zu dem Objekt, auf dem gearbeitet wird. Die Main-Methode wird von der Machine angesprochen und dort wird ein neues Objekt der Klasse instanziiert.
So macht private für mich keinen Sinn. Da könnt man ja vielleicht wirklich schindluder mit treiben... Oder ist es nicht gewollt?

mwanaheri
27-09-2004, 15:56
Tja, aber die Methode main ist public. Also von außen ansprechbar.
Eine public-Methode kann durchaus private-Variablen verarbeiten. Es ist doch
nicht ungewöhnlich, für eine private-Variable eine getter-Methode
zu bauen. So kann der Wert der Variablen zwar ermittelt werden, aber ohne eine entsprechende Setter-Methode nicht von außen gesetzt werden. Das ist sogar eine sehr sinnvolle Staffelung.
Wenn eine Variable also gänzlich unsichtbar sein soll, muss sie selbst private sein
und alle Methoden, die diese Variable zurückgeben.

Sym
27-09-2004, 16:04
Tja, aber die Methode main ist public. Also von außen ansprechbar.
Eine public-Methode kann durchaus private-Variablen verarbeiten. Es ist doch
nicht ungewöhnlich, für eine private-Variable eine getter-Methode
zu bauen. So kann der Wert der Variablen zwar ermittelt werden, aber ohne eine entsprechende Setter-Methode nicht von außen gesetzt werden. Das ist sogar eine sehr sinnvolle Staffelung.
Wenn eine Variable also gänzlich unsichtbar sein soll, muss sie selbst private sein
und alle Methoden, die diese Variable zurückgeben.
[ ] Du hast die Problemstellung verstanden.

Also, Du sprichst hier von Kapselung. Das ist gar nicht das Problem! Es gibt in der Klasse Counter eine private variable min. In der Methode Main wird eine Instanz der Klasse gebildet. Dh die eigentliche Main-Methode gehört jedoch nicht zu der Instanz (jetzt mal vom static abgesehen).
Trotzdem kann anscheinend die Main-Methode auf die Variabel min zugreifen.
Ich hoffe, das war jetzt verständlich.

sixfriends
28-09-2004, 02:12
Lasst uns mal zusammenfassen:
Die main-Methode steht in der Klasse Counter. Damit "gehört" die Klasse main auch zu jedem Objekt vom Typ Counter, das angelegt wird. Punkt.

Wäre die Klasse Counter public könnte man sogar ausserhalb dieser Klasse ein Objekt vom Typ Counter anlegen und von diesem per OBJEKT_NAME.main(args) auf die main Funktion von Counter zugreifen, beispielsweise wenn man die Klasse batch-fähig machen möchte. Also wo liegt das Problem?

peschmae
28-09-2004, 05:50
Lasst uns mal zusammenfassen:
Die main-Methode steht in der Klasse Counter. Damit "gehört" die Klasse main auch zu jedem Objekt vom Typ Counter, das angelegt wird. Punkt.

Naja, von der logik her gehört eine Static-Methode mehr zur Klasse als zu den einzelnen Objekten.



Wäre die Klasse Counter public könnte man sogar ausserhalb dieser Klasse ein Objekt vom Typ Counter anlegen und von diesem per OBJEKT_NAME.main(args) auf die main Funktion von Counter zugreifen, beispielsweise wenn man die Klasse batch-fähig machen möchte. Also wo liegt das Problem?

Was?

MfG Peschmä

Sym
28-09-2004, 09:54
Lasst uns mal zusammenfassen:
Die main-Methode steht in der Klasse Counter. Damit "gehört" die Klasse main auch zu jedem Objekt vom Typ Counter, das angelegt wird. Punkt.

Wäre die Klasse Counter public könnte man sogar ausserhalb dieser Klasse ein Objekt vom Typ Counter anlegen und von diesem per OBJEKT_NAME.main(args) auf die main Funktion von Counter zugreifen, beispielsweise wenn man die Klasse batch-fähig machen möchte. Also wo liegt das Problem?
Wenn ich nun zwei Objekte von einer Klasser erzeuge, wie hängen die denn Deiner Meinung nach zusammen? Warum sollen Methoden des einen Objektes auf private variablen des anderen Objektes zugreifen können?
Das zweite verstehe ich nun auch nicht ganz.

mwanaheri
28-09-2004, 12:11
Wenn ich nun zwei Objekte von einer Klasser erzeuge, wie hängen die denn Deiner Meinung nach zusammen? Warum sollen Methoden des einen Objektes auf private variablen des anderen Objektes zugreifen können?
Das zweite verstehe ich nun auch nicht ganz.

Das können sie nicht (glaub ich). Aber auf die public-Methode schon.

Sym
28-09-2004, 13:18
Das können sie nicht (glaub ich). Aber auf die public-Methode schon.
Dann schau Dir die Problemstellung an, denn genau das wird dort bestätigt.

sixfriends
28-09-2004, 13:52
Hab die Stelle überlesen, sollte wirklich so nicht sein. Allerdings ist es auch egal, da die Methoden, die dann auf das Private Zeugs zugreifen können in der selben Klasse stehen (und dann auch vermutlich vom selben Autor stammen, der sich dann dabei etwas gedacht hat).
Grundsätzlich kann man die Situation ja mit einer Listenstruktur vergleichen. Und wenn ich in so einer Klasse auf private Zeug vom nächsten Element zugreifen kann, macht das auch irgendwie Sinn. Denn damit kann ich intern auf die Private Variablen zugreifen und von aussen trotzdem nicht. Soll heissen: Die Datenstruktur ist nach aussen geschützt, kann aber von Methoden der selben Klasse genutzt werden.

Zum zweiten, was ich gemeint habe ein kleines Beispiel:
Datei foo.java:

public class foo {
public static void main(String[] args) {
System.out.println(args[0]);
}
}
Datei foo_batch.java:

public class foo_batch {
public static void main(String[] args) {
String[] bar = [Stringliste von irgendwo her];
foo test = new foo();
for (int i=0;i<bar.length;i++) {
test.main(bar[i]);
}
}
}
Damit funzen "java foo mein_string" und "java foo_batch" als Aufrufe aus der Kommandozeile.