kostenloser Webspace werbefrei: lima-city


C# Zugriff auf vererbte Klassen

lima-cityForumProgrammiersprachenProgrammieren mit .NET & Mono

  1. Autor dieses Themas

    h******g

    Hallo,
    ich hätte eine grundsätzliche Frage zu C#.
    Ich habe eine abstrakte Klasse "Flugzeug". Die Klassen "Airliner" und "Carrier" erben von dieser. Jetzt soll ich in einer weiteren Klasse "Company" eine Methode "addAeroplane()" schreiben, welche zur entsprechenden Firma ein weiteres Flugzeug hinzufügt.
    Mein Problem: Ich weiß ja nicht, ob es sich jetzt um eine Instanz von Airliner oder von Carrier handelt, die ich hinzufügen soll. Ich könnte natürlich einen String auswerten und mittels Switch entscheiden, ob ein Objekt Airliner oder Carrier erstellt wird, aber gibt es dafür nicht vielleicht eine elegantere Methode?
    Danke schon mal für jede Hilfe
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Google:
    http://stackoverflow.com/questions/3561202/check-if-instance-of-a-type


    Edit: Verstehe... In diesem Fall würde ich mich mit Generics auseinander setzen. Eine Alternative wäre nach wie vor natürlich auch ein flag, string, enum oder sonstigen Identifier zu übergeben.

    Beitrag zuletzt geändert: 19.11.2013 13:42:18 von adrians
  4. Autor dieses Themas

    h******g

    Die Objekte existieren noch nicht, ich soll sie ja erzeugen. Dazu muss ich aber wissen, welchen Konstruktor ich aufrufen soll, den von "Airliner" oder den von "Carrier".
    Ich müsste also einen Verweis auf die Klasse übergeben, von welchem Typ das zu erzeugende Objekt ist.
    Versucht habe ich es schon mit dem Type-Schlüsselwort, aber damit kriege ich ja nur den Klassentyp übergeben. Das ist einerseits wieder unschön beim Methodenaufruf, andererseits weiß ich nicht, wie man mittels Typ wieder die eigentliche Klasse ansprechen kann:
    // MAIN:
    myAir.addAeroplane("A1080-c", 3, 250, 350, 1250, typeof(Airliner));
    
    // aus Klasse Company
    public void addAeroplane(string flightNumber, int crew, double speed, int capacity_passengers, double incomePerTon_Passenger, Type type)
    {
      Array.Resize(ref this.planes, this.planes.Length + 1);
      this.planes[this.planes.Length - 1] = new Carrier(flightNumber, crew, speed, capacity, incomePerTon);
      //bzw. this.planes[this.planes.Length - 1] = new Airliner(flightNumber, crew, speed, passengers, incomePerPassenger);
     }


    Eine schöne Lösung wäre natürlich einfach die Methode zu überladen, aber da die Parameter von Anzahl und Typ her gleich sind, funktioniert das nicht.
  5. Wenn ich das richtig verstehe, dann ist addAeroplane() ja nur eine Factory, die eben ein Objekt erzeugt anhand der übergebenen Daten - logisch :blah:

    So musst du ja an letzter Stelle eine Möglichkeit finden, deine Flugzeuge auseinander zu halten, wieso also nicht per String wie du es selbst gesagt hattest? - Weiß nun nicht wie es bei C# ist, aber bei PHP könnte man dann direkt den übergebenen Stringname als Klassenname verwenden:
    // PHP
    public function factory($className)
    {
    return new $className();
    }

    , das kann manchmal sehr praktisch sein (natürlich brauch man an der Stelle entsprechende Fehlerbehandlung).
  6. Hallo,

    Factory-Pattern hätte ich jetzt auch vorgeschlagen
    http://www.dotnetperls.com/factory

    Hier eine kleine Demo-Version:
    class Program
        {
            static void Main(string[] args)
            {
    
                Flugzeug flugzeug = Factory.GetInstance(typeof(Airliner));
                Flugzeug flugzeug2 = Factory.GetInstance(Factory.FlugzeugEnum.Carrier);
    
            }
        }
    
        abstract class Flugzeug
        { }
    
        class Airliner : Flugzeug
        {
        }
    
        class Carrier : Flugzeug
        { }
    
        static class Factory
        {
            public static Flugzeug GetInstance(FlugzeugEnum type)  
            {
                Flugzeug flugzeug;
                
                if (type == FlugzeugEnum.Airliner)
                {
                    flugzeug = new Airliner();
                }
                else if (type == FlugzeugEnum.Carrier)
                {
                    flugzeug = new Carrier();
                }
    
                return flugzeug;
            }
    
            public enum FlugzeugEnum
            {
                Airliner,
                Carrier
            }
    
            public static Flugzeug GetInstance(Type type)
            {
                [del]return Activator.CreateInstance(type) as Flugzeug;[/del]
    	    [b]EDIT:[/b]
                if (typeof(Flugzeug).IsAssignableFrom(type))
                {
                    return Activator.CreateInstance(type) as Flugzeug;
                }
                else
                {
                    return null;
                }
            }
        }


    In dieser Demo gibt es zwei Funktionen um eine neue Instanz von den verebten Klassen zu erzeugen.
    Bei der zweiten Funktion mit dem Type muss man selber noch drauf achten, dass man auch nur eine Type übergibt der auch wirklich als Flugzeug gecastet werden kann.
    EDIT: Bei der zweiten Funktion muss man drauf achten, dass man prüft, ob ein null zurück gekommen ist.
    Bei der ersten mit dem Enum gibt es nur diese beiden Fälle, da man den Enum zum Steuern hat, wenn man diesen erweitert muss man auch die Funktion anpassen.

    Eine Factory ist dafür da, damit man in dieser Funktion bereits weitere Einstellungen (Eigenschaften) setzen kann, die nur in der verebten Klasse sind.
    Wenn beide / alle verebten Klassen die selben Eigentschaften (Properties) besitzen, sollte man überlegen, ob man diese nicht eine Ebene (in die Elternklasse) hochzieht.

    Gruß
    Trancedrome

    Beitrag zuletzt geändert: 20.11.2013 11:45:15 von trancedrome
  7. Autor dieses Themas

    h******g

    Am einfachsten wäre es wohl gewesen, die Flugnummer auszuwerten. Der letzte Buchstabe ist nämlich ein "a" oder "c".
    Mit String.EndsWith() also schnell lösbar.
    Ich habe mich aber nochmal informiert (das Ganze ist eine Vorlage für eine Praxisüberprüfung): addAeroplane() soll nur ein bereits bestehendes Flugzeug zum Array hinzufügen. Damit erübrigt sich mein Problem natürlich:
    addAeroplane(new Airliner());
    addAeroplane(new Carrier())

    Danke für die Antworten.

    Beitrag zuletzt geändert: 21.11.2013 22:08:47 von hm4-blog
  8. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!