Autohaus

cpuman990

Cadet 4th Year
Registriert
Juli 2014
Beiträge
89
Hallo zusammen,
ich habe mir für Bluej (java) folgende Aufgabe gestellt: Es gibt die Klasse Kunde, Auto und die (Test)-Klasse Autohaus.
Die Klasse Auto enthält Attribute von Autos und den Konstruktor zum Erzeugen eines Auto-Objekts. In der Klasse Autohaus soll ein Feld erzeugt werden, in dem Autoobjekte gespeichert werden. In der Klasse Kunde soll dann eine Art Liste für den Kunden ausgegeben werden von den vorhandenen Autos.

public class Auto {
int id;
String marke;
String modell;
String farbe;
String motor;
String ausstattung;
int anzahlsitze;
int verbrauch;
String felge;
int preis;

public Auto( int ID, String Marke, String Modell, String Farbe, String Motor, String Ausstattung, int Anzahlsitze, int Verbrauch, String Felge, int Preis){
id = ID;
marke = Marke;
modell = Modell;
farbe = Farbe;
motor = Motor;
ausstattung = Ausstattung;
anzahlsitze = Anzahlsitze;
verbrauch = Verbrauch;
felge = Felge;
preis = Preis;


}

}
Das war der Quelltext zur Klasse Auto.
public class Autohaus{
Auto [] pkw;
int anzahl;

public Autohaus( ){
pkw = new Auto[5];
pkw [0]= new Auto();
}



}
Und hier der Quelltext zu Autohaus.
Mein Problem ist, dass ich, wenn ich ein Auto erzeuge, dem Feld von Autohaus nicht die eingegeben Daten zuweisen kann. Hier muss ich das dann immer über den Konstruktor in der Klasse Autohaus selbst machen. Weiß jemand, wie man mit dem Autokonstruktor erzeugte Objekte automatisch einem der Felder zuweisen kann ?

Danke im Voraus !
 
Kein schöner Code :D

So erstellt du ja immer nur ein Auto pro Autohaus.
Nimm eine Liste statt ein Array und mach eine Methode in die Klasse Autohaus mit addAuto(Auto auto) mit der du Autos in die Liste einfügen kannst.

Wieso machst du das über den Konstruktor? Der wird pro Objekt ja nur einmal aufgerufen wobei du Methoden öfter aufrufen kannst.

Würde auch mehr mit getter und setter arbeiten.
Das Autohaus erstellt dir ja auch nur ein Auto mit Standardkonstruktor = keine Attributzuweisungen in deinem Fall.
 
Zuletzt bearbeitet:
Danke für die schnelle Antwort.
Bin leider Neuling im Programmieren. Ich würde schon gerne ein Feld verwenden mit dem Datentyp Auto. Das mit dem Konstruktor bedeutet also, das Feld in eine Methode zu verpacken ? Ich möchte, indem ich den Autokonstruktor aufrufe ja mehrere Autos erstellen, z.B. auto1, auto2 etc. .Könnte ich diese Objekte dann gleich abspeichern in dem Array von Autohaus ?. Wenn ich in Autohaus eine Methode für das Erstellen von Autos machen würde, dann wäre Die Klasse Auto ja eigentlich nur noch dafür da, Attribute für Auto festzulegen. Der Konstruktor wäre dann ja quasi unwichtig ?
Ergänzung ()

Liste ist mir halt noch gar nicht bekannt :D.
 
Der Autokonstruktor beschreibt ja ein Auto.

Du könntest mehrere Autos im Autohauskonstruktor erstellen und hinzufügen aber das ist kein guter Stil .. das ist ziemlich schlechter Stil.
Arbeite mit Methoden gerade wenn du noch am Anfang bist, sollte man sich einen guten Stil anlernen alles andere führt zwar irgendwie auch zum Ergebnis aber wenn du mal wirklich größerere Projekte hast, dann brauchst du eine vernünftige Struktur.

Den Konstruktor würde ich auch versuchen komplett frei zu lassen - also ein Standardkonstruktor Auto(){} - Fülle die Attribute über Methoden.
 
Zuletzt bearbeitet:
Ok ja. Hierfür müsste ich ja mehrmals in den Konstruktor den autoattributen werte zuweisen. Also die Klasse auto so lassen und dann in Autohaus eine Methode machen, die sich auf die Klasse auto bezieht?
Ergänzung ()

public class Auto {
int id;
String marke;
String modell;
String farbe;
String motor;
String ausstattung;
int anzahlsitze;
int verbrauch;
String felge;
int preis;

public Auto( ){



}

}
So also den Konstruktor lassen ?
 
Ja - Listen haben den Vorteil, dass du keine Größe beim Erstellen zuweisen musst.

Ja in Autohaus eine Methode die als Input ein Autoobjekt bekommt und das dann in die Liste der Autos einfügt.
 
Ich würde auch Getter und Setter generieren, dann kannst du später
1. Attribute ändern
2. Auf bestimmte Details deiner Autos zugreifen

Razzer meint folgendes:
public class Autohaus {
....

public newAuto() {
this.autoList.add(new Auto(...))
}

}

das meint er glaube ich.
 
@Auto Klasse
Sagt dir der Begriff getter und setter was?

Du machst für jedes Attibut
String getMarke() {return marke;}
void setMarke(String marke){this.marke=marke;}

Sollte nämlich ein Attribut gelöscht oder hinzukommen juckt das den Konstruktor somit nicht.

@Autohaus

void addAuto(Auto auto) {autoListe.add(auto);}

Wobei autoListe die Liste ist in der die Autos gespeichert werden.
 
Nein setter und getter sind mir leider kein Begriff :rolleyes:. Wenn ich es ohne dieses Getter und setter machen will, also so einfach wie möglich, bzw. am unelegantesten :D, dann brauche ich ja eine methode in Authohaus die autos erstellt und diese in das Feld einfügt ? und wie würde diese aussehen ?
Ergänzung ()

bzw. wie würde es funktionieren wenn man in auto über den konstruktor mehrere autos erstellt und diese dann in das feld einfügen möchte ?
Bisher konnte ich nur mit new Auto(), dem Feld Autos zuweisen, aber keine Autos aus dem Konstruktor von Auto verwenden oder von einer Methode in Autohaus.
Ergänzung ()

wo setzt man bei
void addAuto(Auto auto) {autoListe.add(auto);}
die Attributwerte eines Autos ?
 
Sofern du es bei den vielen Werten im Konstruktor belassen möchtest hilft dir das vielleicht ein Stück weiter. Ich habe deine Felder etwas zusammengefasst und für die Ausgabe eine provisorische toString-Methode geschrieben die immer dann aufgerufen wird, wenn du das Auto ausgeben möchtest.

Code:
public class Auto {
    String marke, modell, farbe, motor, ausstattung, felge;
    int id, anzahlsitze, preis;
    double verbrauch;

    public Auto( int id, String marke, String modell, String farbe, String motor, String ausstattung, int    anzahlsitze, double verbrauch, String felge, int preis){
        this.id = id;
        this.marke = marke;
        this.modell = modell;
        this.farbe = farbe;
        this.motor = motor;
        this.ausstattung = ausstattung;
        this.anzahlsitze = anzahlsitze;
        this.verbrauch = verbrauch;
        this.felge = felge;
        this.preis = preis;
    }

    @Override
    public String toString(){
        return "Auto Nummer "+id+" ist ein "+marke+" "+modell+" in "+farbe+" mit einem "+motor+" Motor und "+ausstattung+", "+anzahlsitze+" Sitzen, "+felge+" Felgen und einem Verbrauch von durchschnittlich "+verbrauch+". Pries: "+preis;
    }
}


Code:
import java.util.ArrayList;
import java.util.List;

public class Autohaus {
    List<Auto> bestand = new ArrayList<>();

    public int anzahl(){
        return bestand.size();
    }

    public void einparken(Auto neu){
        bestand.add(neu);
    }

    public static void main(String[] args) {
        Autohaus maier = new Autohaus();
        maier.einparken(new Auto(1, "Audi", "RS3", "Perlweiss", "2,5 TFSI", "was halt so geht", 5, 13.1, "OZ Superturismo GT", 34000));
        System.out.println(maier.anzahl());
        System.out.println(maier.bestand.get(0));
    }
}

Mit einparken(..) stellst du ein neues Auto ins Autohaus. Das Autohaus selbst hat eine Liste als Feld bekommen, deren Größe die Anzahl der vorhandenen Autos ist. Ausgeben kannst du die mit anzahl().

Bevor du einparken kannst musst du natürlich das neue Autohaus erzeugen, was ich hier in der main beispielhaft schonmal gemacht habe.

Viele Grüße
 
Zuletzt bearbeitet:
Ok, danke. Ich werde mal schauen, ob ich das verstehe :D
Ergänzung ()

kann man hier anstatt einer liste auch ein normales Feld nehmen ?
 
Die Liste hat den Vorteil, dass du mehrere Autos in sie packen kannst. Ein einfaches Feld würde immer nur für ein Auto stehen. Du bräuchtest also entsprechend viele Felder.
Warum genau möchtest du die Liste loswerden?
 
bei dem feld kann ich ja trotzdem pro feld mit dem datentyp auto einen Datensatz reinpacken, oder ? Wenn ich von Anfang an weiß, dass ich nur 5 autos, sprich 5 felder brauche, könnte ich doch auch ein feld verwenden ? Ich möchte Listen nicht loswerden :D, ich möchte nur wissen ob es mit einem Feld auch möglich ist, bzw. mit Feldern, weil ich das mit listen noch nicht so ganz verstehe :(
 
Um auf deine Frage zu antworten: Ja es ist mit Feldern möglich.
Aaaber! Das ist dann ziemlich unschöner Code und kein bisschen optimal.

Also das mit den Listen funktioniert in deinem Fall so:

Ganz oben als Feld hast du im Autohaus eine Liste hinzugefügt
List<Auto> bestand = new ArrayList();

Vor dem Operator "=" beschreibst du deine Liste.
- List<Auto> bedeutet, dass du eine Liste hast die aus Autos (Objekte der Klasse Auto) besteht.
- bestand ist der Name deiner Liste

Hinter dem Operator erzeugst sie, so wie jedes andere Objekt auch mit new.
Möchtest du jetzt ein Autohaus erzeugen, dann erstellst du ein neues Objekt der Klasse Autohaus. Grundsätzlich sieht das so aus:
Klasse wunschname = new Klasse(Konstruktor);


Also:
Autohaus meinAutohaus = new Autohaus();
Die runden Klammern bleiben hierbei leer, weil du keinen Konstruktor geschrieben hast.

Anders beim Auto:
Auto golf = new Auto(id, marke, modell....);
Hier kommen die ganzen Eigenschaften vom Auto in die runden Klammern.

Jetzt willst du natürlich, dass der Golf auch im Autohaus steht. Objekte kannst du einer Liste immer mit add(..) hinzufügen.
Du hast also das Autohaus meinAutohaus und das Auto golf.

meinAutohaus.add(golf);
Und schon ist dein Auto im Autohaus.
 
Vielen Dank! Jetzt ist mir das mit listen uach relativ klar! Mich würde dennoch interessieren, ob man das ganze auch mit feldern lösen könnte, bzw. Wie das geht, weil ich selbst einfach nicht drauf komme :)
 
Wenn du das ganze mit Felder lösen möchtest, dann wohl so:

Code:
public class Autohaus{
  Auto eins, zwei, drei, vier, fuenf;

  public Autohaus(Auto eins, Auto zwei, Auto drei, Auto vier, Auto fuenf){
    this.eins = eins;
    this.zwei = zwei;
    this.drei = drei;
    this.vier = vier;
    this.fuenf = fuenf;
  }

  public static void main(String[] args){
    // hier erstellst du jetzt erstmal deine neuen Autos wie im letzten Post erklärt
    Auto vw = new Auto(id, ....);
    Auto audi = new Auto(id, .....);
    Auto bmw = new Auto(id, .....);
    Auto opel = new Auto(id, .....);
    Auto ford = new Auto(id, .....);

    // jetzt erstellst du ein Autohaus mit den fünf Autos im Konstruktor
    Autohaus meinAutohaus = new Autohaus(vw, audi, bmw, opel, ford);
  }
}

So sollte das klappen, ist aber wie gesagt unschön und nicht flexibel.
 
Zuletzt bearbeitet:
cpuman990 schrieb:
Vielen Dank! Jetzt ist mir das mit listen uach relativ klar! Mich würde dennoch interessieren, ob man das ganze auch mit feldern lösen könnte, bzw. Wie das geht, weil ich selbst einfach nicht drauf komme :)

Die Lösung mit Feldern wurde ja schon gepostet. Das ganze ist allerdings schlechter Stil, weil es redundant ist und die Erweiterbarkeit des codes einschränkt. Falls dein Autohaus später eine höhere Kapazität haben soll, müsstest du in vier Zeilen etwas ändern. Wenn du möchtest, dass die Kapazität vorgegeben ist solltest du ein array verwenden:
Code:
public class Autohaus {
  private static final int KAPAZITÄT = 5;
  private final Auto[] inventar = new Auto[KAPAZITÄT];

  public Autohaus(Auto[] inventar) {
    assert(inventar.length = KAPAZITÄT);
    System.arraycopy(inventar, 0, this.inventar 0, KAPAZITÄT);
  }

  public Auto[] getInventar() { return inventar; }
}
In diesem Code müsstest du nur eine Zeile, die Kapazität, ändern um weitere Autos speichern zu können.
Ich habe im Code versucht best practices zu beachten, daher sind die Felder private und final (sie können nicht geändert werden, im Falle des Arrays ist daher die Größe fix, nur der Inhalt kann sich ändern). Um das inventar im Konstruktor zu füllen verwende ich eine Systemmethode, das ist lesbarer als eine Schleife zu verwenden.
Außerdem kannst du sehen wie ein getter verwendet wird: weil das Inventar private ist, kann man von außerhalb der Klasse nicht darauf zugreifen. Daher gibt es eine Methode die Zugriff darauf erlaubt. Der Vorteil dieser Methode ist, dass man eine bessere Kontrolle über den Zustand der Klasse hat. Beispielsweise wäre es möglich das array nicht direkt zurückzugeben sondern so zu verpacken, dass es nicht verändert werden kann. Den Code so zu kapseln kann Fehler verhindern, weil man den Bereich einschränkt in dem man einen falschen Zustand basteln kann. Stell dir vor, man würde ein Auto von außen ändern: Über einen setter kann man verhindern, dass beispielsweise der null-Wert verwendet wird und so den Zustand konsistent halten.
Weiterer Tipp: gewöhn dir an code auf englisch zu schreiben. Je früher du damit anfängst desto weniger Probleme bekommst du später. Die ganze Welt programmiert in Englisch.

Ich hoffe ich habe dich nicht zu sehr erschlagen und du kannst was mit den Infos anfangen.
P.S.: Selbst bei einer fixen Kapazität würde ich mit Listen arbeiten. Das die Kapazität nicht überschritten wird kannst du im setter abfangen und du kannst eleganteren Code schreiben wenn es darum geht zB ein nicht ganz gefülltes Autohaus zu haben oder das aktuelle Inventar zu verändern.
 
Zuletzt bearbeitet:
Code:
    assert(inventar.length = KAPAZITÄT);
sollte eher
Code:
    assert(inventar.length == KAPAZITÄT);
heißen.

Außerdem: Ich würde kein Array nehmen. Das einfügen an sich wäre schon zu aufwändig, da ich ja nicht einfach appenden / prependen kann. Ich müsste mir merken, wo das letzte Element gerade ist *oder* bei jedem Einfügen über das Array iterieren, um das erste Vorkommen eines "leeren" Eintrags aus dem Array zu finden (Element null).
 
Danke für die Antworten !
Ergänzung ()

Hallo nochmal,
hier meine jetzigen Quellcodes.
Ich weiß, dass das nicht elegant und kein guter Stil ist.:D

public class Autohaus{

Auto [] pkwgarage;
int anzahl;
int i;

public Autohaus(int maxAnzahlAutos){
anzahl = maxAnzahlAutos;
i = 0;
}

public void autoeintragen (int ID, String Marke, String Modell, String Farbe, String Motor, String Ausstattung, int Anzahlsitze, int Verbrauch, String Felge, int Preis ){

pkwgarage = new Auto [anzahl];

pkwgarage=new Auto(ID, Marke, Modell, Farbe, Motor, Ausstattung,Anzahlsitze, Verbrauch, Felge, Preis);
if (i < anzahl-1){
i = i+1;}else{
System.out.println (" Das Autohaus ist voll");
}

}




}
public class Auto {
int id;
String marke;
String modell;
String farbe;
String motor;
String ausstattung;
int anzahlsitze;
int verbrauch;
String felge;
int preis;

public Auto( int ID, String Marke, String Modell, String Farbe, String Motor, String Ausstattung, int Anzahlsitze, int Verbrauch, String Felge, int Preis ){
marke = Marke;
id = ID;
modell= Modell;
farbe = Farbe;
motor = Motor;
ausstattung = Ausstattung;
anzahlsitze = Anzahlsitze;
verbrauch = Verbrauch;
felge = Felge;
preis = Preis;


}

}
public class Kunde {

public Kunde(){


}
public void angebotAusgeben(){




}




}
In der Klasse Autohaus können mit der Methode autoeintragen autos in ein feld abgespeichert werden. Meine Frage wäre jetzt, wenn ich mit dieser Methode in Bluej mehrere Felder mit Daten fülle, ob es möglich ist in die Klasse Kunde eine Methode zu schreiben, bei deren Aufruf man die werte eines Feldes erhält, als System.out.println, sprich dass dann hier z.b. Steht : Marke: ; Motor ; etc. und dann immer die eingetragenen werte ausgegeben werden ?
 
Zurück
Oben