Abgeleitete Klassen von Klassen ableiten



  • Hallo,

    ich habe ein kleines Problem damit eine Programmverbesserung vorzunehmen mit abgeleiteten Klassen.

    Ich möchte eine comboBox haben mit x Tierarten. Für das Beispiel hier erstmal 2.
    Tierart 1 = Bird
    Tierart 2 = Fish

    abstract class Bird
    {
        public int speed;
        public int dexterity;
    
        public virtual void values()
        {
            speed = 60;
            dexteritiy = 20;
        }
    }
    
    abstract class Fish
    {
        public int speed;
        public int dexterity;
    
        public virtual void Values()
        {
            speed = 20;
            dexteritiy = 60;
        }
    }
    

    Eine zweite ComboBox wird nach Wahl der Tierart entsprechend mit Rassen gefühlt, z.B. wenn comboBoxSpecies Fisch ist, dann sind die Items der comboBoxTribe:
    Tribe 1 = Hecht
    Tribe 2 = Barsch
    Tribe 3 = Scholle

    Eine abgeleitete Klasse sieht z.B. so aus:

    class Hecht : Fish
    {
        public Hecht ()
        {
        }
    
        public override void Values()
        {
            speed = 19;
            dexteritiy = 59;
        }
    }
    

    Wenn ich jetzt diese Werte in Textboxen füllen möchte nachdem die comboBoxes gefüllt wurden, dann muss ich ja ne Fallunterscheidung machen:

    if (comboBoxSpecies.Text == Hecht)
    {
        Hecht hecht = new Hecht();
        hecht.Values();
    
        //Textboxen werden mit Werten gefüllt:
        tbSpeed.Text = hecht.speed.ToString();
        tbDexterity = hecht.dexterity.ToString();
    }
    

    Da ich bei unfassbar vielen Rassen etc. nicht immer Zeile 7 und 8 haben möchte aus dem letzt Code, habe ich mir eine Hilfsklasse Individuum gemacht, wodurch der Text nun wiefolgt wird:

    Individuum ind = new Individuum();
    if (comboBoxSpecies.Text == Hecht)
    {
        Hecht hecht = new Hecht();
        ind = hecht;
        hecht.Values();
    
        //Textboxen werden mit Werten gefüllt:
        tbSpeed.Text = ind.speed.ToString();
        tbDexterity = ind.dexterity.ToString();
    }
    

    Nun ist es aber so, dass ich das Individuum auf Abstrakt habe, weil ich es eigentlich ja garnicht ableiten will und selbst wann, weiß ich nicht, wie ich von der abgeleiteten Klasse ableiten soll, geht es auch einfacher mein Vorhaben hinzubekommen oder habt ihr einen Tip?



  • Vielleciht kannst du mal mit Reflection versuchen?

    Außerdem reicht es Individuum ind zu schreiben anstatt Individuum ind = new Individuum(); da es immer überschrieben wird.

    boenz666 schrieb:

    Da ich bei unfassbar vielen Rassen etc. nicht immer Zeile 7 und 8 haben möchte aus dem letzt Code, habe ich mir eine Hilfsklasse Individuum gemacht, wodurch der Text nun wiefolgt wird:

    Individuum ind = new Individuum();
    if (comboBoxSpecies.Text == Hecht)
    {
        Hecht hecht = new Hecht();
        ind = hecht;
        hecht.Values();
    
        //Textboxen werden mit Werten gefüllt:
        tbSpeed.Text = ind.speed.ToString();
        tbDexterity = ind.dexterity.ToString();
    }
    

    Nun ist es aber so, dass ich das Individuum auf Abstrakt habe, weil ich es eigentlich ja garnicht ableiten will und selbst wann, weiß ich nicht, wie ich von der abgeleiteten Klasse ableiten soll, geht es auch einfacher mein Vorhaben hinzubekommen oder habt ihr einen Tip?



  • Statt Hecht von Fish abzuleiten, soltest du lieber Fish und Bird von der abstracten Klasse 'Animal' ableiten.

    Edit:
    Und dann die Fischarten z.B. in eine HashMap packen.



  • Es gibt bisher noch garkeinen Grund für Vererbung in dem Beispiel.

    Mit genau sowas wird Vererbung überstrapaziert und auf alltagssprachliches "is-a" reduziert.



  • Rhombicosidodecahedron schrieb:

    Vielleciht kannst du mal mit Reflection versuchen?

    Außerdem reicht es Individuum ind zu schreiben anstatt Individuum ind = new Individuum(); da es immer überschrieben wird.

    Ok, da lese ich mich mal rein Danke... auch für den Tip

    @Jockelx:
    Das probiere ich gerade Mal, danke auch dir

    @dafuq_did_i_read: Deswegen habe ich ja um Hilfe gebeten, aber das Programm ist natürlich wesentlich umfangreicher und erfordert für spätere Aktionen schon die Vererbung 😉



  • boenz666 schrieb:

    Rhombicosidodecahedron schrieb:

    Vielleciht kannst du mal mit Reflection versuchen?

    Außerdem reicht es Individuum ind zu schreiben anstatt Individuum ind = new Individuum(); da es immer überschrieben wird.

    Ok, da lese ich mich mal rein Danke... auch für den Tip

    @Jockelx:
    Das probiere ich gerade Mal, danke auch dir

    @dafuq_did_i_read: Deswegen habe ich ja um Hilfe gebeten, aber das Programm ist natürlich wesentlich umfangreicher und erfordert für spätere Aktionen schon die Vererbung 😉

    Wie es aber aussieht hast du die den Grundgedanken von Vererbung nicht verstanden. Wenn du naemlich irgendwo so eine Fallunterscheidung vornehmen musst, hast du ein Problem mit deinem Design.



  • boenz666 schrieb:

    @dafuq_did_i_read: Deswegen habe ich ja um Hilfe gebeten, aber das Programm ist natürlich wesentlich umfangreicher und erfordert für spätere Aktionen schon die Vererbung 😉

    Sorry aber Dein Code ist extrem anfängerhaft und ich glaube Du kannst das garnicht einschätzen. Das ist nicht böse gemeint. Aber gerade Anfänger verwenden zu oft Vererbung wobei andere Vorgehensweise besseren Code liefern würden.



  • boenz666 schrieb:

    ...

    Da ich unterbrochen wurde, sind garantiert etliche Anmerkungen hinzugekommen, vielleicht aber dennoch passend:

    Für mich sieht dein gesamter Code nach "Overengineering" aus, zumindest wenn deine Klassen inhaltlich eigentlich identisch sind, und sich nur im Typ und in der Initialisierung unterscheiden. Für mich "riecht" dies nach potentiellen Missverständnissen in der Objektorientierung, nämlich den Verwechseln zwischen Klassen und Instanzen/Objekten, und zudem den Aufbau einer unnötig komplexen Hierarchie.

    Des weiteren verstehe ich nicht den Sinn deiner values-Methode (die noch dazu unterschiedlich benannt ist), da die eigentlich nichts anderes macht, als man vom Konstruktor erwartet (Initialisierung).

    Wenn deine Anforderungen wirklich so niedrig bleiben würde ich eher eine Klasse Tier anbieten, die nur ein Kriterium für die konkrete Art enthält (z.B. ein enum).



  • OK, dann scheint mein Know-How dementsprechend falsch zu sein und ich muss das mit dem Ableiten fallen lassen und es anders ausprobieren, aber ich bin jetzt total verwirrt.

    Was ich vor hattee:
    Ich möchte ca. 5 Klassen species haben:
    - Fish
    - Bird
    - Insect
    ...

    Je nachdem welche Klasse ich wähle, muss die comboBoxRasse andere Werte bieten, da ich ja nicht Hecht zur Option haben darf, wenn Bird selektiert ist. Die Anzahl dieser Werte liegt jeweils bei 20.
    Dann gibt es noch eine comboBox, die items beinhalten soll, abhängig von der Art des Tieres und zwar nur spezielle Tiere: (z.B. falls giftig Giftstachel)

    Nun gebe ich folgendes ein in die Boxen:

    comboBoxSpecies = Insect
    comboBoxTribe = Skorpion
    comboBoxSpecial = Betäubungsgift, Tödliches Gift
    //Letzters wählt der Benutzer dieses Programmes

    In dem Programm frage ich unzählige Male an verschiedenen Stellen, um welches Objekt es sich handelt, weil dann das eine oder das andere Ereignis passiert und damit ich nicht an jeder Stelle 5*20 Abfragen habe und wenn ich später nur allgemeine Abfragen machen möchte, ob das Tier z.B der Spezies Fish angehört, dachte ich, dass ich das über Vererbung mache, was wohl falsch war.

    Ist es dann doch besser nur eine Klasse zu machen und in der bereits alles abzufragen?
    Habe in einem Tutorial abgeleitete Klassen gehabt und das hatte einfach ne Menge Arbeit erspart und nur darum geht es mir, dass ich zum Beispiel später, wenn ich der Spinne lieber speed 12 geben möchte, dass ich dann nur in der Klasse Spinne was ändern muss. Weil es kommen ca. 40 Eigenschaften pro Tier und es wird ja unübersichtlich, wenn ich in der Klasse Animal dann 40*20*5 Eigenschaften habe = 400 oder ist es nunmal einfach besser?



  • Vorweg und nur so nebenbei:
    Ein Skorpion ist kein Insekt.

    boenz666 schrieb:

    Ist es dann doch besser nur eine Klasse zu machen und in der bereits alles abzufragen?

    Ja, wobei ich nicht weiß, was du mit alles abfragen meinst.

    boenz666 schrieb:

    Habe in einem Tutorial abgeleitete Klassen gehabt und das hatte einfach ne Menge Arbeit erspart und nur darum geht es mir, dass ich zum Beispiel später, wenn ich der Spinne lieber speed 12 geben möchte, dass ich dann nur in der Klasse Spinne was ändern muss.

    Das ist aber alles kein Problem, wenn du das z.B. grob so machst:

    class Animal
    {
        private enum ETyp typ;  // Hecht, Scorpion & co
        private enum ESpizies spezies;  
        private int speed;
        private int dexterity;
        private enum ESpezial spezial;
    
        private Animal(ETyp typ,...) {...}
        public Animal createHecht() {
            return new Animal(ETyp.Hecht, ESpezies.Fish, 11, 34, ESpezial.None);
        }
    }
    

    Jetzt hast du deine Viecher ja wohl in irgendeinem vector oder sowas gespeichert und musst du dir dann nur Methoden schreiben, die die passenden Tiere zu einer Spezies raussucht.

    So in etwa würde ich das machen.

    Edit:
    Member private gemacht



  • boenz666 schrieb:

    OK, dann scheint mein Know-How dementsprechend falsch zu sein...

    oder deine Informationen und Fragen. Ich werde aus den dir gegebenen Informationen nicht ganz schlau, vielleicht beschreibst du mal aus Sicht eines Anwenders, was man eingeben oder sehen kann.

    boenz666 schrieb:

    wenn ich in der Klasse Animal dann 40*20*5 Eigenschaften habe = 400 oder ist es nunmal einfach besser?

    Ich glaube einfach das du viel zu kompliziert denkst...



  • Was willst du eigentlich ganz konkret erreichen? Du hast also irgendwelche Arten mit Werten, dazu irgendwelche "Items" (Der Begriff erinnert mich an Rollenspiel), und was ist Bestandteil der Items?

    Die bisherigen Codeschnipsel deuten, wie schon erwähnt darauf das du Klassen mit Instanzen verwechselst. Eine Klasse ist nur eine Schablone, die in der Regel keine eigenen Werte besitzt (wenn man mal von statischen Variablen absieht), erst eine konkrete Instanz hat Werte.

    Mit Ausnahme der tröpfchenweisen Zusatzinformationen deutete alles anfangs darauf hin das, das du eigentlich nur eine Klasse mit einer Hand voll Variablen bräuchtest, von denen du dann konkrete Instanzen (Hecht, Skorpion...) zur Laufzeit anlegst.

    Ich befürchte jetzt aber das du für jeden Wert zu Laufzeit meinst, immer eine eigene Membervariable anzulegen. Dann frage ich mich aber wie du jemals das Programm fertig bekommen willst. Vielleicht solltest du wirklich einmal überlegen was du benötigst, ohne dir Gedanken über eine Umsetzung zu machen. Oder wenn nur über das, was der Anwender sehen soll.

    Wie werden z.B. die "Items" beschrieben. Wenn diese wiederum gleich aufgebaut sind, ist hier eine weitere Klasse sinnvoll (Wenn man z.B. Items im Sinne von einen Rollenspiel, auch gerne als "Loot" bezeichnet denkt, bestehen diese eigentlich vereinfacht gesprochen immer aus einen Verkaufspreis, einem Gewicht und einer Beschreibung [Was darauf hindeutet das man Gemeinsamkeiten hat, die man in eine "Schablone", sprich als eine Klasse umsetzt, nicht als eine Klasse pro möglichen Objekt]).


Anmelden zum Antworten