Mit Enums allgemeine Typen festlegen

hamena

Grünschnabel
Howdy!
Ich habe 3 Klassen:
Vehicle, Bike und Car. Bike und Car sind jeweils von Vehicle abgeleitet. Jetzt möchte ich in Bike und Car jeweils den Typ festlegen (Tandem, Rennrad, ... für Fahrrad --- Kleinwagen, Mittelklasse, ... für Auto) und habe dazu zunächst in Bike und Car je ein Enum geschrieben.

Jetzt will ich eine Methode nutzen, die per Zufall festlegt, welcher Typ das Bike bzw. Car sein soll, die ich typGenerieren() nenne.
Da ich aber für jede Klasse ein eigenes Enum habe, muss ich auch für jede Klasse die Methode quasi neu schreiben. Ich versuche jetzt also, in Vehicle die Methode unterzubringen und so zu verallgemeinern, dass ich in Bike und Car diese aufrufen kann:
Code:
public class Bike extends Vehicle{

public Bike(){
     typGenerieren([ENUM Fahrradtyp]);
}
(ebenso Klasse Car)
-------------------------------------------
public class Vehicle{

     public enum BikeType{
          RENNRAD, TANDEM,...;
     }

     public enum CarType{
          KLEINWAGEN, MITTELKLASSE, ...;
     }

     public [ENUM] typGenerieren([ENUM] enumwert){
          int zufall;
          zufall = (int)(Math.random * 3) + 1);
          if (zufall == 1){
               xxx

Jetzt weiss ich also nicht, wie ich das Enum so allgemein gestalten kann, dass ich damit eine einzige Methode schreibe. Denn wenn ich die Methode für jede Klasse neu schreibe und in Vehicle belasse, habe ich keinen Code gespart, sondern nur die Methode zentralisiert.
Wer weiss Rat? :confused:

HAVE PHUN!
 
Hallo,

schau mal hier:
Java:
/**
 * 
 */
package de.tutorials;

/**
 * @author Thomas.Darimont
 * 
 */
public class RandomEnumValueSelection {

    enum VehicleType {
        CAR, BIKECYCLE, MOTOCYCLE, AIRPLANE, SHIP
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        int[] occurenceCount = new int[VehicleType.values().length];
        int loops = 10000;

        for (int i = 0; i < loops; i++) {
            VehicleType vehicleType = getRandomEnumValue(VehicleType.class);
            occurenceCount[vehicleType.ordinal()]++;
        }

        int sum = 0;
        for (int i = 0; i < occurenceCount.length; i++) {
            System.out.println(VehicleType.values()[i] + ": "
                    + occurenceCount[i]);
            sum += occurenceCount[i];
        }

        System.out.println(sum); // should be equal to loops
    }

    final static String valuesMethodName = "values";

    private static <TargetEnumType> TargetEnumType getRandomEnumValue(
            Class<TargetEnumType> enumClass) {
        if (!enumClass.isEnum()) {
            throw new IllegalArgumentException(
                    "Only enum classes allowed as parameter... given parameter is of type: "
                            + enumClass);
        }

        try {
            Object[] enumValues = ((Object[]) enumClass.getDeclaredMethod(
                    valuesMethodName).invoke(null));
            Object enumValue = enumValues[(int) (Math.random() * enumValues.length)];
            return enumClass.cast(enumValue);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}


Ausgabe:
Code:
CAR: 2067
BIKECYCLE: 2052
MOTOCYCLE: 1915
AIRPLANE: 1988
SHIP: 1978
10000

Gruß Tom
 
Hi Thomas.
Erstmal vielen Dank für deine Antwort.
Ich habe mich jetzt längere Zeit mit deinem Code befasst und muss leider gestehen, dass ich damit so rein garnichts anfangen kann.
Du scheinst auch Generics zu verwenden, ich bin jedoch eher auf eine allgemeine Antwort aus, ob das Problem mit den Enums generell lösbar ist.
Man bräuchte also quasi eine Möglichkeit, in eine Methode einen beliebigen Enum-Typ zu stecken. Soweit ich Generics verstehe, scheinst du das hier auch zu tun, aber ich kann's leider nicht nachvollziehen. :confused:
Gibt es vielleicht noch eine allgemeinere Lösung?

Besten Dank im vorraus!

HAVE PHUN!
 
Hallo,

das ist die allgemeine Lösung ;-) Zu dem Problem:
"Einen zufälligen Wert aus einem angebenen Enum-Typ auswählen und zurückgeben".

Gruß Tom
 
Ah, jetzt verstehe ich! :D
Ich möchte nicht einen zufälligen Wert aus einem Enum auswählen und ausgeben, sondern ursprünglich wollte ich Code sparen:
Ich muss für jede Klasse ein Enum mit den Enumwerten festlegen und in jeder Klasse eine Methode schreiben, die dem Objekt dann einen Enumwert zuweist.
Weil ich (in dem Beispiel) 3 Klassen hatte, musste ich auch die Methode "typGenerieren()" 3 mal neu schreiben, obwohl im Grunde genommen nur die Enum-Werte anders sind, denn ein Enum
"public enum Tag{Mo, Di, ...}" aus der Klasse A ist nicht kompatibel zu
"public enum Tag{Mo, Di, ...}" aus der Klasse B.
Daher kann ich nicht einfach die Methode in die Basisklasse auslagern und da die Enumwerte der anderen Klassen nutzen, sondern muss halt 3 mal die quasi gleiche Methode schreiben.
Das ist mein Problem, sorry wenn ich mich undeutlich ausgedrückt haben sollte, aber das Problem lässt sich blöd erklären. ;D

HAVE PHUN!
 
Zurück