none
Innere Klassen RRS feed

  • Frage

  • Hallo Liebe Community, (es wird ein wenig lang, ich hoffe dennoch hier antworten zu finden ... zumindest partiell)

    ich möchte eine Innere Klasse verwenden, also nach dem Muster:

    Public Class OuterClass
        Private InnerClass
            Protected Friend Sub StartWork()
            End Sub
        End Class
    
        Public ReadOnly Property Value() As Object
            Get
                Return New Object()
            End Get
        End Property
    
        Public ReadOnly Property EasyMeAccess() As OuterClass
            Get
                Return Me
            End Get
        End Property
    
        Private Sub DoSomething()
            Dim icTmp As New InnerClass
    
            icTemp.StartWork()
        End Sub
    End Class
    
    


    aber der Zugriff der Klassen untereinander ist mir nicht ganz klar. In Java kann ich von der Inneren Klasse auf die Eigenschaften der Äußeren zugreifen, z.B.:

    private class InnerClass
    {
        public void StartPublicWork()
        {
            TestGeneralJava_2.this.strMySecret = "Not a Secret to my InnerClass";
        }
    
        private void StartPrivateWork()
        {
            // Do nothing.
        }
    }
    
    private String strMySecret;
    
    public JPanel testInnerClass()
    {
        strMySecret = "Very secretive";
    
        JPanel resultPanel = new JPanel(new BorderLayout());
        TextArea msgField = new TextArea("My Secret is: " + strMySecret + "\n");
    
        resultPanel.add(msgField, BorderLayout.CENTER);
    
        InnerClass icTmp = new InnerClass();
        icTmp.StartPrivateWork(); // Not an error!
        icTmp.StartPublicWork();
    
        msgField.append("My Secret is: " + strMySecret);
    
        return resultPanel;
    }
    


    Gibt es in VB.Net ebenfalls so eine elegante Möglichekeit, oder muss ich stets erst die Äußere Klasse als Referenz an die Innere weitergeben?

    Außerdem bin ich mir über die folgende (aus meiner Sicht) Kuriosität nicht ganz im Klaren:

    Partial Public Class TestGeneralVB_2
        Inherits System.Windows.Forms.Form
    
        Private WithEvents btn As System.Windows.Forms.Button
        Private txt As System.Windows.Forms.TextBox
    
        Private Sub InitializeComponents()
            Dim pnlsplt As New System.Windows.Forms.SplitContainer With {.Dock = DockStyle.Fill}
    
            txt = New System.Windows.Forms.TextBox With {.Dock = DockStyle.Fill, .ScrollBars = ScrollBars.Vertical, .Multiline = True}
            btn = New System.Windows.Forms.Button With {.Dock = DockStyle.Fill, .Text = "Check EasyMeAccess"}
    
            With pnlsplt
                .Panel1.Controls.Add(btn)
                .Panel2.Controls.Add(txt)
            End With
    
            Me.Controls.Add(pnlsplt)
        End Sub
    End Class
    
    Public NotInheritable Class TestGeneralVB_2
        Private Class InnerClass
            Private Function StartPrivateWork() As TestGeneralVB_2
                '
                ' Warum wird hier ein Neues Objekt angelegt?
                ' Wieso ist so ein Zugriff überhaupt möglich?
                '
                Return TestGeneralVB_2.EasyMeAccess
            End Function
    
            Public Function StartPublicWork() As TestGeneralVB_2
                Return StartPrivateWork()
            End Function
        End Class
    
        Public Sub New()
            InitializeComponents()
        End Sub
    
        Public ReadOnly Property EasyMeAccess() As TestGeneralVB_2
            Get
                Return Me
            End Get
        End Property
    
        Public Function ComparePrivateWorkToMe() As Boolean
            With New InnerClass
                Return Me.Equals(.StartPublicWork)
            End With
        End Function
    
        Private Sub btn_Click() Handles btn.Click
            ' Asuming ComparePrivateWorkToMe:=False
            txt.AppendText("Result of Me.Equals(New InnerClass().StartPublicWork) is " & ComparePrivateWorkToMe() & vbNewLine)
        End Sub
    End Class

    was passiert genau in InnerClass.StartPrivateWork()? Wenn dass so in Ordnung geht, warum wird dann

    Public Module TestGeneralVB_1
        Partial Public Class OuterClass
            Inherits System.Windows.Forms.Form
    
        End Class
    
        Public NotInheritable Class OuterClass
            Private Class InnerClass
                Inherits TreeNode
    
                Private Function StartPrivateWork() As OuterClass
                    Return OuterClass.EasyMeAccess
                End Function
            End Class
    
            Public ReadOnly Property EasyMeAccess() As OuterClass
                Get
                    Return Me
                End Get
            End Property
        End Class
    End Module

    nicht vom Compiler akzeptiert obwohl es im Prinzip das Gleiche macht?
    Samstag, 2. Januar 2010 21:46

Antworten

  • Hallo,

    innere Klassen stellen in VB eigenständige Klassen dar ohne Bezug auf die äußere umgebene Klasse und müssen separat instantiiert werden und Referenzen zur äußeren Klasse explizit erhalten. Vorteil ist hier vor allem die Möglichkeit der Organisation innerhalb des Namespace, sowie die Einschränkung des Zugriffs (Private Modifier).

    Beim zweiten Beispiel bist Du einem VB Feature in Verbindung mit Windows Forms aufgesessen: VB erstellt hier automatisch eine Standardinstanz des Formulars, sobald ein Zugriff erfolgt. Bei normalen Klassen passiert das nicht, daher meckert der Compiler den Zugriff ohne Objektinstanz an. Wenn Du beim ersten Beispiel Deine Klasse nicht von System.Windows.Forms erben lässt, bekommst Du den gleichen Fehler, wie beim zweiten.
    Thorsten Dörfler
    Microsoft MVP Visual Basic
    • Als Antwort markiert RiverSpoon Samstag, 2. Januar 2010 23:30
    Samstag, 2. Januar 2010 23:15
    Moderator

Alle Antworten

  • Hallo,

    innere Klassen stellen in VB eigenständige Klassen dar ohne Bezug auf die äußere umgebene Klasse und müssen separat instantiiert werden und Referenzen zur äußeren Klasse explizit erhalten. Vorteil ist hier vor allem die Möglichkeit der Organisation innerhalb des Namespace, sowie die Einschränkung des Zugriffs (Private Modifier).

    Beim zweiten Beispiel bist Du einem VB Feature in Verbindung mit Windows Forms aufgesessen: VB erstellt hier automatisch eine Standardinstanz des Formulars, sobald ein Zugriff erfolgt. Bei normalen Klassen passiert das nicht, daher meckert der Compiler den Zugriff ohne Objektinstanz an. Wenn Du beim ersten Beispiel Deine Klasse nicht von System.Windows.Forms erben lässt, bekommst Du den gleichen Fehler, wie beim zweiten.
    Thorsten Dörfler
    Microsoft MVP Visual Basic
    • Als Antwort markiert RiverSpoon Samstag, 2. Januar 2010 23:30
    Samstag, 2. Januar 2010 23:15
    Moderator
  • Sehr geehrter Herr Dörfler,

    aus meiner Sicht haben Sie meine Fragen beantwortet. Vielleicht ist da noch Raum für eine Nachfrage:

    'Public Module TestGeneralVB_1
    Partial Public Class OuterClass
        Inherits System.Windows.Forms.Form
    
    End Class
    
    Public NotInheritable Class OuterClass
        Private Class InnerClass
            Inherits TreeNode
    
            Private Function StartPrivateWork() As OuterClass
                Return OuterClass.EasyMeAccess
            End Function
        End Class
    
        Public ReadOnly Property EasyMeAccess() As OuterClass
            Get
                Return Me
            End Get
        End Property
    End Class
    'End Module

    Nach entfernen der Moduldeklaration funtioniert dann auch wieder das 2. Beispiel. Sie haben bereits gesagt, dass es sich um ein VB Feature ("VBF") handelt. Wenn ich es richtig verstehe, dann greift dieses VBF nur dann, wenn die Klasse für sich stehend von Form erbt und nicht (wie in meinem Initialposting) in einem Modul (oder einer anderen Klasse) eingebunden ist. Ist das korrekt?

    Im Übrigen: Danke für die schnelle und präzise Antwort.

    Beste Grüße.
    Samstag, 2. Januar 2010 23:41
  • Hallo,

    freut mich, dass Dir meine Antwort weiter geholfen hat. Ja, das Feature mit den Standardinstanzen greift nur, wenn die Klassendeklaration für sich alleine steht und nicht in einer weiteren Klasse definiert ist. Der Designer funktioniert in diesem Fall auch nicht, obwohl VB erkennt, dass hier irgendwo eine Formular Definition erfolgt ist und dies entsprechend im Projektexplorer darstellt.
    Thorsten Dörfler
    Microsoft MVP Visual Basic
    Sonntag, 3. Januar 2010 08:40
    Moderator