Zunächst: Das ist OO. Grundsätzlich erstmal weg von der Idee mit Schleifen und Arrays und goto und was weiß ich. OO ist die Realität (in diesem Sinn).
Wenn Du PKWs hast, dann wäre an der Stelle ein vergleichsweise einfacher Ansatz:
- Klasse PKW erstellen:
- Klasse "Hersteller" ableiten:
- Überlegen, was für Eigenschaften PKWs haben (und alle Hersteller damit auch). Diese Eigenschaften kommen in den "PKW".
- Überlegen ob (falls) es weitere Eigenschaften gibt, die nur die Hersteller selber haben. Falls ja, kommen die in die abgeleiteten Klassen.
- Konstruktor basteln:
. Hier drin wird Code angelegt (und ausgeführt) welcher das neue "Objekt" anlegt. Sprich,
erstellt ein neues Fahrzeug aus dem großen Pool der Audis - also mußt Du dem Konstruktor noch paar Infos mitgeben, damit sich Audi1 von Audi2 unterscheidet.
Wie Du das machst ist erstmal Deine Sache. Der saubere Weg sind Klassen für jedes Fahrzeugmodell - class A1 : Audi --- aber Du kannst genausogut auch einfach eine Eigenschaft Modell in der Klasse Audi haben und Du kannst sogar ganz flach rangehen und NUR class PKW haben und dort dann Eigenschaften Marke und Modell verwenden. Nicht schön, aber geht.
- Jetzt hast Du einen Haufen von Fahrzeugen (bzw erstmal die Möglichkeit, diesen anzulegen).
- Als nächstes hast Du für eine Anwendung eine statische Main() Methode mit oder ohne Übergabeparameter. Die wird mit Programmstart ausgeführt, aber man sollte sie halt sauber halten.
- Deshalb baust Du idealerweise eine zusätzliche statische Klasse (hinweis, die sind gerne verpönt, aber nur von Leuten ohne Ahnung von OO) welche die Methode(n) enthält, die vom ganzen Rest unabhängig sind. Zum Beispiel
C#:
static List<PKW> RandomizePKW(uint anzahl)
. Was Du übergibst bleibt Dir überlassen, aber die Methode muß zumindest erfahren, was sie braucht und nicht selber beschaffen kann.
Option A: Generics und eine Signatur wie
C#:
static List<TInput> RandomizePKW<TInput>(uint Anzahl) where TInput: PKW
Vorteil: Ermöglicht es, den generischen Typen TInput in der Methode zu verwenden als Platzhalter für alles, was der Benutzer später mal angibt. Der sagt dann
C#:
List<PKW> meinePKWs = RandomizePKW<Audi>(5)
Nachteil: Generika sind sehr abstrakt, sie stehen der Klassenhierarchie diametrisch gegenüber, man muß ggfs um die Ecke denken, und wenn es was zu konvertieren oder zu instantiieren gibt, dann wird es interessant. Für den Neuling nur bedingt empfehlenswert.
Option B: Enums und eine Signatur wie
C#:
static List<PKW> RandomizePKW(Fahrzeugtyp typ, uint anzahl) {}
.
Dann
C#:
public enum Fahrzeugtyp {}
deklarieren und da drin die möglichen Fahrzeugtypen einfach auflisten.
Vorteil: Einfach.
Nachteil: Man braucht eine Switch-Anweisung, um alle möglichen Felder des enum typ auf die tatsächliche Klasse abzubilden. Das gibt ordentlich Codezeilen. Andererseits kann man enums zu int konvertieren... das ist an der Stelle vermutlich für die Randomisierung gar nicht mal so schlecht.
Da es einen fixen Pool gibt an Fahrzeugen, kann man auch einen fixen Pool an Fahrzeugen in die Anwendung aufnehmen. Das kann ein Array oder ein Dictionary oder auch eine List sein - auch wieder statisch.
Wenn man dann "anzahl" oft sowas wie Math.Random() aufruft, dann kann man über den erhaltenen Index notfalls mit ein bißchen Transformation einfach eines der Fahrzeuge aus diesem statischen Pool greifen und zurückgeben.
Beispiel: public Audi hat die Signatur (string name, uint Türen) sodaß man 2,3,4 und 5-Türer Varianten eines Modells erstellen kann.
Dann wäre ein statischer Pool sowas wie
C#:
static List<PKW> = new List<PKW>()
{ new Audi("A3", 3), new Audi("A3", 5 }
hier also ein Pool aus zwei Fahrzeugen, nämlich einem drei- und einem fünftürigen Audi A3.
Hinweise: statische Methoden werden mit Klassenname aufgerufen, wenn also eine statische Klasse da ist
C#:
static class PKWsAndStuff
{
static List<PKW> RandomizePKW(Fahrzeugtyp typ, uint anzahl)
{
// Implementierung
}
}
dann ruft man das mit
C#:
PKWsAndStuff.RandomizePKW(Fahrzeugtyp.Audi, 5)
auf.