Kolekce uvnitř vlastní třídy a přístup k ní   otázka

VB.NET, Architektura

Zdravím,

chci si udělat vlastní třídu, která bude obsahovat, kromě jiných properties. i kolekci.

Snažím se aby bylo možné ke kolekci přistupovat stylem:

MojeTřída.Kolekce.Add(), ale nevím jak na to.

Vím, že mohu udělat kolekci jako public a pak to půjde, jenže pak si nemohu dát do metody .add vlastní podmínky (nebo aspoň nevím jak....)

Nebo mohu kolekci nechat jako private a udělat metodu, že bude syntax:

MojeTřída.PřidejDoKolekce(), což se také není úplně ono.

Jako třetí možnost sem zkusil udělat si vlastní třídu Kolekce, se všemi metodami, a pak v konstruktoru třídy MojeTřída vytvořit novou Kolekci (myšleno instanci třídy Kolekce). Pak už funguje MojeTřída.Kolekce.Add(), ale vadí mi, že se potom dá kdekoli jinde vytvořit i třída kolekce, která nedává žádný smysl. Jak mohu udělat to, abych mohl třídu kolekce použít pouze ve třídě MojeTřída a ne už třeba ve třídách Form1 atd.?

Případně: Jak mohu udělat to, o co mi jde, jinak?

Díky!

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nakonec jsem to vyřešil tak, že jsem třídu Kolekce vytvořil uvnitř třídy MojeTřída, je to tak OK nebo je to (opět) prasárna? :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Je to prasárna. Public třídy nikdy nemají být definované uvnitř jiných tříd. Korektní postup je udělat si třídu kolekce odvozené například od List(Of T) a v třídě "MojeTřída" k ní přistupovat pomocí Public ReadOnly vlastnosti.

Do metody Add si samozřejmě můžete dát vlastní podmínky a to overridováním této metody mateřské třídy, od které to odvozujete.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Díky za odpověď, ale přiznám se, že Vaše moc odpověď mi v tom moc jasno neudělala. Myslíte, že bych Vás mohl poprosit o menší ukázku nebo nějaký odkaz (k prvnímu odstavci)?

Děkuji

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To jsou naprosté základy OOP, bez nich to můžete zabalit. Články na téma OOP jsou zde i na jiných webech zabývajících se vývojem software.

Class MyList
  Inherits List(Of Object)
  Shadows Sub Add(ByVal value As Object)
    MyBase.Add(value)
  End Sub
End Class

Class MojeTřída
  Private _myList As New MyList
  Public ReadOnly Property List() As MyList
    Get
      Return _myList
    End Get
  End Property
End Class

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Díky. Dědění a překrývání metod mi je jasné, ale todle:

Private _myList As New MyList
Public ReadOnly Property List() As MyList
....

se přiznám, jsem ještě neviděl...

Díyk

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Cože? Vždyť je to normální vlastnost určitého typu, stejně jako by to byl String, Integer, nebo cokoliv jiného. A pozor na to překrývání metod, mezi Shadows a Overrides je velký rozdíl.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

:) Ne, jen jsem se špatně vyjádřil, nikdy jsem neviděl přístup k "vlastní" třídě tímto způsobem přes readonly vlastnost a proto mne to celé nenapadlo (ostatně kdybych, to již viděl, tak bych se neptal). Samotnou syntaxi public readonly property něco as typ samozřejmě znám a používám. To je jedno, neumím to popsat, každopádně děkuji za rozšíření obzorů.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nastudujte si řádně základy OOP - tohle patří k jeho téměř největším základům.Jedná se o tzv.zapouzdření.Tzn.že nedáváte přístup přímo k členským proměnným,ale jejich hodnotu je možné zjistit přes metodu uvnitř dané třídy.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Lze nějak zařídit, aby Vámi vytvořenou třídu "MyList" nešlo používat samostatně?

Pokud u ní překryji mnoho metod tak, aby seděly na třídu "MojeTřída", pak třída MyList nedává žádný smysl k použití a mohla by uživatele mást.

(já si to samozřejmě pamatuji, ale v teoretické rovině by to být užitečné mohlo - nebo opět plácám nesmysly?)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pakliže děláte třídu, která bude jen určitým specifikem jiné kolekce, pak je dobré podědit již od nějaké existující kolekce a překrýt, popř. doplnit metody.

Chcete-li ale udělat třídu, která mimo ostatních vlastností má i kolekci, pak je dobré využít tzv. zapouzdření. Členskou proměnnou (kolekci) uděláte privátní a budete k ní přistupovat výhradně skrze speciální metody, které již budou obsahovat vaše určité podmínky. Např.:

Public Class MojeTrida

    Private _list As New List(Of Object)

    Public Sub pridat(obj As Object)
        If obj IsNot Nothing Then
            Me._list.add(obj)
        End If
    End Sub

End Class

Kód může mít chybu, psal jsem z hlavy a ve VB.NET jsem dlouho nedělal :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

ano to mne napadlo a i jsem to tak zkoušel (viz čtvrtý odstavec mého úplně prvního příspěvku), ale není to ono - podle mě je v mém případě lepší mít všechny metody automaticky třída.něco.add() třída.něco.count() (viz příklad p. Linharta), než mít metody třída.PřidejDoNěčeho() a třída.PočetVNěčem().

Pravděpodobně jsem svůj problém jako začátečník špatně popsal, ale třeba se Váš příklad bude hodit dalším, kteří se zde budou učit OOP v budoucnu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback