Announcement

Collapse
No announcement yet.

Vererbung: Wie ruft man den Konstruktor der Basis-Klasse auf?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Vererbung: Wie ruft man den Konstruktor der Basis-Klasse auf?

    Ich steige gerade von VB.NET auf C# um und komme bei einer Mehrfachvererbung nicht weiter. Wie kann ich in einer abgeleiteten Klasse den Konstruktor der Basis-Klasse aufrufen? Der parameterlose Aufruf ist ja automatisch vorhanden so wie ich das verstehe aber wie arbeite ich mit Parametern?

    Hier mein Code:

    [highlight=c#]
    abstract class BaseReport: TreeNode
    {
    public int Id { get; protected set; }
    }

    class ChartReport: BaseReport
    {
    public ChartReport(int id, string name, int img)
    {
    //this = new TreeNode(name, img, img);
    this.Id = id;
    }
    }
    [/highlight]

    Im VB.NET würde ich an der entsprechenden Stelle dies schreiben:

    [highlight=vb.net]
    MyBase.New(name, img, img)
    [/highlight]

    Gruss

  • #2
    Aus einem Konstruktor kannst du nur Konstruktoren des direkten Vorfahren oder der andere Konstruktoren der eigenen Klasse aufrufen.

    [HIGHLIGHT=C#]class ChartReport: BaseReport
    {
    public ChartReport(int id, string name, int img) : base() // Paramterloser Konstruktor von BaseReport
    {
    .....[/HIGHLIGHT]
    oder
    [HIGHLIGHT=C#]class ChartReport: BaseReport
    {
    public ChartReport(int id, string name, int img) : this() // Paramterloser Konstruktor von ChartReport
    {
    .....[/HIGHLIGHT]


    //this = new TreeNode(name, img, img);
    Das ist auf mehreren Ebenen nicht so gedacht

    a.) this ist an der Stelle vom Typ ChartReport. Ein TreeNode ist kein Chartreport. Die Vererbungshierarchie ist andersherum
    b.) this kann man nur in einen Wertetyp (struct) was zuweisen. this ist in einer Klasse fix.


    MyBase.New(name, img, img)
    Bist du dir sicher das das gehen würde? Ich habe Vorstellungsprobleme damit das im .Net Framework eine Ebene der Vererbungshierarchie überspringen darf. Also das man hier in ChartReport direkt einen Konstruktor von TreeNode aufrufen dürfte ohne das einer von BaseReport beteiligt ist. Ich hätte auch gedacht das sich MyBase in ChartReport immer auf BaseReport bezieht und BaseReport hat keinen passenden Konstruktor den du da zeigst. Wenn VB das kann woher weiß VB welcher Vorfahre mit MyBase gemeint ist? In C# ist es auf jeden Fall so das Konstruktoren nicht vererbt werden wenn du in Chartreport den von TreeNode aufrufen willst mußt du den auch in BaseReport einführen und eventuelle Parameter durchreichen.

    Edit: Verweis auf die Hilfe von base

    Comment


    • #3
      Ich verstehe, dass ich beim Konstruktor nicht eine Ebene überspringen kann (ist im VB.NET auch so). Wenn ich im BaseReport einen Konstruktor schreibe geht es:

      [HIGHLIGHT=c#]

      abstract class BaseReport: TreeNode
      {
      public BaseReport(int id, string name, int img) : base(name, img, img) { }
      public int Id { get; protected set; }
      }

      class ChartReport: BaseReport
      {
      public ChartReport(int id, string name, int img)
      {
      public ChartReport(int id, string name, int img) : base(id, name, img)
      this.Id = id;
      }
      }

      [/HIGHLIGHT]

      Kann/muss der Konstruktor im BaseReport "abstract" oder "virtual" sein?

      Gruss

      Comment


      • #4
        Hallo,

        Kann/muss der Konstruktor im BaseReport "abstract" oder "virtual" sein?
        Weder noch - aber probiers einfach aus und schau was der Compiler sagt ;-)

        Die Zugriffsmodifizierer (public, internal, protected) müssen passen, sonst meckert der Compiler auch...

        mfG Gü
        "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

        Comment


        • #5
          Kann/muss der Konstruktor im BaseReport "abstract" oder "virtual" sein?
          Nein. Ich finde es aber etwas merkwürdig die Klasse selbst schon abstract zu markieren. Zumindest sehe ich nichts abstraktes und der Vorfahr ist ja auch nicht abstrakt. Wenn du nicht möchtest das man BaseReport instanziiert sondern nur dessen Nachfahren mach den Konstruktor einfach protected.

          Comment


          • #6
            Oder über "Composition over Inheritance" nachdenken

            Comment


            • #7
              Da wird man sich bei einer vorhandenen geschlossenen Klasse schwer tun. Insbesondere bei etwas wie TreeNode wo das drum herum schon so ausgelegt ist das man bestimmte Dinge per Inheritance lösen sollte

              Comment


              • #8
                parameterlose standard konstruktor

                @winfried,

                der paramterlose standard constructor existiert zwar per se, wird aber ein construktor mit paramter eingefügt, dann gibt es ihn nicht mehr, man merkt das erst wenn man ableitet.
                Ein paramterloser construktor muss dann explicit implementiert werden.

                Code:
                 abstract class BaseReport : TreeNode
                    {
                        public BaseReport() {}
                
                        public BaseReport(int id, string name, int img)
                        { }
                        //base(name, img, img) { }
                
                        public int Id { get; protected set; }
                    }
                JonDonym: privacy needs anonymity more than ever

                Comment

                Working...
                X