NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 10 - Vlastnosti ve Visual Basic .NET

V předešlém cvičení, Řešené úlohy k 9. lekci OOP ve VB.NET, jsme si procvičili nabyté zkušenosti z předchozích lekcí.

V dnešním VB.NET tutoriálu se podíváme na další prvky tříd, které ještě neznáme. Začněme slíbenými vlastnostmi.

Vlastnosti

Velmi často se nám stává, že chceme mít kontrolu nad změnami nějakého atributu objektu zvenčí. Budeme chtít atribut nastavit jako read-only nebo reagovat na jeho změny. Založme si nový projekt (název Vlastnosti) a vytvořme následující třídu Student, která bude reprezentovat studenta v nějakém informačním systému.

Class Student
    Public jmeno As String
    Public muz As Boolean
    Public vek As Integer
    Public plnolety As Boolean

    Public Sub New(jmeno As String, pohlavi As Boolean, vek As Integer)
        Me.jmeno = jmeno
        Me.muz = pohlavi
        Me.vek = vek
        plnolety = True
        If vek < 18 Then
            plnolety = False
        End If
    End Sub

    Public Overrides Function ToString() As String
        Dim jsemPlnolety As String = "jsem"
        If Not plnolety Then
            jsemPlnolety = "nejsem"
        End If
        Dim pohlavi As String = "muž"
        If Not muz Then
            pohlavi = "žena"
        End If
        Return String.Format("Jsem {0}, {1}. Je mi {2} let a {3} plnoletý.", jmeno, pohlavi, vek, jsemPlnolety)
    End Function

End Class

Třída je velmi jednoduchá, student se nějak jmenuje, je nějakého pohlaví a má určitý věk. Podle tohoto věku se nastavuje atribut plnolety pro pohodlnější vyhodnocování plnoletosti na různých místech systému. K uložení pohlaví používáme hodnotu Boolean, zda je student muž. Konstruktor dle věku určí, zda je student plnoletý. Metoda ToString() je navržena pro potřeby tutoriálu tak, aby nám vypsala všechny informace. V reálu by tam bylo pravděpodobně jen jméno studenta. Pomocí konstruktoru si nějakého studenta vytvořme:

Klikni pro editaci
  • App
    • Module1.vb
    • Student.vb
  • Dim s As New Student("Pavel Hora", True, 20)
    Console.WriteLine(s)
    
    • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

    Výstup:

    Konzolová aplikace
    Jsem Pavel Hora, muž. Je mi 20 let a jsem plnoletý.

    Vše vypadá hezky, ale atributy jsou přístupné jak ke čtení, tak k zápisu. Objekt tedy můžeme rozbít například takto (hovoříme o nekonzistentním vnitřním stavu):

    Klikni pro editaci
    • App
      • Module1.vb
      • Student.vb
    • Dim s As New Student("Pavel Hora", True, 20)
      s.vek = 15
      s.muz = False
      Console.WriteLine(s)
      Console.ReadKey()
      
      • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

      Výstup:

      Konzolová aplikace
      Jsem Pavel Hora, žena. Je mi 15 let a jsem plnoletý.

      Určitě musíme ošetřit, aby se plnoletost obnovila při změně věku. Když se zamyslíme nad ostatními atributy, není nejmenší důvod, abychom je taktéž umožňovali modifikovat. Student si za normálních okolností asi jen stěží změní pohlaví nebo jméno. Bylo by však zároveň vhodné je vystavit ke čtení, nemůžeme je tedy pouze pouze nastavit jako Private. V dřívějších dílech seriálu jsme k tomuto účelu používaly metody, které sloužily ke čtení privátních atributů. Jejich název jsme volili jako VratVek() a podobně. Ke čtení vybraných atributů vytvoříme také metody a atributy označíme jako privátní. Třída by nově vypadala např. takto (vynechal jsem konstruktor a ToString()):

      Class Student
          Private jmeno As String
          Private muz As Boolean
          Private vek As Integer
          Private plnolety As Boolean
      
          ...
      
          Public Function VratJmeno() As String
              Return jmeno
          End Function
      
          Public Function VratPlnoletost() As Boolean
              Return plnolety
          End Function
      
          Public Function VratVek() As Integer
              Return vek
          End Function
      
          Public Function Muz() As String
              Return muz
          End Function
      
          Public Sub NastavVek(hodnota As Integer)
              vek = hodnota
              ' přehodnocení plnoletosti
              plnolety = True
              If vek < 18 Then
                  plnolety = False
              End If
          End Sub
      
      
      End Class

      Metody, co hodnoty jen vracejí, jsou velmi jednoduché. Nastavení věku má již nějakou vnitřní logiku, při jeho změně musíme totiž přehodnotit atribut plnolety. Zajistili jsme, že se do proměnných nedá zapisovat jinak, než my chceme. Máme tedy pod kontrolou všechny změny atributů a dokážeme na ně reagovat. Nemůže se stát, že by nám někdo vnitřní stav nekontrolovaně měnil a rozbil.

      Metodám k navrácení hodnoty se říká gettery a metodám pro zápis settery. Pro editaci ostatních atributů bychom udělali jednu metodu EditujStudenta, která by byla podobná konstruktoru. Jméno, věk a podobně by se tedy měnily pomocí této metody, tam bychom mohli např. konstrolovat, zda hodnoty dávají smysl, opět bychom odchytili všechny pokusy o změnu na jediném místě. Ruční psaní getterů a setterů je jistě velmi pracné. Nemohl by to udělat někdo za nás? Ano, VB.NET nám je umí vygenerovat. Poté již nehovoříme o atributech, ale o vlastnostech.

      Syntaxe vlastnosti je velmi podobná atributu:

      Public Property Jmeno As String

      Zprvu to vypadá, jako bychom deklarovali atribut. Jméno vlastnosti je však velkým písmenem, jedná se totiž o metodu (přesněji 2 metody). Ještě k deklaraci musíme přidat klíčové slovo Property. V ukázce výše se vygeneruje setter i getter, vlastnost půjde tedy normálně číst i modifikovat:

      Console.WriteLine(objekt.Jmeno)' číst
      objekt.Jmeno = "Jan Malý"' zapisovat

      Jediný rozdíl oproti atributu je zvenčí v tom, že počáteční písmeno je velké. VB.NET ve skutečnosti vygeneruje privátní atribut a k němu dvě metody, které podle kontextu volá (pozná dle situace zda čteme nebo zapisujeme). Pokud chceme uvést vlastní setter a getter, je syntaxe následující:

      Private _jmeno As String
      Public Property Jmeno As String
          Get
              Return _jmeno
          End Get
          Set(value As String)
              _jmeno = value
          End Set
      End Property

      U vlastní deklarace si hodnotu ještě někde musíme pamatovat, dává se do privátního atributu, obvykle ho pojmenujeme podtržítko a název vlastnosti s malým počátečním písmenem.

      Když do vlastnosti nevygenerujeme setter, nepůjde měnit ani zevnitř, ani zvenčí. Pokud si přejeme, aby vlastnost nešla mimo třídu měnit, označíme setter jako privátní:

      Public Property Jmeno() As String
          Get
              Return _jmeno
          End Get
          Private Set(value As String)
              _jmeno = Value
          End Set
      End Property
      Private _jmeno As String

      Tohoto budeme hojně využívat a právě takto bude vypadat většina vlastností našich budoucích tříd.

      V getteru nebo setteru se toho může samozřejmě dělat více, než jen načtení/zápis hodnoty, pokud si ho definujeme ručně. Ukažme si to na našem příkladu s plnoletostí, která se musí po změně věku přehodnotit:

      Private _vek As Integer
      Public Property Vek() As Integer
          Get
              Return _vek
          End Get
          Set(value As Integer)
              _vek = value
              ' kontrola plnoletosti
              Plnolety = True
              If _vek < 18 Then
                  Plnolety = False
              End If
          End Set
      End Property

      Zprvu je nutné si vytvořit privátní proměnnou vek s malým písmenem, ve které bude hodnota ve skutečnosti uložena. V getteru a setteru poté pracujeme s touto proměnnou, pokud použijete v get nebo set Vek, program se zacyklí!. Není možné definovat jen getter nebo setter, buď se oba vygenerují sami nebo oba definujeme ručně. Pro přístup k zadané hodnotě je nám v setteru k dispozici klíčové slovo Value. Takto se ve VB.NET do verze 4.0 musely definovat všechny vlastnosti, až poté Microsoft zavedl tzv. autoimplementaci a zkrácený zápis, jaký jsme si uvedli výše. U drtivé většiny vlastností totiž v metodách nepotřebujeme žádnou logiku. S Vek nyní pracujeme opět stejně, jako s atributem, jen s velkým písmenem. Nenápadné přiřazení do věku vnitřně spustí další logiku k přehodnocení vlastnosti Plnolety:

      objekt.Vek = 15 ' nyní se změní i plnoletost

      Stejně můžeme pochopitelně implementovat i getter a například něco někam logovat.

      Upravíme si naši třídu Student tak, aby používala vlastnosti. Vypadala by takto:

      Class Student
      
          Private _jmeno As String
          Public Property Jmeno() As String
              Get
                  Return _jmeno
              End Get
              Private Set(value As String)
                  _jmeno = Value
              End Set
          End Property
      
          Private _muz As Boolean
          Public Property Muz() As Boolean
              Get
                  Return _muz
              End Get
              Private Set(value As Boolean)
                  _muz = Value
              End Set
          End Property
      
          Private _plnolety As Boolean
          Public Property Plnolety() As Boolean
              Get
                  Return _plnolety
              End Get
              Private Set(value As Boolean)
                  _plnolety = Value
              End Set
          End Property
      
          Private _vek As Integer
          Public Property Vek() As Integer
              Get
                  Return _vek
              End Get
              Set(value As Integer)
                  _vek = value
                  ' kontrola plnoletosti
                  Plnolety = True
                  If _vek < 18 Then
                      Plnolety = False
                  End If
              End Set
          End Property
      
          Public Sub New(jmeno As String, pohlavi As Boolean, vek As Integer)
              EditujStudenta(jmeno, pohlavi, vek)
          End Sub
      
          Public Sub EditujStudenta(jmeno As String, muz As Boolean, vek As Integer)
              Me.Jmeno = jmeno
              Me.Muz = muz
              Me.Vek = vek
          End Sub
      
          Public Overrides Function ToString() As String
              Dim jsemPlnolety As String = "jsem"
              If Not Plnolety Then
                  jsemPlnolety = "nejsem"
              End If
              Dim pohlavi As String = "muž"
              If Not Muz Then
                  pohlavi = "žena"
              End If
              Return String.Format("Jsem {0}, {1}. Je mi {2} let a {3} plnoletý.", jmeno, pohlavi, vek, jsemPlnolety)
          End Function
      
      End Class

      Vlastnosti budeme odteď používat stále, umožňují nám totiž objekty dokonale zapouzdřit. V .NET jsou všechny veřejné atributy tříd vlastnosti (např. nám známá vlastnost Length na stringu), platí pravidlo, že co jde ven je vlastnost, co se používá jen uvnitř je privátní atribut. Veřejný atribut se defakto příliš nepoužívá. Celou třídu i s ukázkovým programem si samozřejmě opět můžete stáhnout pod článkem. Kontrolu plnoletosti můžeme z konstruktoru nyní vyjmout, jakmile totiž dosadíme do vlastnosti Vek, nastaví se plnoletost sama. Ještě si opět vyzkoušejme problémový příklad:

      Klikni pro editaci
      • App
        • Module1.vb
        • Student.vb
      • Dim s As New Student("Pavel Hora", True, 20)
        s.vek = 15
        ' s.pohlavi = False ' tento řádek nyní způsobí chybu a musí být odebrán
        Console.WriteLine(s)
        
        • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

        A výstup:

        Konzolová aplikace
        Jsem Pavel Hora, muž. Je mi 15 let a nejsem plnoletý.

        Pokud celou vlastnost označíme jako private, nelze poté settery nebo gettery označit jako public.

        V následujícím kvízu, Kvíz - Dědičnost, statika, vlastnosti ve VB.NET OOP, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


         

        Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

        Stáhnout

        Stažením následujícího souboru souhlasíš s licenčními podmínkami

        Staženo 189x (58.29 kB)
        Aplikace je včetně zdrojových kódů v jazyce VB

         

        Jak se ti líbí článek?
        Před uložením hodnocení, popiš prosím autorovi, co je špatněZnaků 0 z 50-500
        Předchozí článek
        Řešené úlohy k 9. lekci OOP ve VB.NET
        Všechny články v sekci
        Objektově orientované programování ve Visual Basic .NET
        Přeskočit článek
        (nedoporučujeme)
        Kvíz - Dědičnost, statika, vlastnosti ve VB.NET OOP
        Článek pro vás napsal Michal Žůrek - misaz
        Avatar
        Uživatelské hodnocení:
        10 hlasů
        Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.
        Aktivity