Klassen verknüpfen

  • VB.NET

Es gibt 48 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Klassen verknüpfen

    hallo!

    ich habe eine hierarchische stückliste aus systemen>modulen>bauteilen. da alle drei elemente die selben attribute bestitzen sollte ich eine klasse dafür programmieren.

    soweit hab ich das mal. eine klasse zum definieren von elementen und eine übergeordnete, dort will ich die systeme reingeben, und danach bei der definition des module die einem system zuweisen.

    wie kann ich dies mit/in der klasse der elemeten umsetzen? hätte da jemand bitte ein paar hinweise für mich?


    Visual Basic-Quellcode

    1. Public Class VehicleElements
    2. Private mName As String
    3. Private mRelatedItem As String
    4. Public Property Name As String
    5. Get
    6. Return mName
    7. End Get
    8. Set(ByVal value As String)
    9. mName = value
    10. End Set
    11. End Property
    12. Public Property RelatedItem As String
    13. Get
    14. Return mRelatedItem
    15. End Get
    16. Set(ByVal value As String)
    17. mRelatedItem = value
    18. End Set
    19. End Property
    20. Public Sub New(ByVal Name As String, ByVal RelatedItem As String)
    21. Me.Name = Name
    22. Me.RelatedItem = RelatedItem
    23. End Sub
    24. End Class
    25. Public Class Vehicle
    26. Private mVehicleName As String
    27. Dim Vehicle As DataSet = New DataSet("Vehicle")
    28. Dim VehicleItems As DataTable = Vehicle.Tables.Add("VehicleItems")
    29. Dim ItemID As DataColumn = VehicleItems.Columns.Add( _
    30. "ItemID", Type.GetType("System.Int32"))
    31. Dim ItemName As DataColumn = VehicleItems.Columns.Add( _
    32. "ItemName", Type.GetType("System.String"))
    33. VehicleItems.PrimaryKey= New DataColumn() {ItemID}
    34. Public Property VehicleName As String
    35. Get
    36. Return mVehicleName
    37. End Get
    38. Set(ByVal value As String)
    39. mVehicleName = value
    40. End Set
    41. End Property
    42. Public Sub New(ByVal VehicleName As String)
    43. Me.VehicleName = VehicleName
    44. End Sub
    45. End Class

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „BöseSusi“ ()

    Nutze mal bitte den VB-Tag, dann kann man den Code wesentlich besser lesen. ([code=vbnet]...[/code])
    Properties in denen du nur Werte speicherst und nicht irgendetwas zuweisen/abfragst kannst du kurz so schreiben. Public Property Name As String
    Außerdem würde ich die Namen deiner Properties etwas ändern. Man würde niemals Vehicle.VehicleName aufrufen, sondern eher Vehicle.Name.
    Sehr kleinlich, aber wenn du es automatisch so machst ist es sehr sauber.

    Zu deinem eigentlichen Problem. Ich weiß nicht genau was du machen willst.
    Woher kommen denn deine Daten für die Elemente? Aus einer Datei oder per Usereingabe .... ?
    Und fast noch wichtiger, wie willst du diese Daten verwalten?

    Wenn du richtige Datenverwaltung haben willst, dann schau mal im Tutorialbereich unter Datenbanken. Da findest du Tutorials von @ErfinderDesRades zu typisierten Datasets.
    Ich denke, ich habe nicht 100%-ig verstanden, was Du vor hast. Es hört sich für mich so an:

    VB.NET-Quellcode

    1. 'Ausgangssituation:
    2. Class ItemA
    3. Property Name As String
    4. End Class
    5. Class ItemB
    6. Propert Name As String
    7. End Class
    8. 'Ziel:
    9. Class ItemBase
    10. Property Name As String
    11. End Class
    12. Class ItemA
    13. Inherits ItemBase
    14. End Class
    15. Class ItemB
    16. Inherits ItemBase
    17. End Class


    Durch die Vererbung bekommen die Klassen ItemA und ItemB ebenfalls je eine Name-Property.
    Die Properties sind übrigens syntaktisch richtig (Visual Basic 2010 vorausgesetzt).

    VB.NET-Quellcode

    1. Property Name As String
    2. 'Entspricht
    3. Private _Name As String
    4. Property Name As String
    5. Get
    6. Return _Name
    7. End Get
    8. Set(value As String)
    9. _Name = value
    10. End Set
    11. End Property

    Wenn man nur einfache Properties benötigt, spart man sich die Schreibarbeit.


    Wenn Du bereits im Konstruktor einen Wert an die Name-Property zuweisen möchtest, musst Du der Basisklasse einen Konstruktor geben und diesen von den Konstruktoren der abgeleiteten Klassen aufrufen:

    VB.NET-Quellcode

    1. Class ItemBase
    2. Property Name As String
    3. Public Sub New(NewName As String)
    4. Name = NewName
    5. End Sub
    6. End Class
    7. Class ItemA
    8. Inherits ItemBase
    9. Public Sub New(NewName As String)
    10. MyBase.New(NewName)
    11. End Sub
    12. End Class
    13. Class ItemB
    14. Inherits ItemBase
    15. Public Sub New(NewName As String)
    16. MyBase.New(NewName)
    17. End Sub
    18. End Class

    Der Aufruf an den Konstruktor der Basisklasse muss die erste Anweisung im Konstruktor der abgeleiteten Klasse sein. Danach kannst Du andere Logik einfügen.

    Es würde sich auch empfehlen, die Basisklasse als MustInherit zu deklarieren. Denn es macht keinen Sinn, ein Item zu erstellen, das weder ItemA noch ItemB ist.
    Dadurch kann man erbende Klassen auch zwingen, Methoden zu überschreiben. Z.B. könnte man eine

    Visual Basic-Quellcode

    1. MustOverride ReadOnly Property Price As Decimal
    haben. Jede Art von Item muss selbst wissen, wie es seine Kosten zu berechnen hat.


    PS: Codes solltest Du in Code-Tags verpacken, damit man sie lesen kann. Die macht man so:
    (code=vbnet)(/code) wobei die runden Klammern durch eckige wie diese [ und diese } zu ersetzen sind.


    Edit: Meh, das es-gab-Beiträge-seit-du-behonnen-hast-PlugIn funktioniert nicht / gibt's nicht.
    Und O_o das Syntax-Highlighting ist entstellt! Ok, "vbnet" statt "vb" verwenden, dann sieht's besser aus
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Niko Ortner“ ()

    ok das verstehe ich mit den namen, werde ich ändern.

    die daten für die elemente kommen per usereingabe.

    verwaltet soll das ganze in einem datenbanksystem werden, aber so weit bin ich noch nicht, bzw wir in der schule. geht nur darum mal zu lernen wie man die klassen ausftellt.
    mit typisierten DataSets hab ich schon was gemacht, das hier soll aber auf nicht damit gemacht werden.

    was will ich genau machen:
    einfach eine hierarchische struktur aus den elementen aubauen.
    das vehicle besteht aus systemen, die systeme aus modulen, und die module aus bauteilen.
    Was Du brauchst, sind Auflistungen. Da gibt's einige unterschiedliche.
    Die, die Dich vermutlich interessieren wird ist die List(Of T). Die verwendet man so:

    VB.NET-Quellcode

    1. Dim Items As New List(Of String)
    2. Items.Add("Hallo")
    3. Items.Add("Welt")

    Die Liste enthält dann 2 Strings. "Hallo" und "Welt". Und du kannst bei List(Of String) statt String jeden beiliebigen anderen Typ hinschreiben. Dann musst Du Elemente von dem entsprechenden Typ hinzufügen. Z.B. List(Of Integer) -> Items.Add(4).
    Die List(Of T) ist darauf ausgelegt, dass man vorher nicht genau weiß, wie viele Elemente man hat (dafür würde man Arrays verwenden). Und ich vermute mal, das ist genau das, was bei Dir zutrifft.

    Bei dir würde das dann so in der Richtung aussehen:

    VB.NET-Quellcode

    1. Class Vehicle
    2. Private _Systems As New List(Of System) 'Hier wird direkt eine Instanz erstellt
    3. Public ReadOnly Property Systems As List(Of System) 'ReadOnly, damit man die Liste nicht ersetzen kann.
    4. Get
    5. Return _Systems
    6. End Get
    7. End Property
    8. End Class
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    danke für deine antwort.

    so ganz blick ich da leider noch nicht durch...

    der theorie nach muss ich das umsetzen:


    mir ist auch das relationale modell dazu klar, mit zwischentabellen/fremschlüsseltabellen bilde ich die n:m beziehungen nach.
    aber wie ich diese verknüpungen der IDs machen soll...

    sorry, ich rede jetzt wahrscheinlich an deine mühsamen posts vorbei, aber ich bin gerade verwirrt.
    m:n-Beziehungen ohne Dataset darzustellen wird hässlich. Es wird wohl darauf hinauslaufen, dass du entweder die Methode der Zwischentabelle nachbildest, indem du ne unabhängige Liste mit Objekte, die lediglich die IDs miteinander verknüpfen, anlegst, oder indem du den objektorientierten Weg gehst und in jede Klasse ne Liste mit den IDs der zugehörigen Objekte gibst.
    Ist echt ne Schande, sowas ohne nen Dataset zu lösen. Du kannst deinem Lehrer ruhig von mir ausrichten, dass er seinen Beruf gerade hart am verfehlen ist, wenn er euch beibringt solchen Ranz zu programmieren.
    ja manche lehrer haben mit der praxis nix am hut bzw leben noch in einer anderen zeit...

    wir sollen das ohne typisierte datasets in vb machen, also sonst dürfen datasets schon verwendet werden.

    wäre so ein grundkonzept möglich:
    eine klasse mit ID, namen usw, und auswahl einer von 3 datatables (systeme/module/bauteile)
    eine klasse welche die zwischentabelle repräsentiert wo ich elemente zweier datatables verknüpfen kann

    oder wie löst man sowas? ich hab keine bsp zu sowas und weiß daher nicht wie man das grundsätzlich löst...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „BöseSusi“ ()

    Sowas ? EDIT: Tshuldigung, hab m:n nicht gesehen :s

    Visual Basic-Quellcode

    1. Public Class Vehicle
    2. Public Property ID() As Integer
    3. Public Property Name() As String
    4. Public Property Systems() As List(Of System)
    5. End Class
    6. Public Class System
    7. Public Property ID() As Integer
    8. Public Property Name() As String
    9. Public Property Documentation() As String
    10. Public Property Moduls() As List(Of [Module])
    11. End Class
    12. Public Class [Module]
    13. Public Property ID() As Integer
    14. Public Property Name() As String
    15. Public Property Documentation() As String
    16. Public Property Parts() As List(Of Part)
    17. End Class
    18. Public Class Part
    19. Public Property ID() As Integer
    20. Public Property Name() As String
    21. Public Property Technology() As String
    22. Public Property Documentation() As String
    23. End Class

    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
    So wie dus machst, mit eigenen Klassen, haben DataTables da nichts verloren, die funktionieren nur, wenn du auch alles andere aus dem DataSet verwendest.

    Ne einzelne m:n-Beziehung müsste etwa so aussehen:

    VB.NET-Quellcode

    1. Public Class Vehicle
    2. Public Property Id As Integer
    3. End Class
    4. Public Class System
    5. Public Property Id As Integer
    6. End Class
    7. Public Class VehicleToSystem
    8. Public Property VehicleId As Integer
    9. Public Property SystemId As Integer
    10. End Class
    Für jede dieser drei Klassen brauchst du dann ne eigene Auflistung.

    BöseSusi schrieb:

    in eine DataTable ablegen?
    Nein, Du kannst Instanzen von System einfach zur Instanz der List adden:

    VB.NET-Quellcode

    1. Dim ll = New List(Of System)
    2. ll.Add(New System(a, b, c))
    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!
    Was in dieser Konzeption vielleicht ganz interessant ist ist sowas hier.
    Das würde richtig sein wenn ein "Vehicle" eine Auflistung von mehreren Systemen ist.

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' Stellt eine Auflistung von Systemen dar
    3. ''' </summary>
    4. ''' <remarks></remarks>
    5. Public Class Vehicle
    6. Inherits List(Of System)
    7. Public Property ID As Integer
    8. Public Property Name As String
    9. End Class


    Aufruf:

    VB.NET-Quellcode

    1. Dim v As New Vehicle()
    2. v.Add(New Systeme())
    3. v.Name = "Test"
    4. v.ID = 1
    5. MessageBox.Show(v.Count.ToString() & " " & v.Name)

    LaMiy schrieb:

    VB.NET-Quellcode

    1. MessageBox.Show(v.Count.ToString() & " " & v.Name)
    Dann würde ich aber gleich die ToString()-Methode von Vehicle überschreiben.
    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!
    Die Aufgabe ist unlösbar.
    m:n - Relationen ohne relationales Datenmodell - das geht nicht. Begründung gugge die relationale GrundIdee
    mit Listen kannst du nur 1:n - Relationen darstellen, also Baumstrukturen. Was du aber aufgezeichnet hast, geht aber eindeutig drüber hinaus.

    naja - vlt. ist nur die Beschriftung falsch, nämlich wenn da 1:n stünde statt m:n dann wäre das möglich. und die Aussagen sind ja auch nur sinnvoll als 1:n - Aussagen:
    a Vehicle has Systems
    a System has Modules
    a Module has Parts

    (so einfach kann man so Kram formulieren - ich frag mich echt immer, wozu UML gut sein soll.)

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

    aber eine art von modulen kann in mehreren systemen verbaut sein, sowie eine art von bauteilen in mehreren modulen...

    sooo und beim tippen kam ich auf die idee, dass ich schrieb "eine art von bauteilen/modulen" dh nicht dass EIN bauteil/modul in mehreren übergeordneten elementen verbaut ist, daher 1:n, hatte ich da einen groben denkfehler?
    von Bauteilen ist in deinem obigen Datenmodell an keiner stelle die Rede. Ah, du meinst wohl Parts.

    ja, dann ist die Beschriftung richtig, und was ich zuerst gesagt hab: Die aufgabe ist mit Listen von Objekten, wie wiederum Listen von anneren Objekten enthalten, nicht lösbar.
    relationale Infrastruktur muß her.

    ansonsten kannst du ja mal versuchen, dass ein Modul eine Liste von Parts hat, und ein Part hat eine Liste von Moduln.
    Interessante Sache.
    Wenn du nun einem Modul einen Part zufügst, dann musste dem Part auch das Modul zufügen. (und beim Löschen entsprechend)
    Nun hat man aber ein Problem, wenn man alle Parts überhaupt sehen will, weil die sind ja jetzt auf viele Module verteilt.
    Man braucht aber auch die Gesamt-Schau, denn wenn du nun einen bestimmten Part in ein 2. Modul einsetzen willst, musste den Part ja auswählen können (möglicht ohne alle Moduln durchgucken zu müssen)

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

    ich möchte meine klasse items über eine andere klasse collection "verwalten". also nur ein "item" per befehl zu einer liste hinzufügen oder entfernen können.

    ist mein dafür erstellter code richtig?

    VB.NET-Quellcode

    1. Public Class Item
    2. Private m_name As String
    3. Private m_technology As String
    4. Public Property technology As String
    5. Get
    6. Return m_technology
    7. End Get
    8. Set(ByVal value As String)
    9. m_technology = value
    10. End Set
    11. End Property
    12. Public Property name As String
    13. Get
    14. Return m_name
    15. End Get
    16. Set(ByVal value As String)
    17. m_name = value
    18. End Set
    19. End Property
    20. Public Sub New(ByVal name As String, ByVal technology As String)
    21. m_name = name
    22. m_technology = technology
    23. End Sub
    24. End Class
    25. Public Class Collection
    26. Dim items As List(Of Item)
    27. Public Sub AddItem(ByVal itemname As String, ByVal itemtechnology As String)
    28. items.Add(New Item(name:=itemname, technology:=itemtechnology))
    29. End Sub
    30. Public Sub RemoveItem(ByVal itemname As String, ByVal itemtechnology As String)
    31. items.Remove(New Item(name:=itemname, technology:=itemtechnology))
    32. End Sub
    33. End Class
    Remove kann nicht funktionieren, deine Items sind Referenztypen und daher ungleich, auch wenn der Inhalt identisch ist. Du kannst ein RemoveWhere implementieren, aber schlauer wäre es, einfach gleich auf den Objekten zu arbeiten.

    Properties schreibt man übrigens groß.