Java OOP statische Variable inkrement Ausgabe

palaber

Captain
Registriert
Juni 2006
Beiträge
3.856
Hallo zusammen,

ich hab mal mit Programmieren angefangen. Hat mich bisher nie interessiert, aber jetzt wird es doch langsam mal Zeit dafür, als Informatikstudent ;)

Mein Problem ist, das ich aus einer Klasse eine statische Variable inkrementieren will.
Eigentlich geht es auch, aber nicht so wie ich es will :(

Worum es geht: Ich lege Objekte an, welche eine ID haben, die automatisch hochgezählt werden soll.
Lege ich in der Main ein Objekt an, zählt die ID auf 1 --> alles ok.
Lege ich in der Main allerdings zwei Objekte an, ist die ID für Objekt 1 und 2 dieselbe und zwar beides mal "2".
Lege ich 3 Objekte an, wird die ID für alle Objekte als "3" ausgegeben.
Leider hab ich keinen Plan woran das liegt und googlen hat mir auch nicht geholfen.

Jetzt hoffe ich auf euch. Schon mal danke!

Anbei noch der Quellcode:

Code:
package immatri;

public class Immatrikulation extends Student {

	private static int id=0;
	private String datum;
	private boolean gezahlt;
	

//getter & setter
	
	public String getDatum() {
		return datum;
	}


	public void setDatum(String datum) {
		this.datum = datum;
	}


	public boolean getGezahlt() {
		return gezahlt;
	}


	public void setGezahlt(boolean gezahlt) {
		this.gezahlt = gezahlt;
	}


	public static int getId() {
		return id;
	}

//konstruktor		
	
	public Immatrikulation(String name, String vorname, String datum, boolean gezahlt) {
			super(name, vorname);       //erbt von der Oberklasse Student
			setDatum(datum);
			setGezahlt(gezahlt);
			Immatrikulation.id++;         //erhöhen von id um 1
	
	}

	@Override
	public String toString(){
		return getMatnr()+" "+getName()+" "+ getVorname()+" "+getId() +" "+ getDatum() +" "+ getGezahlt()+"\n";
		
	}
	
	
}
-----------------------------------------------------------------------------------------------------------------
MAIN
-----------------------------------------------------------------------------------------------------------------
Code:
package immatri;

public class Test {

	
	public static void main(String[] args) {
		
		Immatrikulation s1=new Immatrikulation ("Tom", "Rip", "25.12.09", true);
		Immatrikulation s2=new Immatrikulation ("Harry", "Müller", "01.01.2010", false);
		
		
		System.out.println(s1);
		System.out.println(s2);
		}
}
 
Zuletzt bearbeitet:
Genau das ist ja der Sinn hinter dem static. Die Variable ist statisch und somit in jeder Instanz der Klasse Immatrikulation die gleiche. Sie wird also nur einmal angelegt und existiert von da an immer.
Du veraenderst sozusagen jedes mal den Wert der gleichen Variable und somit haben alle Instanzen die gleiche ID

Folgender Link koennte dir das nocheinmal verdeutlichen : http://www.roseindia.net/java/beginners/staticvariable.shtml
 
Zuletzt bearbeitet:
liegt daran, dass deine id static ist...das bedeutet, dass alle objekte dieser klasse die selbe variable verwenden und somit ist es ja dann klar, dass die bei 2 objekten 2 ist, bei 3 3 usw.
lg
 
Der Bezeichner static sagt für deine ID-Variable soviel aus, dass es von dieser nur ein Exemplar gibt, Du kannst soviele Objekte erzeugen wie Du willst, sie werden alle den gleichen Wert teilen.

Gegenvorschlag:
Generiere Zufallszahlen als ID und wenn Du dann Objekte erzeugst, überprüfe doppelte IDs und lass ggf. neue generieren. Ist etwas ineffizient, sollte aber für das Beispiel reichen. Ich geh einfach mal davon aus, dass Du keine großen Mengen von Objekten erstellst

edit:
Mist, zu langsam :)
 
Zuletzt bearbeitet:
du bist nicht zufällig an der Hochschule Mannheim oder?

wie die anderen schon sagten, die variable ist statisch, also alle Objekte teilen sich diese Variable. Oder anders gesagt es ist eine Klassenvariable die für alle Objekte die aus ihr erzeugt werden gilt.
Du kannst den Code z.b. dafür benutzen, um deine erzeugten Objekte zu zählen :)

Für andere Zwecke einfach das statische weg machen, dann hat jedes Objekt ein Feld.
Wenn es statisch ist, greifen alle Objekte für die Variable auf den selben Speicherbereich zu.
 
Bitte den Code in Code-Tags packen ([code ][ /code]).


Was du willst sind keine Klassenvariablen sondern Instanzvariablen. "static" markiert Klassenvariablen, kein "static" markiert Instanzvariablen. Klassenvariablen gelten für alle Objekte, die aus dieser Klasse erzeugt wurden.

Beispiel:
Code:
public class Auto {
  private String marke;
  private static boolean brauchtFuehrerschein = true;

  public Auto(String marke) {
    this.marke = marke;
  }

  public String getMarke() {
    return marke;
  }

  public static void setFuehrerschein(boolean brauchtFuehrerschein) {
    this.brauchtFuehrerscheint = brauchtFuehrerschein;
  }

  public static boolean getFuehrerschein() {
    return brauchtFuehrerschein;
  }
}

Alles mit "static" sind Klassenvariablen oder -methoden, alles ohne "static" sind Instanzvariablen und Instanzmethoden. Instanzvariablen und -methoden existieren erst, wenn die Klasse dazu "missbraucht" wurde, um ein Objekt zu erzeugen (zu instantiieren).

Das geht:
Code:
Auto.setFuehrerschein(true);
boolean lappen = Auto.getFuehrerschein();

Auto audi = new Auto("Audi");
ausgeben(audi.getMarke());

audi.setFuehrerschein(false); // Beide Methoden sind gleich!
Auto.setFuehrerschein(false); // Man sollte aber die Klassenmethode bevorzugen, um den Unterschied von Klassen- und Instanzmethode gleich zu erkennen.

Das geht nicht:
ausgabe(Auto.getMarke()); // Es muss erst ein Objekt vom Typ Auto instanziiert werden, und nur dort darf man dann diese Methode aufrufen.
 
Also das mit Static hab ich dann geschnallt, aber warum funktioniert das Aufzählen in dem Code?
Vielleicht is es auch einfach schon zu spät, das ich es nimmer raff. Aber das Bsp. is doch eigentlich das selbe.
Und für jedes Objekt (z.B. Kunde 1, Kunde 2... zählt die kdnr hoch).

Klasse Kunde:
Code:
package autohaus;

public class Kunde {
	
	private String name;
	private String vorname;
	private static int kdnr=1000;
	
	public String getName() {
		return name;
		}
	public void setName(String name) {
		this.name = name;
		}
	public String getVorname() {
		return vorname;
		}
	public void setVorname(String vorname) {
		this.vorname = vorname;
		}
	public int getKdnr() {
		return kdnr;
		}
	
	public Kunde(String name, String vorname){
		Kunde.kdnr++;
		this.setName(name);
		this.setVorname(vorname);		
		}
	
}


Main:
Code:
package autohaus;

public class TestAutohaus {

	
	public static void main(String[] args) {
		
	
		Kunde k1=new Kunde("Hans", "Schmied");
		ausgeben2(k1);
		Kunde k2=new Kunde("Horst", "Schlämmer");
		ausgeben2(k2);
	        }	
	

	private static void ausgeben2(Kunde k) {
		System.out.println("Kunden ID: "+k.getKdnr()+"\n Name: "+k.getName()+"\n Vorname: "+k.getVorname());
		
	}


}

PS: Ne bin nicht in Mannheim an der FH

Achja, vielen Dank für die ganzen Antworten!
 
Zuletzt bearbeitet:
ja weil es static ist...eine variable für ALLE instanzen davon
und da im konstruktor dann steht: Kunde.kdnr++; zählt es hoch...
btw schreib lieber nur kdnr++;
und wenn kdnr als parameter vorkommt schreib this.kdnr++;
is schöner ;)
Ergänzung ()

edit: auch bei name und vorname brauchst du nicht die setter verwenden...kannst ja in der klasse direkt auf die variablen zugreifen...
 
Code:
Kunde k1=new Kunde("Hans", "Schmied");
ausgeben2(k1);
Kunde k2=new Kunde("Horst", "Schlämmer");
ausgeben2(k2);


Code:
Immatrikulation s1=new Immatrikulation ("Tom", "Rip", "25.12.09", true);
Immatrikulation s2=new Immatrikulation ("Harry", "Müller", "01.01.2010", false);
		
	
System.out.println(s1);
System.out.println(s2);

Vergleich die mal.
Beim ersten wird die 2te Instanz der Klasse erst erstellt, nachdem die static Variable der ersten ausgegeben wurde. Beim 2ten Beispiel wird die static aus beiden Instanzen (die selbe Variable) erst ausgegeben, nachdem beide Instanzen erstellt wurden.

Edit:
Für eine fortlaufende ID sollte du in deiner Klasse zusätzlich zu der static noch eine normale (Instanz) Variable machen und diese im Konstruktor nachdem deine static hochgezählt wurde auf den Wert der static setzen. Somit hast du mit deiner static die gesamtzahl deiner Instanzen und mit den Instanzvariablen die ID jeder Instanz. SO in etwa müsste das aussehen:

Code:
public class Immatrikulation extends Student {

	private static int anzahl=0;
        private int id;
	private String datum;
	private boolean gezahlt;

....

//konstruktor		
	
	public Immatrikulation(String name, String vorname, String datum, boolean gezahlt) {
			super(name, vorname);       //erbt von der Oberklasse Student
			setDatum(datum);
			setGezahlt(gezahlt);
			Immatrikulation.anzahl++;         //erhöhen von id um 1
                        id=Immatrikulation.anzahl;
	
	}
 
Zuletzt bearbeitet:
Ich würde es so machen:

Code:
package immatri;

public class Immatrikulation extends Student {
	private static int idcounter=0;
        private int id;
	private String datum;
	private boolean gezahlt;
	

//getter & setter
	
	public String getDatum() {
		return datum;
	}


	public void setDatum(String datum) {
		this.datum = datum;
	}


	public boolean getGezahlt() {
		return gezahlt;
	}


	public void setGezahlt(boolean gezahlt) {
		this.gezahlt = gezahlt;
	}


	public static int getId() {
		return id;
	}

//konstruktor		
	
	public Immatrikulation(String name, String vorname, String datum, boolean gezahlt) {
			super(name, vorname);       //erbt von der Oberklasse Student
			setDatum(datum);
			setGezahlt(gezahlt);
                        id = Immatrikulation.idcounter++;         //Diese Instanz id setzen und erhöhen von idcounter um 1
	}

	@Override
	public String toString(){
		return getMatnr()+" "+getName()+" "+ getVorname()+" "+getId() +" "+ getDatum() +" "+ getGezahlt()+"\n";
		
	}
}

idcounter zählt für alle Instanzen hoch und vergibt im Konstruktor den aktuellen Count an die eigene id und erhöht den Counter.
 
Hm aber mal was anderes: ne Klasse "Immatrikulation" von einer Klasse "Student" erben lassen? - bähbähbäh.
 
Wensentlich sinnvoller wäre es allerdings eine Klasse zu implementieren welche dann die Menge der Studenten / Kunden hält, oder wenns ganz einfach gehen soll eine ArrayList. Ersteres hat den vorteil einer richtigen Verwaltung, letztere den einer einfachen implementierung.
 

Ähnliche Themen

Antworten
14
Aufrufe
2.964
Zurück
Oben