ein paar Fragen zu Zugriffs-Modifikatoren

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 37 Antworten in diesem Thema. Der letzte Beitrag () ist von Bartosz.

    Wenns funktioniert, wie es soll, ists richtig. Wie soll es funktionieren?

    "pure-virtual" ist für mich eine ungenügende Anforderungs-Definition.

    scheint dasselbe zu sein, was ich unter MustOverride verstehe.
    Also wenns kompiliert ists richtig (falls Kompilierbarkeit gewünscht ist)

    Du verwendest es in einer Variante, Vererbung bietet natürlich weitere Möglichkeiten.
    Der Versuch, alle durchzudeklinieren dürfte allerdings ein ziemliches Buch werden (und was dann keiner lesen wird).

    Aber so als Schmankerl - Wie findste den hier?

    VB.NET-Quellcode

    1. Public MustInherit Class Lebewesen
    2. Public Alter As Integer
    3. Public ReadOnly Property Name As String
    4. Get
    5. Return Nenne_deinen_Namen()
    6. End Get
    7. End Property
    8. Protected MustOverride Function Nenne_deinen_Namen() As String
    9. End Class
    Dafür müssteste die Erben natürlich entsprechend anpassen (soll ja nicht zu einfach sein für dich ;) )

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Bartosz schrieb:

    Und jede erbende Klasse bringt dann weitere Eigenschaften mit sich.
    Das ist etwas zu allgemein.
    Die Basisklasse kann virtual | Overridable Prozeduren und Properties haben, da wird nur dann der Code der abgeleiteten Klasse ausgeführt, wenn diese Prozeduren mit override bzw. Overrides überschrieben wurden, ansonsten wird der Code der Basisklasse ausgeführt.
    abstract | MustOverride Prozeduren und Properties müssen überschrieben werden. Die betreffenden Klasse müssen dann als abstract bzw. MustInherit deklariert werden, wenn nicht, gibt es einen Compilerfehler.
    In diesem Kontext gibt es auch den Konstrukt, dass eine virtual | Overridable deklarierte Prozedur in einer abgeleiteten Klasse nicht die Prozedur in der Basisklasse, sondern in einer dazwischen abgeleiteten Klasse aufruft, das geht mit new virtual | Overridable Shadows.
    Dazu folgenden Test, Form mit 3 Button:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim tt As New Test1()
    4. tt.HalloWorld2()
    5. Console.WriteLine()
    6. End Sub
    7. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    8. Dim tt As New Test2()
    9. tt.HalloWorld2()
    10. Console.WriteLine()
    11. End Sub
    12. Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    13. Dim tt As New Test3()
    14. tt.HalloWorld2()
    15. Console.WriteLine()
    16. End Sub
    17. End Class
    und die Testklassen:

    VB.NET-Quellcode

    1. Public MustInherit Class TestBase
    2. Public Overridable Sub HalloWorld()
    3. Console.WriteLine("hello base")
    4. End Sub
    5. Public MustOverride Sub HalloWorld2()
    6. End Class
    7. Public Class Test1
    8. Inherits TestBase
    9. Public Overrides Sub HalloWorld2()
    10. Console.WriteLine("hello 2 from Test1")
    11. HalloWorld()
    12. End Sub
    13. End Class
    14. Public Class Test2
    15. Inherits Test1
    16. Public Overrides Sub HalloWorld2()
    17. Console.WriteLine("hello 2 from Test2")
    18. MyBase.HalloWorld()
    19. End Sub
    20. Public Overridable Shadows Sub HalloWorld()
    21. Console.WriteLine("hello Test2")
    22. End Sub
    23. End Class
    24. Public Class Test3
    25. Inherits Test2
    26. Public Overrides Sub HalloWorld2()
    27. Console.WriteLine("hello 2 from Test3")
    28. HalloWorld()
    29. End Sub
    30. End Class


    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wie soll es funktionieren? ... was ich unter MustOverride verstehe.
    Jup, genau das meinte ich. RFG hat's für mich nochmal genauer erläutert. Danke an der Stelle. Ich habe den Begriff ‚pure-virtual‘ in einem Video aufgeschnappt und dachte, ich bring den mal. Ich habe festgestellt, dass ich lieber ‚MustOverride‘ sagen sollte. Ich schaue mir euren Code nacheinander an und melde mich wieder.
    @ErfinderDesRades
    Dafür müssteste die Erben natürlich entsprechend anpassen (soll ja nicht zu einfach sein für dich
    Habe ich versucht. Es gibt 2 Fehler, siehe Anhang.

    Ich komme gerade nicht weiter, was deinen Code anbelangt:
    Die Eigenschaft Name ergibt (für mich noch) keinen Sinn: Der Getter verwendet die überschreibbare Methode Nenne_deinen_Namen(), um einen Namen zurückzugeben, während Nenne_deinen_Namen(), um diesen Namen zurückzugeben, die Eigenschaft Getter verwendet. Ich benötige ein internes Feld, um Name schreibgeschützt zu halten und ich muss Protected Overrides Function Nenne_deinen_Namen() As String ändern. Diese Methode sollte nicht public sein (oder doch?). Oder ich ändere das zu Name Get / Private Set. Diese Mischung aus öffentlichen Feldern und Eigenschaften muss überarbeitet werden.
    Sag mir bitte, wie du es meinst. Ist keine Kritik, ich möchte nur verstehen, wie du es gemeint hast. Ich möchte deinen Code gerne verwenden.

    VB.NET-Quellcode

    1. #Disable Warning IDE1006 ' Benennungsstile
    2. Public MustInherit Class Lebewesen
    3. Public Alter As Integer 'Age
    4. 'Public Name As String = ""
    5. 'Public MustOverride Sub Nenne_deinen_Namen() ' pure-virtual gewollt
    6. Public ReadOnly Property Name As String
    7. Get
    8. Return Nenne_deinen_Namen()
    9. End Get
    10. End Property
    11. Protected MustOverride Function Nenne_deinen_Namen() As String
    12. End Class
    13. Public MustInherit Class Saeugetiere : Inherits Lebewesen
    14. Public kann_fliegen As Boolean
    15. Public Felllaenge As Single 'in Prozent des Möglichen
    16. Public Anzahl_der_Zaehne As Integer
    17. Public Koerpertemperatur As Integer 'in ℃
    18. End Class
    19. Public MustInherit Class Paarhufer : Inherits Saeugetiere
    20. Public ist_nachtaktiv As Boolean
    21. Public Structure Waffenarten
    22. Public Property hat_Hoerner As Boolean
    23. Public Property hat_Stosszaehne As Boolean
    24. Public Property hat_Klauen As Boolean
    25. End Structure
    26. End Class
    27. Public MustInherit Class Echte_Schweine : Inherits Paarhufer
    28. Public hat_Bart As Boolean
    29. End Class
    30. Public Class Hausschwein : Inherits Echte_Schweine
    31. Public dieses_wird_im_Stall_gehalten As Boolean
    32. Public WA As Waffenarten 'Instanz erzeugen
    33. Public Sub New(ByVal uebergebenesAlter As Integer, ByVal imStall As Boolean, ByVal Name As String)
    34. Me.Alter = uebergebenesAlter
    35. Me.kann_fliegen = False
    36. Me.Felllaenge = 0.2F
    37. Me.Anzahl_der_Zaehne = 44
    38. Me.Koerpertemperatur = 39
    39. Me.ist_nachtaktiv = False
    40. Me.dieses_wird_im_Stall_gehalten = imStall
    41. Me.WA.hat_Hoerner = False
    42. Me.WA.hat_Stosszaehne = False
    43. Me.WA.hat_Klauen = False
    44. Me.hat_Bart = False
    45. Me.Name = Name
    46. End Sub
    47. Public Overrides Function Nenne_deinen_Namen() As String
    48. 'MessageBox.Show($"{Name} is its name.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information)
    49. Return Me.Name
    50. End Function
    51. End Class
    52. #Enable Warning IDE1006 ' Benennungsstile
    Bilder
    • Screenshot 2021-04-17 144716.png

      80,37 kB, 1.094×702, 58 mal angesehen
    @Bartosz So redet Deine Nachbarin wieder mit Dir, ist allerdings ein wenig wüst:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. #Disable Warning IDE1006 ' Benennungsstile
    2. Public MustInherit Class Lebewesen
    3. Protected Name1 As String = "Lecker"
    4. Public Alter As Integer 'Age
    5. 'Public Name As String = ""
    6. 'Public MustOverride Sub Nenne_deinen_Namen() ' pure-virtual gewollt
    7. Protected ReadOnly Property Name As String
    8. Get
    9. Return Name1
    10. End Get
    11. End Property
    12. Public MustOverride Function Nenne_deinen_Namen() As String
    13. End Class
    14. Public MustInherit Class Saeugetiere : Inherits Lebewesen
    15. Public kann_fliegen As Boolean
    16. Public Felllaenge As Single 'in Prozent des Möglichen
    17. Public Anzahl_der_Zaehne As Integer
    18. Public Koerpertemperatur As Integer 'in ℃
    19. End Class
    20. Public MustInherit Class Paarhufer : Inherits Saeugetiere
    21. Public ist_nachtaktiv As Boolean
    22. Public Structure Waffenarten
    23. Public Property hat_Hoerner As Boolean
    24. Public Property hat_Stosszaehne As Boolean
    25. Public Property hat_Klauen As Boolean
    26. End Structure
    27. End Class
    28. Public MustInherit Class Echte_Schweine : Inherits Paarhufer
    29. Public hat_Bart As Boolean
    30. End Class
    31. Public Class Hausschwein : Inherits Echte_Schweine
    32. Private ReadOnly Name2 As String
    33. Public dieses_wird_im_Stall_gehalten As Boolean
    34. Public WA As Waffenarten 'Instanz erzeugen
    35. Public Sub New(ByVal uebergebenesAlter As Integer, ByVal imStall As Boolean, ByVal Name As String)
    36. Me.Alter = uebergebenesAlter
    37. Me.kann_fliegen = False
    38. Me.Felllaenge = 0.2F
    39. Me.Anzahl_der_Zaehne = 44
    40. Me.Koerpertemperatur = 39
    41. Me.ist_nachtaktiv = False
    42. Me.dieses_wird_im_Stall_gehalten = imStall
    43. Me.WA.hat_Hoerner = False
    44. Me.WA.hat_Stosszaehne = False
    45. Me.WA.hat_Klauen = False
    46. Me.hat_Bart = False
    47. Me.Name2 = "Schmeckt gut"
    48. End Sub
    49. Public Overrides Function Nenne_deinen_Namen() As String
    50. 'MessageBox.Show($"{Name} is its name.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information)
    51. Return Me.Name2
    52. End Function
    53. End Class
    54. #Enable Warning IDE1006 ' Benennungsstile

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany Ich habe das gerade eingebaut und habe geschaut, was erreicht wurde:
    • in Form1.vb kann man den Namen einmalig zuweisen und dann nur noch über die Sub Nenne_deinen_Namen() abfragen
    • man kann selbst nicht S1.Name schreiben (gut so)

    VB.NET-Quellcode

    1. Private Sub Button_Lebewesen_Click(sender As Object, e As EventArgs) Handles Button_Lebewesen.Click
    2. Dim S1 As New Hausschwein(10, False, "Horst")
    3. Dim Test As String = S1.Nenne_deinen_Namen()
    4. End Sub


    Ist es richtig, dass Zeile 7 0 Verweise hat?

    VB.NET-Quellcode

    1. #Disable Warning IDE1006 ' Benennungsstile
    2. Public MustInherit Class Lebewesen
    3. Protected Name1 As String = ""
    4. Public Alter As Integer 'Age
    5. 'Public Name As String = ""
    6. 'Public MustOverride Sub Nenne_deinen_Namen() ' pure-virtual gewollt
    7. Protected ReadOnly Property Name As String
    8. Get
    9. Return Name1
    10. End Get
    11. End Property
    12. Public MustOverride Function Nenne_deinen_Namen() As String
    13. End Class


    Das ist schon geil.
    Bilder
    • Vollbildaufzeichnung 17.04.2021 173151.jpg

      179,31 kB, 774×923, 39 mal angesehen

    Bartosz schrieb:

    Ist es richtig, dass Zeile 7 0 Verweise hat?
    Wo, glaubst Du denn, unterschlägt Visual Studio einen Verweis?
    btw: Felllaenge ist benennungstechnisch ungünstig. Du schreibst im Kommentar, was in den Variablenname gehört. Sonst musst Du im dümmsten Fall jedes mal wieder überlegen, in welcher Einheit das Teil ist. Daher RelativeFelllaenge oder FelllaengeInProzent oder ähnlich. Kommt natürlich drauf an, was 100 % darstellt.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    0 Verweise heißt, dass Du in Deinem Code eben noch nirgends auf die Property verweist/zugreifst. Du hast sie zwar, nutzt sie aber noch nicht. Mehr will die VS damit nicht sagen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ich habe es nun wie folgt gelöst. Wie gestern mit der TestClass. Damit habe ich gelernt was ich lernen wollte und geschafft, was ich schaffen wollte. Aus Form1.vb kann man nicht auf Name zugreifen, nur über die Prozedur Nenne_deinen_Namen().

    Was @ErfinderDesRades mit "Dafür müssteste die Erben natürlich entsprechend anpassen" genau meinte , muss ich noch schauen.
    Ich bedanke mich für die Hilfe!

    VB.NET-Quellcode

    1. #Disable Warning IDE1006 ' Benennungsstile
    2. Public MustInherit Class Lebewesen
    3. Public Alter As Integer 'Age
    4. Private _Name As String
    5. Public Property Name() As String
    6. Get
    7. Return _Name
    8. End Get
    9. Protected Set(__name As String)
    10. _Name = __name
    11. End Set
    12. End Property
    13. Public MustOverride Sub Nenne_deinen_Namen()
    14. End Class
    15. Public MustInherit Class Saeugetiere : Inherits Lebewesen
    16. Public kann_fliegen As Boolean
    17. Public FelllaengeInProzent As Single
    18. Public Anzahl_der_Zaehne As Integer
    19. Public Koerpertemperatur As Integer 'in ℃
    20. End Class
    21. Public MustInherit Class Paarhufer : Inherits Saeugetiere
    22. Public ist_nachtaktiv As Boolean
    23. Public Structure Waffenarten
    24. Public Property hat_Hoerner As Boolean
    25. Public Property hat_Stosszaehne As Boolean
    26. Public Property hat_Klauen As Boolean
    27. End Structure
    28. End Class
    29. Public MustInherit Class Echte_Schweine : Inherits Paarhufer
    30. Public hat_Bart As Boolean
    31. End Class
    32. Public Class Hausschwein : Inherits Echte_Schweine
    33. Public dieses_wird_im_Stall_gehalten As Boolean
    34. Public WA As Waffenarten 'Instanz erzeugen
    35. Public Sub New(ByVal uebergebenesAlter As Integer, ByVal imStall As Boolean, ByVal uebergebener_Name As String)
    36. Me.Alter = uebergebenesAlter
    37. Me.kann_fliegen = False
    38. Me.FelllaengeInProzent = 0.2F
    39. Me.Anzahl_der_Zaehne = 44
    40. Me.Koerpertemperatur = 39
    41. Me.ist_nachtaktiv = False
    42. Me.dieses_wird_im_Stall_gehalten = imStall
    43. Me.WA.hat_Hoerner = False
    44. Me.WA.hat_Stosszaehne = False
    45. Me.WA.hat_Klauen = False
    46. Me.hat_Bart = False
    47. Me.Name = uebergebener_Name
    48. End Sub
    49. Public Overrides Sub Nenne_deinen_Namen()
    50. MessageBox.Show($"{Name} is its name.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information)
    51. End Sub
    52. End Class
    53. #Enable Warning IDE1006 ' Benennungsstile


    In Form1.vb

    VB.NET-Quellcode

    1. Private Sub Button_Lebewesen_Click(sender As Object, e As EventArgs) Handles Button_Lebewesen.Click
    2. Dim S1 As New Hausschwein(10, False, "Horst")
    3. S1.Nenne_deinen_Namen()
    4. End Sub

    Bartosz schrieb:

    VB.NET-Quellcode

    1. Public MustInherit Class Saeugetiere : Inherits Lebewesen
    2. Public kann_fliegen As Boolean
    3. Public FelllaengeInProzent As Single
    4. Public Anzahl_der_Zaehne As Integer
    5. Public Koerpertemperatur As Integer 'in ℃
    6. End Class
    würde ich so machen:

    VB.NET-Quellcode

    1. Public MustInherit Class Saeugetiere : Inherits Lebewesen
    2. Public KannFliegen As Boolean
    3. ''' <summary>
    4. ''' in %
    5. ''' </summary>
    6. Public Felllaenge As Single
    7. Public ZaehneAnzahl As Integer
    8. ''' <summary>
    9. ''' im °C
    10. ''' </summary>
    11. Public Koerpertemperatur As Integer 'in ℃
    12. End Class
    Es ist immer sinnvoll, solch Information in den '''-Kommentar zu stecken, da sie in der IDE und im ObjektBrowser angezeigt wird:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @ErfinderDesRades Ich meinte eigentlich, dass ich nicht in Form1.vb einfach so schreiben kann S1.Name = "". Aber ja, du hast Recht, man sieht noch in den Vorschlägen S1.Name.
    Daher wollte ich in Lebewesen.vb den Public Property Name() As String auf Private ändern, aber dann kommen Fehlermeldungen (siehe Bild). Was kann man tun?
    Bilder
    • Screenshot 2021-04-17 224844.png

      30,42 kB, 709×555, 44 mal angesehen
    • Screenshot 2021-04-17 224910.png

      101,24 kB, 932×913, 45 mal angesehen
    ich kapier nicht was du willst.
    Willst du eine Property, die nicht angezeigt wird?
    Dann kannste sie natürlich nicht benutzen.
    Wird sie angezeigt, kannstese benutzen.
    Ist sie Readonly, kannstese auch benutzen aber nur mit Lesezugriff.

    Aber das ist doch sowas von banal - was muss ich dir das erklären?

    Bartosz schrieb:

    Was kann man tun?
    Höre auf, Deine verqueren Tests weiterzuentwickeln.
    Pack diese alle in den "Ich habe gelernt"-Ordner und setz das ganze mit dem inzwischen gelernten neu auf.
    Der @ErfinderDesRades würde wahrscheinlich sagen: Mach Dir ein ordentliches Daten-Modell.
    Dem würde ich beipflichten.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!