Java "static" nicht verstanden und Programm funktioniert (noch) nicht

Anno

Lt. Commander
Registriert
Sep. 2007
Beiträge
1.387
Hi,

ich bräuchte mal bitte kurz eure Hilfe. Ich komm nicht weiter, da ich die Funktion static noch nicht verstanden haben. Deshalb verstehe ich auch die Fehlermeldung nicht. :(

Angabe:
angabe_cbs3sh4.png


Code:
class Seite13{ // class Prepaid{

	int telefonNummer;
	double guthaben;
	
	Seite13(int nummer, double guthaben){
		this.telefonNummer = nummer;
		this.guthaben = guthaben;
	}
	
	double getGuthaben(){
		return guthaben;
	}
	
	void aufladen(double betrag){
		this.guthaben += guthaben;
	}

	public static void main(String[] args){
		Seite13 myPrepaid = new Seite13(12345, 10);
		System.out.println(getGuthaben());
	}


}

fehler_cb2msl8.png







So funktioniert der Code zwar, aber 1. hab ich dann keine Ahnung, was das static genau macht und warum es damit funktioniert und 2. steht in der Angabe "double getGuthaben" und nicht "static double getGuthaben". :(
Code:
class Seite13{ // class Prepaid{

	int telefonNummer;
	static double guthaben;
	
	Seite13(int nummer, double guthaben){
		this.telefonNummer = nummer;
		this.guthaben = guthaben;
	}
	
	static double getGuthaben(){
		return guthaben;
	}
	
	void aufladen(double betrag){
		this.guthaben += guthaben;
	}

	public static void main(String[] args){
		Seite13 myPrepaid = new Seite13(12345, 10);
		System.out.println(getGuthaben());
	}


}
Ergebnis auf Konsole: "10.0"

Kann mir bitte jamand helfen?
Vielen Dank :)
 
Zuletzt bearbeitet:
In Java hast du zwei Kategorien, in die Klassen, Methoden und Variablen fallen können. Zum einen wäre das die statischen und die instanziierten.

Statisch ("static") bedeutet, dass diese Klassen, Methoden und Variablen genau einmal existieren.
Instanziiert (ohne "static") bedeutet, dass diese Klassen, Methoden und Variablen mehrfach in ihrer jeweils eigenen und unabhängigen Instanz existieren können.

Wenn eine statische Methoden auf zB eine instanziierte Variable zugreifen soll, dann musst du sagen, in welcher Instanz diese Variable zu finden ist. Umgekehrt ist das nicht nötig. Wenn also eine Instanzmethode auf eine statische Variable zugreifen will, muss keine Instanz angegeben werden - die Variable existiert ja nur einmal und daher ist eindeutig, was gemeint ist.


Und genau das ist das Problem in deinem Code.
Code:
public static void main(String[] args){
	Seite13 myPrepaid = new Seite13(12345, 10);
	System.out.println(getGuthaben());
}
getGuthaben() ist eine Instanzmethode, d. h. sie kann mehrfach in verschiedenen Instanzen existieren. Wenn du sie jetzt einfach so aufrufst, dann weiß Java nicht, in welcher Instanz sich diese Methode befindet. Schreibst du myPrepaid.getGuthaben(), dann ist die Instanz (die "myPrepaid" heißt) eindeutig bekannt.


PS: Instanziierte Klassen nennt man übrigens Objekte. ;)
 
Zuletzt bearbeitet:
Durch "static" wird die Methode statisch, deshalb wird es eine Methode der Klasse, nicht des Objekts.

Du willst in System.out eine statische Methode aufrufen, da diese genau so heißt wie die Methode des Objekts gibt der Compiler diese Meldung aus.

Richtig ist: myPrepaid.getGuthaben(), dann rufst du die Methode des Objekts auf und erhältst den Wert

Machst du die Methode statisch geht das natürlich auch, jedoch kannst du dann nicht die Guthaben der initialisierten Objekte ausgeben.
 
Hi,
Der Aufruf "System.out.println(getGuthaben());" ist falsch. Du rufst die Methode unabhängig von dem Objekt auf. Was du willst ist: "System.out.println(myPrepaid.getGuthaben());".
Was static macht kannste in jedem Java Buch z.B. "Java ist auch eine Insel" nachlesen.


MfG
Kale
 
Als Objekt:
Code:
public static void main(String[] args){
Seite13 myPrepaid = new Seite13(12345, 10);
System.out.println(myPrepaid.getGuthaben());
}
Statischer Zugriff (Dein 2 Code) ist genau dass (da getGuthaben static):
Code:
public static void main(String[] args){
Seite13 myPrepaid = new Seite13(12345, 10);
System.out.println(Seite13.getGuthaben());
}
 
Normalerweise sind deine Variablen Objektvariablen, d.h. jedes mal wenn du ein Objekt von deiner Klasse erzeugst, kann es verschiedene Werte haben (hier z.b. verschiedene Telefonnummern). Wenn du jetzt jedoch eine Variable mit static deklarierst, bedeutet dies, dass du eine Klassenvariable deklariest. Jedes Objekt das du nun erzeugt, wird genau diesen Wert haben (also hier in deinem Bsp. haben alle das gleiche Guthaben). Änderst du nun bei einem Objekt das Guthaben, wird auch bei allen anderen erzeugten Objekten das Guthaben verändert.
Wenn du ein gutes Buch für Anfänger möchtest, empfiehle ich dir "Java von Kopf bis Fuß" und eine kostenlose Variante mit "Java ist auch nur eine Insel".
 
Super, vielen Dank!
Damit funktioniert es nun und ich verstehe auch den Sinn dahinter. :)

Würdest du (e: ihr) sagen, dass die nachfolgende Lösung im Sinne der Aufgabenstellung richtig ist?
Zeilen 19,20,21 sind nicht nötig und ich habe sie nur zur Kontrolle eingefügt, ob das Programm dann funktioniert. Die Klasse wird ja eigentlich von einer anderen Klasse/Datei aufgerufen, wenn ich das richtig verstehe.


Code:
class Seite13{ // class Prepaid{

	int telefonNummer;
	double guthaben;
	
	Seite13(int nummer, double guthaben){
		this.telefonNummer = nummer;
		this.guthaben = guthaben;
	}
	
	double getGuthaben(){
		return guthaben;
	}
	
	void aufladen(double betrag){
		this.guthaben += betrag;
	}

	public static void main(String[] args){
		Seite13 myPrepaid = new Seite13(12345, 10);
		System.out.println(myPrepaid.getGuthaben());
	}
}

//
Ups, einen Fehler hab ich grade gefunden:
Zeile 16 lautet natürlich: this.guthaben += betrag;
 
Zuletzt bearbeitet:
Die Aufgabe hast du sinngemäß erfüllt. Aber (;)) hat man dir noch nichts über das Geheimnisprinzip, Zugriffsmodifizierer, Setter/Getter sowie die Java-Konventionen erzählt? Denn dazu fehlt noch was im Code.
 
Mit Geheimnisprinzip meinst du wahrscheinlich "private" ...? Könnte man evtl. reinmachen, habe ich aber gelassen, da es in der Aufgabe nicht verlangt war.

Setter wäre doch z. B. aufladen, oder? (Zumindest ähnlich)
Und ein Getter wäre getGuthaben. Oder sehe ich das falsch?

Welche Konvention habe ich denn nicht eingehalten?
 
Jepp, ich meine unter anderem den Kram mit private & Co. Schreibe das immer dazu! Wenn du später in einer Firma was codest, ist es sehr wahrscheinlich, dass ein anderer mal deine Objekte verwenden wird. Da wäre es gut, wenn er mit denen kein Schindluder treiben kann. Deswegen immer schön konsequent das Geheimnisprinzip anwenden.

Für die Telefonnummer fehlt noch wenigstens der Getter. Einen Setter bräuchte man hier nicht unbedingt. Die Nummer verändert sich ja normalerweise nicht. Allerdings kann man bei deinem Code beim Aufladen eine negative Zahl übergeben. ;)

Zum Thema Konventionen: Du hast deinen Code nicht kommentiert. So einfach ist das. ;)
 
Danke. :)
Da hast du Recht.

Ja, das mit der negativen Zahl weiß ich. Solange es in der Aufgabenstellung nicht verlangt wird, ist das für mich in Ordnung. :)
Wenn ich mal selbst ein (echtes) Programm schreibe, sieht das natürlich ganz anders aus. Hier gehts im Moment um Prüfungsfragen- und aufgaben, wo auch die Zeit ein sehr wichtiger Faktor ist. Also schreibe ich nur das, was auch verlangt wird.

Wenn du (und natürlich alle anderen) Lust hast, dann könntest du hier mal drüberschaun, ob man das so machen könnte. :)
Schaut in meinen Augen eigentlich ganz gut aus und ist ohne Fehler kompilierbar. :D



Angabe:
angabe_cb22k0q.png





Seite15.java
Code:
class Seite15{ // class Person{

	int ID;
	int nextId = 100;
	String name;
	int alter;
	Seite15Geschlecht geschlecht;

	Seite15(){
		this.ID = nextId;
		this.nextId++;
	}
	
	Seite15(String name, int alter, Seite15Geschlecht geschlecht){
		this.name = name;
		this.alter = alter;
		this.geschlecht = geschlecht;
	}
	
	int getId(){
		return ID;
	}
	
	String getName(){
		return name;
	}
	
	int getAlter(){
		return alter;
	}
	
	void setName(String name){
		this.name = name;
	}
	
	void setAlter(int alter){
		this.alter = alter;
	}
	
	public String toString(){
		return "ID: " + this.ID + "\nName: " + this.name + "\nAlter: " + this.alter + "\nGeschlecht: " + this.geschlecht;
	}
	
	public boolean equals(Seite15 obj){
		if(this.ID == obj.getId() && this.name == obj.getName() && this.alter == obj.getAlter()) return true;
		return false;
	}
}


Seite15Geschlecht.java
Code:
public enum Seite15Geschlecht{
	männlich, weiblich, baby, undefiniert
}


"Seite15" verwende ich deshalb, weil diese Aufgabe auf Seite 15 der Aufgabensammlung ist und ich so genau weiß, welche Aufgabe wo steht. Also nicht wundern ... :)
 
Gute Übungen für das erste Studiensemester, das Zeug kommt 100% dran :)
Für paar chillige Wochen im Studium, lern folgendes denn es verrät einiges über Objektorientierung:

Static hat verschiedene Bedeutungen, je nachdem ob es für Klassen, Methoden oder Variablen benutzt wird.
Dein Fehler oben war static bei einer Methode. Mit static kann man Methoden direkt aufrufen, ohne ein Objekt einer Klasse. Deshalb ist die main immer static, da sie einfach direkt aufgerufen werden muss ohne irgendwelche vorangestellen Objekte. Man kann sagen: Static bei Methoden hebelt die Objektorientierung aus ! Die Methoden werden also zu Funktionen.

Bei deiner 2ten Aufgabe ist eine Sinnlosigkeit drin :)
Du hast getter/setter für Variablen gemacht die nicht private sind. D.h. du kannst in der main "new Seite15...." machen und über das Objekt auf objekt.alter zugreifen. Der Sinn von gettern und settern ist aber genau um dies zu verhindern.

Außerhalb der Klasse soll niemand diese Variablen direkt ansteuern können. Dazu macht man "private int alter". Die Getter/Setter Methoden selbst sind allerdings public (wenn keine Sichtbarkeit angegeben ist public standard). Danach kannst du in der main nur noch objekt.getAlter() machen aber nicht mehr objekt.alter. Stell dir Bankkonten vor, wo jemand etwas draufzahlen soll, aber nicht wissen muss wie viel drauf ist.

Normalerweise macht man die Felder (=Objektvariablen) fast immer private und baut Getter/Setter. Immer nur das Minimum nach außen sichtbar machen um Probleme und Sicherheit nicht zu gefährden.

-------------

Das equals ist auch noch mehrfach zu verbessern, da es so nicht dem Zweck dient und überschrieben hast so auch nix da die Parameter anders sind, du hast nur Methoden "Überladen" -> gleiche Methode, andere Parameter.

1.
Dein Parameter bei der Equals ist "Seite15 obj", soll aber sein "Object obj" ! Du musst generell vergleichen können, ohne zu wissen was das "obj" ist und woher es kommt. Object ist in Java praktisch alles, selbst ein String, Integer etc.

2.
Du hast kein @override benutzt, dies macht man immer wenn man von Oberklassen Methoden überschreibt.
Alles in Java erbt von der Oberklasse "Object" (automatisch!). Darin sind die toString() und equals() enthalten.
Und daher sind sie überall präsent, in jeder Klasse die du schreibst. Das merkst du daran, dass wenn du eine leere Klasse machst, du dennoch ein klasse.toString() etc. hast ! Überschreibst du diese Methoden nicht in deiner Klasse, werden bei Bedarf eben die aus der "Object" Klasse benutzt ! Die erbende Klasse kann also alles was die Oberklasse kann - und man fügt der erbenden nur noch mehr Zeug ein, bzw. überschreibt den Kram aus der Oberklasse wenn man eine andere Funktionalität will.
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html

3.
Allerdings wissen die standard toSTring und Equals nicht wie sie mit deiner Klasse umgehen sollen, d.h. sie kennen die Struktur nicht. Deswegen muss man diese überschreiben. Gibst du nun per system.out ein Klassenobjekt aus, wird die toString() automatisch aufgerufen und du siehst nur Müll. Wenn du selbst eine toString() geschrieben hast, wird diese statt dem Standard Ding benutzt. Standard toString und Equals funktionieren nur bei einfachen Objekten, wie String x = "aaa".

4.
Da nun die Equals den Parameter Object hat, musst du folgendes machen:
- du prüfst mit "instanceof" erst mal ob der Parameter "obj" von deiner Klasse abstammt, also der in der du grade schreibst. Dazu machst "if (obj instanceof Seite15)". Damit hast du sichergestellt dass du korrekt vergleichen kannst, d.h. du hast auf jedem Fall 2 gleichartige Objekte - nun prüfst ob der Inhalt auch gleich ist ! Nun darfst du das "obj" casten, also "Seite test = (Seite15) obj" ohne das Fehler auftreten, instanceof ist nur true wenn es sich um zwei Seite15 Objekte handelt, oder um Klassen die davon erben. Das casten brauchst du da der Paramteter vom Typ "Object" ist, Java weiß zu dem Zeitpunkt nicht um welche Klasse es sich handelt - das musst du erst mal sagen und eben mit instanceof sicherstellen das alles rechtens ist. Danach darfst du deine Variablen normal vergleichen wie du es oben tust.

5.
Die toString() ist ok. Aber ! Wenn Dinge viele "+" Zeichen enthalten, benutze einen StringBuffer(). Das hat den Grund das "+" sehr viel aufwand betreibt. Für jedes + muss Java einen neuen (größeren) Speicherblock reservieren und die vorherigen Strings umkopieren. Das zieht extrem die Leistung eines Programmes runter. Große Texte verarbeiten wäre ohne Buffer zu nutzen ein PC-Killer, selbst die neuesten gehen in die Knie ! Falls du mal C lernst wirst du genauer verstehen was ich meine, bis dahin: Stringbuffer wenn es mal mehr Zeug wird :)

6.
Das return buffer.toString() ruft das toString() aus dem Objekt "buffer" auf, also den Standard Kram der darin steckt. Es ruft nicht deine toString() auf, denn deine gilt nur für das Objekt deiner Klasse (new Seite15....).

Hoffe das war halbwegs verständlich.

Code:
public class Seite15 {
	private int alter;

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Seite15) {
			Seite15 test = (Seite15) obj;
			if (this.alter == test.getAlter()) {
				System.out.println("Alter gleich, Objekte gleich! -> true");
				return true;
			} else {
				System.out.println("Alter verschieden! Objekte nicht gleich! -> false");
			}
		}
		return false;
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer("Hallo");
		buffer.append(" Welt!");
		return buffer.toString();
	}

	public int getAlter() {
		return this.alter;
	}

	public static void main(String[] args) {

		Seite15 aa = new Seite15();
		// Ruft automatisch toString() aus der Klasse Seite15 auf.
		// Wenn kein toString() überschrieben wurde Ausgabe wie "package.Seite15@35345d"
		System.out.println(aa); // Ausgabe: Hallo Welt!

	}
}
 
Zuletzt bearbeitet:
black90 schrieb:
5.
Die toString() ist ok. Aber ! Wenn Dinge viele "+" Zeichen enthalten, benutze einen StringBuffer(). Das hat den Grund das "+" sehr viel aufwand betreibt. Für jedes + muss Java einen neuen (größeren) Speicherblock reservieren und die vorherigen Strings umkopieren. Das zieht extrem die Leistung eines Programmes runter. Große Texte verarbeiten wäre ohne Buffer zu nutzen ein PC-Killer, selbst die neuesten gehen in die Knie ! Falls du mal C lernst wirst du genauer verstehen was ich meine, bis dahin: Stringbuffer wenn es mal mehr Zeug wird :)

Jede moderne VM für Java wandelt "A" + "B" beim Kompilieren in new StringBuilder().append("A").append("B").toString() um. Zumal der TS nicht im Ansatz in einem Szenario ist, in dem er Probleme bekommen würde, wenn das nicht so wäre, selbst wenn seine Klasse noch 1000 andere Attribute ähnlicher Länge zur Ausgabe hätte. Da müssen, wie du sagtest, die Texte schon groß sein.
Ansonsten sind Strings halt immutable und das ist toll. Es gibt Sprachen, die quasi nur immutables nutzen und unter anderem deswegen sehr viel eleganter sind als Java. Der Objekt-Overhead ist dadurch natürlich größer, aber in den meisten Fällen vernachlässigbar, vor allem wenn man sich dann in multithreaded Anwendungen den Synchonisierungsmüll und -Kopfschmerz sparen kann. Würde Java heute noch mal entworfen werden, dann wären sehr viel mehr Klassen immutable. Es macht beispielsweise überhaupt keinen Sinn, dass Date und Point nicht immutable sind. Ein Datum ist ein Datum und ein Punkt ist ein Punkt. Ändere ich den Tag oder die Y-Koordinate, dann habe ich eben einen anderen Tag/Punkt.

Im Fall des TS wäre ich aus Wartbarkeitsgründen schlicht für

Code:
String.format("ID: %s, Name: %s, Alter: %s, Geschlecht: %s ", id, name, alter, geschlecht);

Und zum Thema equals: die allererste Prüfung beim Zugriff auf das Fremdobjekt sollte natürlich immer die auf null sein.

Eclipse produziert das hier:

Code:
@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Seite15 other = (Seite15) obj;
		if (ID != other.ID)
			return false;
		if (alter != other.alter)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (nextId != other.nextId)
			return false;
		return true;
	}

Detailunterschied zur vorherigen Lösung: getClass funktioniert anders als Instanceof, da könnte man über Vor- und Nachteile nachdenken zur Übung.
Bei gleichen Daten ist a.equals(b) unter Verwendung von instanceof nicht zwingend das gleiche wie b.equals(a), bei getClass schon. equals via getClass ist gut weil es das Symmetrieprinzip erfüllt, Joshua Bloch findet es blöd, weil er lieber das Liskovsche Substitutionsprinzip umsetzt und deshalb instanceof nimmt. Es gibt wohl kein richtig oder falsch, die Umsetzung sollte allerdings speziell daraufhin dokumentiert werden.

Und es kommt noch ein weiteres Problem des TS ans Tageslicht: this.name == obj.getName() geht zwar, Referenzgleichheit ist an dieser Stelle aber nicht das, was man möchte.

Zum Thema getter/setter: Kapselung hat zwei Aspekte. Es geht nicht nur darum, dass niemand direkt auf den internen Zustand zugreifen können soll, weil er das nicht darf, sondern auch, weil er sich Anhängigkeiten einfängt. Möchtest du das Attribut name in surname umbenennen, dann hast du ohne Kapselung ein Problem, denn die ganze Welt da draußen ist zu dir nur dann noch code- und binärkompatibel, wenn name weiterhin name heißt. Hast du jedoch Getter und Setter, die möglicherweise gar über einen eigenen Typ abstrahiert werden (z.B. durch ein Interface), dann kannst du mit den Internas deiner Klasse anstellen, was du möchtest, es würde keiner merken.
Ich erwähne es nur deswegen, weil Leute in den ersten Programmiervorlesungen immer schnell den Eindruck bekommen, dass Kapselung nur für "Du DARFST da nicht direkt zugreifen weil ich es so will, nänänänä" gut ist. Sicherheit ist ein Thema, Wartbarkeit das andere.
 
Zuletzt bearbeitet:
Kleine Anmerkung zur Aufgabe 5:

Falls du gut darstehen willst, überschreibe zusätzlich noch die hashcode() Methode.
Immer, wenn man equals() überschreibt, sollte man auch hashcode() überschreiben. Es gibt viel Literatur dazu, aber dieser Stackoverflow post beschreibt es sehr treffend http://stackoverflow.com/a/27609

Kannst so bissel angeben ;)
 
Bei der Equals brauchst kein check auf null, da man mit null Objekten ein false vom instanceof bekommt und der code nicht weiter geht. Braucht man nur in anderen Methoden, wie beim Überschreiben von Listen, da darf es halt kein null sein.

Was der Compiler bei Strings macht ist egal, es geht um die Code Lesbarkeit, die ist sogar wichtiger als die Effizienz. Auf den Compiler kann und soll man sich nicht verlassen. Außerdem gilt das nicht überall mit dem Compiler Optimierungen, z.B. sollte man Dateizugriffe immer buffern.

Naja, Variablen umbenennen ist immer eine Sache die man lieber lassen als tun sollte. Um sowas zu vermeiden gibt es extra Leute die sich mit UML die Zeit totschlagen. Vorausplanen statt pfuschen.
 
Zuletzt bearbeitet:
Vielen Dank für eure Antworten. :)

Ich hab mir mal die Lösungen der Tutoren angeschaut und die machen es auch so. Das ist zwar aus einer anderen Aufgabe, aber vom Prinzip eigentlich das gleiche.
Hier mal deren Lösungsvorschlag:

Code:
	...
	...

	public boolean equals(PKW pkw)
	{
		if(this.automarke == pkw.getAutomarke() && this.kennzeichen == pkw.getKennzeichen() && this.sitzplaetze == pkw.getSitzplaetze())
		{
			return true;
		}
		return false;
	}

	public int hashCode()
	{
		return this.automarke.hashCode()+this.fahrzeugnummer+this.kennzeichen.hashCode();
	}

	public String toString()
	{
		return "Kennzeichen: "+this.kennzeichen+"\nNr: "+this.fahrzeugnummer+"\nAnzahl der Sitze: "+ this.sitzplaetze;
	}

}


Ich habs dann mal so übernommen:

Code:
class Seite15{ // class Person{

	private int ID;
	private int nextId = 100;
	private String name;
	private int alter;
	private Seite15Geschlecht geschlecht;

	Seite15(){
		this.ID = nextId;
		this.nextId++;
	}
	
	Seite15(String name, int alter, Seite15Geschlecht geschlecht){
		this.name = name;
		this.alter = alter;
		this.geschlecht = geschlecht;
	}
	
	public int getId(){
		return ID;
	}
	
	public String getName(){
		return name;
	}
	
	public int getAlter(){
		return alter;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public void setAlter(int alter){
		this.alter = alter;
	}
	
	public String toString(){
		return "ID: " + this.ID + "\nName: " + this.name + "\nAlter: " + this.alter + "\nGeschlecht: " + this.geschlecht;
	}

	public boolean equals(Seite15 obj){
		if(this.ID == obj.getId() && this.name == obj.getName() && this.alter == obj.getAlter()) return true;
	return false;
	}
	
	public int hashCode(){
		return this.name.hashCode()+this.ID+this.alter;
	}
}
/ kleine Anpassung in Zeile 50
 
Zuletzt bearbeitet:
Die equals geht so nicht. Kracht für null, statt false zu liefern. Schau dir mal den Link von CapFuture an, da kann man viel lernen.
 
Grad probiert, da kracht gar nix und man bekommt ein false

Code:
		Seite15 aa = new Seite15();
		LinkedList<String> bb = null;
		Seite15 cc = null;
		System.out.println(aa.equals(bb)); // false
		System.out.println(aa.equals(cc)); // false
 
Musst du mir mal verraten, wie du in Zeile 45 folgenden Ausdruck auflöst
Code:
obj.getId()
für obj = null;
 
Jetzt hab ich noch ne kurze Frage.

Bis Zeile 67 funktioniert anscheinend alles. Nur der Defaultkonstruktor wird nicht aufgerufen. (?)
Die Ausgabe von Zeile 67 lautet "0". Das versteh ich jetzt nicht ganz.

Ich dachte, der Standardkonstruktor wird immer dann aufgerufen, wenn das Objekt erzeugt wird.
In der Angabe steht auch, dass wir zwei Konstruktoren machen sollen:
Implementieren Sie einen Default-Konstruktor, der die eindeutige und fortlaufende ID setzt und einen Custom-Konstruktor Person(String name, int alter, Geschlecht geschlecht), der alle Objektvariablen setzt.

Kann mir bitte jemand kurz helfen? :)

Code:
public class Seite15{ // public class Person{

	private int ID;
	private int nextId = 100;
	private String name;
	private int alter;
	private Seite15Geschlecht geschlecht;

	Seite15(){
		this.ID = this.nextId;
		this.nextId++;
		System.out.println("test default konst.");
	}
	
	Seite15(String name, int alter, Seite15Geschlecht geschlecht){
		this.name = name;
		this.alter = alter;
		this.geschlecht = geschlecht;
	}
	
	public int getId(){
		return ID;
	}
	
	public String getName(){
		return name;
	}
	
	public int getAlter(){
		return alter;
	}
	
	public Seite15Geschlecht getGeschlecht(){
		return geschlecht;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public void setAlter(int alter){
		this.alter = alter;
	}
	
	public String toString(){
		return "ID: " + this.ID + "\nName: " + this.name + "\nAlter: " + this.alter + "\nGeschlecht: " + this.geschlecht;
	}

	public boolean equals(Seite15 obj){
		if(this.ID == obj.getId() && this.name == obj.getName() && this.alter == obj.getAlter()) return true;
	return false;
	}
	
	public int hashCode(){
		return this.name.hashCode()+this.ID+this.alter;
	}
	
	// Test auf Funktion ...
	public static void main(String[] args){
		Seite15 myPerson = new Seite15("Hans", 99, Seite15Geschlecht.maennlich);
		System.out.println(myPerson.getAlter()); // 99
		System.out.println(myPerson.getGeschlecht()); // maennlich
		myPerson.setAlter(11);
		System.out.println(myPerson.getAlter()); // 11
		myPerson.setName("Wurst");
		System.out.println(myPerson.getName()); // Wurst
		System.out.println(myPerson.getId()); // 0?! sollte aber 100 sein!
		
		
	}
}
 
Zurück
Oben