Objektově orientované programování - základy

17. díl - Objektově orientované programování - základy

Tomáš Herceg       30.06.2008       VB.NET       23328 zobrazení

V tomto díle se podíváme na základy objektově orientovaného programování, řekneme si, co je to třída, co je to objekt, vysvětlíme si rozdíl mezi hodnotovými a referenčními typy atd. Jedná se pouze o úvod, celá problematika je poměrně složitá.

V tomto seriálu jsme se naučili základní konstrukce jazyka Visual Basic .NET a také jsme se je v několika málo dílech naučili používat. Jen stručně shrnu, co už umíme, pokud si v něčem nejste jisti, projděte si patřičné minulé díly:

Další úroveň - objekty

Těchto pár odrážek, které jsem tady vyjmenoval, jsou základní kameny procedurálního programování. Při návrhu našich programů jsme si problém rozdělili na několik úloh, které se provádějí s různým vstupem opakovaně, a pro každou z nich jsme vytvořili proceduru nebo funkci.

Další úrovní, která nás jako programátory čeká, je tzv. objektově orientované programování. U velkých projektů se v množství procedur ztrácí přehlednost a jednotlivé úlohy se dají velmi efektivně rozdělit do skupin podle jejich funkčnosti. Díky objektovému programování můžeme efektivně oddělit různé vrstvy aplikace, což zvýší přehlednost a sníží počet možných chyb, které bychom mohli "nasekat". V předminulém dílu jsem se už snažil objekty trochu přiblížit, nyní se do toho podíváme hlouběji a podrobněji, první seznámení máme už za sebou.

Co je to objekt?

Filozofická otázka na začátek, objektem ve skutečném světě je všechno. Objekt v programování je instance nějaké třídy. Třída popisuje to, co by objekt měl umět a co by si měl pamatovat, je to taková šablona, obecný model. Podle každé třídy pak můžeme vytvořit kolik chceme nezávislých objektů, které budou přesně vyhovovat její definici, budou si zachovávat svůj vlastní stav, a budou umět provádět nějaké akce.

Deklarace třídy

Vše, co třída obsahuje, musí být ve VB.NET zapsáno uvnitř této konstrukce:

 Public Class MojeTrida

End Class

Dovnitř třídy můžeme zapisovat deklarace těchto "věcí" (ve skutečnosti je jich víc, nám teď budou stačit tyhle):

  • metody (dříve jsme jim říkali funkce a procedury, u tříd se jim dohromady říká metody)
  • proměnné
  • vlastnosti

Řízení přístupu

Pro každou z těchto položek uvnitř třídy můžeme určit, kdo k ní může přistupovat. Máme v zásadě 4 možnosti:

  • Public - k členům třídy budeme moci přistupovat odkudkoliv
  • Friend - k členům třídy budeme moci přistupovat z dané assembly (ve většině případů je to to samé, jako projekt; když tedy napíšete nějakou DLL knihovnu, nedostante se ke členům označeným jako Friend z jiného projektu, který tuto knihovnu využívá)
  • Protected - k členům třídy budeme moci přistupovat jen z této třídy a ze tříd, které tuto třídu dědí (o tom až za chvíli)
  • Private - k členům třídy budeme moci přistupovat jen z této třídy

Proměnné, metody a vlastnosti uvnitř třídy

Dovnitř třídy můžeme nadeklarovat proměnné. Místo nám známého Dim ale píšeme modifikátor přístupu:

     Public prom1 As Integer

Metody uvnitř třídy píšeme úplně stejně jako dříve, opět akorát před Sub nebo Function přihodíme modifikátor přístupu:

     Public Sub MojeMetoda(ByVal par As String)

End Sub

Novým elementem, který jsme sice používali, ale nikdy nedeklarovali, jsou vlastnosti. Vlastnost je typicky dvojice metod Get a Set, první z nich má za úkol nějakou hodnotu získat, druhá z nich hodnotu nastavuje. V drtivé většině případů se vlastnosti používají k zajištění a ošetření čtení a změny nějaké proměnné. Pokud vypustíme metodu Get, nebo Set, dostaneme WriteOnly resp. ReadOnly vlastnost, tedy vlastnost určenou pouze k zápisu, resp. ke čtení. První typ se nepoužívá téměř nikdy, druhý typ je poměrně častý. Deklarace vlastnosti vypadá takto:

     Private _promenna As Integer
Public Property Promenna() As Integer
Get
Return _promenna
End Get
Set(ByVal value As Integer)
_promenna = value
End Set
End Property

Toto je typické použití vlastnosti, je to taková obálka kolem proměnné - v metodě Set předanou hodnotu uložíme do proměnné, v metodě Get vrátíme to, co v proměnné je.

     Private _jenKeCteni As Integer
Public ReadOnly Property JenKeCteni() As Integer
Get
Return _jenKeCteni
End Get
End Property

V této ukázce je proměnná určená jen ke čtení. Tady je význam zřejmý, zvenčí uvidíme hodnotu proměnné, ale nemůžeme ji nijak změnit, protože samotná proměnná je Private. Vlastnost jako taková je ale Public, což znamená, že vlastnost zvenku použít můžeme.

Nestačí nám místo vlastnosti Public proměnná?

Pokud jste se ještě neztratili, možná vám přijde divné, k čemu potřebujeme vlastnosti, když vlastnost je Public a nedělá nic jiného, než že čte a nastavuje Private proměnnou. Nestačilo by udělat proměnnou Public a na vlastnost se vykašlat?

Samozřejmě že stačilo, nicméně v praxi se to téměř nikdy nedělá. Nikdy totiž nevíte, kdy budete potřebovat před změnou hodnoty přidat nějakou kontrolu. Představme si, že bude naše třída nějaká schránka a chceme si u ní pamatovat počet položek, kolik se do ní vejde. Určitě nechceme, aby do proměnné šlo přiřadit záporné číslo, protože to prostě nedává smysl. Proto je vždy lepší kolem proměnné udělat vlastnost, kde v metodě Set či Get můžeme nějaké podmínky ověřit a nějak zareagovat (například přiřadit nulu, nebo vyvolat výjimku a přerušit tak nějakou akci).

     Private _pocet As Integer
Public Property Pocet() As Integer
Get
Return _pocet
End Get
Set(ByVal value As Integer)
If value >= 0 Then
_pocet = value
Else
_pocet = 0
End If
End Set
End Property

Obecná zvyklost je dávat vlastnosti všude a Public proměnné až na naprosté minimum případů, kdy je to opodstatněné, nikdy nepoužívat, nikdy totiž nevíte, kdy při čtení nebo přiřazování budete chtít eliminovat možnost nějaké chyby a nějakou logiku tam přidat. Díky vlastnostem můžete zajistit, že vám zvenku nikdo nenadělá nějakou škodu a nezmění něco tak, jak nemá, čímž by mohl narušit funkčnost celé aplikace.

Praktický příklad

Vytvořte si nový projekt typu Console Application. Dnes nebudeme používat žádná okénka, to by nás jenom pletlo. Vytvořil se nám nový soubor, ve kterém je procedura Main. V konzolové aplikaci se při jejím spuštění spustí procedura Main, provede se to, co je uvnitř, a když se dorazí na konec procedury, aplikace se ukončí. Co my nyní uděláme? Nadeklarujeme si třídu.

Přidejte si do projektu novou třídu, pojmenujte ji Zamestnanec.

 Přidání třídy do projektu

Pojmenování třídy

Visual Studio nám do souboru už připravilo základní kostru, dovnitř deklarací tedy nakopírujte vnitřek třídy:

 Public Class Zamestnanec

Private _jmeno As String
''' <summary>
''' Jméno zaměstnance
''' </summary>
Public Property Jmeno() As String
Get
Return _jmeno
End Get
Set(ByVal value As String)
_jmeno = value
End Set
End Property

Private _vek As Integer
''' <summary>
''' Věk zaměstnance
''' </summary>
Public Property Vek() As Integer
Get
Return _vek
End Get
Set(ByVal value As Integer)
_vek = value
End Set
End Property

Private _email As String
''' <summary>
''' E-mail zaměstnance
''' </summary>
Public Property Email() As String
Get
Return _email
End Get
Set(ByVal value As String)
_email = value
End Set
End Property

''' <summary>
''' Vygeneruje vizitku zaměstnance
''' </summary>
Public Sub Vizitka()


End Sub

End
Class

Tím jsme vytvořili třídu Zamestnanec, které jsme dali vlastnosti Jmeno, Vek a Email. Dále tato třída má metodu Vizitka, kterou můžeme volat zvenčí. Nyní napíšeme samotné generování vizitky. Napsal jsem to možná přehnaně složitě, ale alespoň si vyzkoušíte pořádně dělit problém na podúlohy. Nahraďte proceduru Vizitka tímto kódem:

     ''' <summary>
''' Vytiskne vizitku
''' </summary>
Public Sub Vizitka()
VizitkaOkraj()
'horní okraj

VizitkaObsah() 'vnitřek

VizitkaOkraj() 'dolní okraj

Console.WriteLine() 'odřádkovat
End Sub

Private Sub VizitkaOkraj()
Console.WriteLine(
"**************************************************")
End Sub

Private Sub VizitkaRadek(ByVal text As String)
Console.Write(
"* ") 'levý okraj

If text.Length > 46 Then text = text.Substring(0, 43) & "..." 'text vizitky (moc dlouhý oříznout)
Console.Write(text)

Console.CursorLeft = 49
'pravý okraj
Console.WriteLine("*")
End Sub

''' <summary>
''' Vytiskne obsah vizitky
''' </summary>
Private Sub VizitkaObsah()
VizitkaRadek(
"Jméno: " & Me.Jmeno)
VizitkaRadek(
"Věk: " & Me.Vek)
VizitkaRadek(
"E-mail: " & Me.Email)
End Sub

Co naše procedura Vizitka dělá? Nejdřív nakreslí horní okraj vizitky, pak vypíše samotný obsah vizitky, pak nakreslí dolní okraj a odřádkuje. Vykreslování horního a dolního okraje je jednoduché, v metodě VizitkaObsah zavoláme třikrát VizitkaRadek a předáme jí to, co chceme vypsat. Tato procedura před samotný výpis nakreslí levý okraj, pak vypíše text (pokud by se tam nevešel, tak ho ořízne a na konec přidá tři tečky), a pak dokreslí pravý okraj. To je celé.

Zdě opět používáme modifikátory přístupu - zvenčí je možné zavolat pouze metodu Vizitka, nemůžeme nakreslit samostatně například její okraj.

Všimněte si dále, jak získáme hodnotu nějaké vlastnosti. Me.vlastnost přistupuje k vlastnostem aktuální instance objektu. Vlastně bychom tam ani nemuseli psát to Me., stačil by jen název vlastnosti, ale je lepší jej zdůraznit, aby bylo hned jasné, odkud se to bere.

Jak naši třídu použít a zobrazovat vizitky?

Přepněte se nyní do prvního souboru Module1.vb, kde máme proceduru Main, do níž musíme napsat hlavní program. Právě jsme si napsali třídu Zamestnanec a budeme tedy vytvářet její instance. Je důležité si uvědomit rozdíl mezi třídou a objektem - třída je jen jedna, je to jenom šablona, fyzicky nikde neexistuje, je to prostě vzor. Objekt je už daný exemplář, určité místo v paměti, které si pamatuje všechny své proměnné, a můžeme na něm používat metody a vlastnosti, které jsou definované uvnitř třídy. Každá instance objektu je nezávislá na ostatních instancích, můžeme si tedy vytvořit třeba 30 zaměstnanců a každý bude mít jiné jméno, jiný věk a jiný e-mail. Jak na to? Zkopírujte do procedury Main tento kód:

     Sub Main()
Dim z1 As Zamestnanec 'proměnná z1 typu Zamestnanec
z1 = New Zamestnanec() 'tady vytváříme novou instanci třídy, vzniká nový objekt
z1.Jmeno = "Lubomír Zatrsatr" 'přistupujeme k vlastnostem objektu
z1.Vek = 24
z1.Email =
"[email protected]"

Dim z2 As New Zamestnanec() 'zkrácené vytvoření objektu
z2.Jmeno = "Jožin z Bažin" 'přistupujeme k vlastnostem objektu
z2.Vek = 150
z2.Email =
"[email protected]"

'vypíšeme vizitky obou zaměstnanců, každá bude jiná, protože každý objekt má jiné hodnoty svých vlastností
z1.Vizitka()
z2.Vizitka()

Console.ReadKey()
End Sub

Vizitky

Všimněte si, že když ve Visual Studiu napíšete z1, objeví se vám v nabídce IntelliSense jenom metody a vlastnosti, které jsou v daném kontextu vidět, neukáže vám žádné Private členy.

IntelliSense ukazuje jen to, co můžeme použít

     ''' <summary>
''' Věk zaměstnance
''' </summary>
Public Property Vek() As Integer
Get
Return _vek
End Get
Set(ByVal value As Integer)
_vek = value
End Set
End Property

Dále si všimněte, že pokud použijete nad deklarací vlastnosti nebo metody speciální XML komentáře, ukáže vám je i Visual Studio v této nabídce. To je obrovská výhoda při práci v týmu, velice rychle zjistíte, co dělá metoda, kterou napsal někdo jiný, můžete ji jen použít a nestaráte se o to, jak funguje vevnitř.

Hodnotové a referenční typy

V .NET Frameworku máme tzv. hodnotové a referenční typy (Value a Reference types). Hodnotové datové typy jsou například Integer, Long, Short, Byte, Double, Single, Boolean a dále sem patří struktury, které jsme již používali, ale raději je připomenu:

     Public Structure Zaznam
Dim id As Integer
Dim cena As Double
End Structure

Proč hodnotové? Protože proměnná si pamatuje přímo jejich hodnotu a kdykoliv ji přiřazujeme, předává se celá hodnota (kopíruje se paměť). Pozor na kopírování velkých struktur, opravdu se kopírují všechna data v celé struktuře.

Asi všichni víte, co bude na konci v proměnných a a b:

         Dim a As Integer = 32
Dim b As Integer = 16
a = b
b += 2
Console.Write(a &
" " & b)

V a je 32, v b je 16. Přiřazením hodnoty b do a způsobíme, že v obou proměnných bude 16. Když pak b zvětšíme o 2, bude v b 18. To je naprosto přirozené a každý by to tak čekal.

Referenční datové typy se ale chovají trochu jinak. Proměnná jako taková nenese přímo samotnou hodnotu, ale jenom adresu místa v paměti, kde se hodnota nachází. Říkáme, že proměnná obsahuje referenci (pointer, ukazatel). Mezi referenční datové typy patří např. String, pole a objekty. Při vytváření se pole, řetězec nebo objekt neuloží do proměnné, ale .NET jej uloží na tzv. haldu (místo, které je v paměti pro objěkty vyhrazeno) a do proměnné uloží odkaz na místo, kde se v haldě hodnota nachází. Vezměme si tento kód:

         'vytvoření objektů z1 a z2
Dim z1 As Zamestnanec 'proměnná z1 typu Zamestnanec
z1 = New Zamestnanec() 'tady vytváříme novou instanci třídy, vzniká nový objekt
z1.Jmeno = "Lubomír Zatrsatr" 'přistupujeme k vlastnostem objektu
z1.Vek = 24
z1.Email =
"[email protected]"

Dim z2 As New Zamestnanec() 'zkrácené vytvoření objektu
z2.Jmeno = "Jožin z Bažin" 'přistupujeme k vlastnostem objektu
z2.Vek = 150
z2.Email =
"[email protected]"

'******* nyní přiřadíme z2 do z1
z1 = z2

'vypíšeme vizitky obou zaměstnanců, každá bude jiná, protože každý objekt má jiné hodnoty svých vlastností
z1.Vizitka()
z2.Vizitka()

Console.ReadKey()

V tomto kódu děláme prakticky to samé, akorát se složitějšími datovými typy. Vytvořili jsme si a nějak nastavili proměnné z1 a z2 a pak jsme přiřadili z2 do z1. Na konzoli se nám vypíše dvakrát vizitka druhého zaměstnance. Ke druhému zaměstnanci se již nikdy nedostaneme, protože v žádné proměnné si už nedržíme referenci na jeho objekt. Je to jako s číslem 32, které zmizelo, protože jsme jej přepsali. Tady jsme ale přepsali jenom referenci, tedy čtyřbajtovou adresu (pro rýpaly osmibajtovou na 64bitových systémech) na objekt na haldě.

Třicetdvojku jsme v předchozím případě přepsali v paměti jinými daty, ale tady nám na haldě zůstal objekt, ke kterému se mimo jiné už nikdy nedostaneme. Nebudou se nám zahozené objekty na haldě hromadit? No jistě že budou. .NET Framework má na to takzvaný Garbage Collector (česky něco jako popelář, sběrač odpadu). Ten se jednou za čas spustí, najde na haldě nepoužívané objekty, a ty odstraní. Je to poměrně složitý proces, .NET si u každého objektu pamatuje, kolik referencí na něj existuje, a při každém přiřazení si toto číslo aktualizuje. Pokud se číslo stane nulou, znamená to, že na objekt už nikdo neodkazuje, a tím pádem se může vyhodit. Je nutné si uvědomit, že v jiných jazycích, např. v C++, žádný GC není, tam se z2 = z1 napsat nesmí, objekt by z paměti nikdo nikdy neodstranil a pokud byste to dělali ve velkém, za chvíli by aplikace spotřebovala všechnu paměť. My ale GC máme, přesto je dobré brát v potaz to, že prakticky nemůžeme ovlivnit, kdy se GC bude spouštět, a hlavně naše aplikace se při činnosti GC pozastaví a nemáme nad ničím kontrolu. GC se také většinou spouští až když už paměti opravdu moc nezbývá, rozhodně neběží pořád a nesbírá objekty průběžně.

Co jsme ale nyní udělali, když jsme přiřadili z2 do z1? Obě dvě proměnné nyní ukazují na ten stejný objekt, na ta samá fyzická data. Co to znamená? Že když změníme nějakou vlastnost nebo něco v z1, změní se to automaticky i v z2, obě proměnné odkazují na stejnou paměť. Přidáte-li do předchozí ukázky poslední řádek, změní se věk u obou vizitek.

         '******* nyní přiřadíme z2 do z1
z1 = z2
z1.Vek = 35

Předávání parametrů metodám hodnotou a referencí

Velmi podobné chování můžeme potřebovat, když předáváme parametry metodám. Před deklaraci každého parametru nám VB.NET sám přidá kouzelné slovíčko ByVal, které říká, že parametr se předává hodnotou. Pokud toto slovíčko změníme na ByRef, bude se proměnná předávat referencí. Tohle nemá nic společného s hodnotovými a referenčními typy přímo, ale princip je stejný.

     Sub Main()
Dim i As Integer = 3 'nastavíme i
Zmen(i) 'zavoláme funkci, předáme jí HODNOTU i
Console.WriteLine(i) 'i bude pořád 3, původní proměnná se nezměnila
End Sub

Sub Zmen(ByVal i As Integer)
i = 5
End Sub

V metodě Zmen je parametr i předáván hodnotou, to znamená, že hodnota proměnné se zkopíruje a nad touto kopií se provede kód metody Zmen. Po návratu do rodičovské metody Main je v i její původní hodnota, změnila se jenom kopie. Pokud změníme ByVal na ByRef, změní se i i v rodičovské metodě Main, protože jsme nepředávali hodnotu proměnné, ale referenci, opět jenom adresu na místo, kde je hodnota uložená (přestože Integer je hodnotový typ).

Stejně to funguje i s typy referenčními, předávání parametrů se chová jako přiřazování. Hodnota, která se zde ale předává, je reference na objekt na haldě, takže když předáme objekt pomocí ByVal, změny na vlastnostech a proměnných objektu se projeví i ven. Pokud ale do parametru přiřadíme jiný objekt, v rodičovské proceduře se nic nezmění, protože jsme změnili jenom kopii reference na objekt. Předáme-li objekt ByRef, přiřazení se projeví i venku. Lépe je to vidět z kódu:

     Sub Main()
'vytvoření objektů z1 a z2
Dim z1 As Zamestnanec 'proměnná z1 typu Zamestnanec
z1 = New Zamestnanec() 'tady vytváříme novou instanci třídy, vzniká nový objekt
z1.Jmeno = "Lubomír Zatrsatr" 'přistupujeme k vlastnostem objektu
z1.Vek = 24
z1.Email =
"[email protected]"

Dim z2 As New Zamestnanec() 'zkrácené vytvoření objektu
z2.Jmeno = "Jožin z Bažin" 'přistupujeme k vlastnostem objektu
z2.Vek = 150
z2.Email =
"[email protected]"


Zmen(z1, z2) 'zavoláme funkci, předáme jí HODNOTY proměnných z1 a z2, tedy ukazatele na haldu

z1.Vizitka() 'vlastnost objektu se změnila
End Sub

Sub Zmen(ByVal z1 As Zamestnanec, ByVal z2 As Zamestnanec)
z1.Vek = 13
'změna vlastnosti objektu se projeví ven
z1 = z2 'přiřazení do samotné proměnné ale ne, máme ByVal
End Sub

Na tomto příkladu se tedy změní věk, ale v z1 v metodě Main bude pořád první zaměstnanec, změnila se jenom kopie. Předáme-li první parametry ByRef, změna se projeví a zavoláním z1.Vizitka() by se vypsala vizitka druhého zaměstnance.

     Sub Zmen(ByRef z1 As Zamestnanec, ByVal z2 As Zamestnanec)
z1.Vek = 13
'změna vlastnosti objektu se projeví ven
z1 = z2 'tady se změna projeví i v rodičovské metodě, máme ByRef
End Sub

ByVal tedy předává funkci kopii toho, co je uloženo v proměnné (hodnota u hodnotových typů nebo reference u referenčních typů), ByRef předá referenci na hodnotu v proměnné.

Konstruktor

Občas potřebujeme při vytváření instance objektu provést ještě nějaký další kód, typicky nastavit objektu výchozí hodnoty vlastností. Proto může mít třída svůj konstruktor. Konstruktor se zapisuje jako normální metoda, která má název New. Konstruktor může mít i parametry, které při inicializaci může samozřejmě použít. Parametry konstruktoru předáváme při vytváření instance objektu. Tento kód přidejte do třídy Zamestnanec:

     Public Sub New(ByVal jmeno As String, ByVal vek As String, ByVal email As String)
Me.Jmeno = jmeno
Me.Vek = vek
Me.Email = email
Console.WriteLine(
"Objekt vytvořen, jméno " & jmeno)
End Sub

Všimněte si, že zde je při přístupu do vlastností nutné použít slovo Me, protože pokud máme dva elementy se stejným názvem, VB.NET si vždycky vybere ten s nižším kontextem (viditelností). Tady kdybychom napsali jmeno = jmeno, nic by se nestalo, protože VB.NET si vždycky vybere dříve lokální proměnnou metody, než vlastnost třídy. Pokud řekneme Me.Jmeno, je jasné, že chceme jmeno, které patří objektu, takže v tomto případě vezme vlastnost. Při vytváření objektu ještě vypíšeme na konzoli informaci, že se objekt vytvořil.

Proceduru Main změňte takto:

     Sub Main()
'vytvoření objektů z1 a z2
Dim z1 As New Zamestnanec("Lubomír Zatrsatr", 24, "[email protected]")
Dim z2 As New Zamestnanec("Jožin z Bažin", 150, "[email protected]")

'vypíšeme vizitky obou zaměstnanců, každá bude jiná, protože každý objekt má jiné hodnoty svých vlastností
z1.Vizitka()
z2.Vizitka()

Console.ReadKey()
End Sub

Bude to dělat úplně to samé, co první verze metody Main, je to jen kratší a vypíše to navíc dvě hlášky o vytvoření objektů tak, jak je to v kontruktoru. Hodnoty, které chceme přiřadit do jednotlivých vlastností, totiž předáváme jako parametry konstruktoru, a ten už je nastaví do svých vlastností sám.

Jen dodávám, že konstruktorů si můžete napsat více, s různými počty a typy parametrů. Pokud třídě nenapíšete konstruktor žádný, dá jí .NET Framework výchozí konstruktor bez parametrů, který neudělá nic navíc. Konstruktor nemusí být Public, v některých situacích se vyplatí mít například Private nebo Protected konstruktory, ale o tom až někdy příště.

Pokračování příště...

Chápu, že si asi říkáte, co tady pořád valím s těmi objekty, že to je na nic, že když budete chtít vypisovat vizitky do konzole, že se to dá napsat na pár řádků a nemusí se kvůli tomu dělat třídy. Příště náš příklad použijeme a vysvětlíme si, co je to dědičnost, a jak ji používat. Tam teprve uvidíme, proč jsem navrhnul tisk vizitek takto složitě a dělal na každou část vizitky metodu, přestože jsem to všechno mohl plácnout do Vizitka.

Pokud stále nechápete, jak objekty fungují, nezoufejte a klidně se ptejte v diskusi. K čemu objekty jsou, k tomu se ještě dopracujeme, zatím je s tím pětkrát víc psaní a desetkrát víc nudné teorie, ale u větších projektů se objekty opravdu vyplatí.

 

hodnocení článku

2 bodů / 2 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Všechny díly tohoto seriálu

18. Dědičnost 06.10.2008
17. Objektově orientované programování - základy 30.06.2008
16. Třídy a funkce .NET frameworku, o kterých je dobré vědět 31.12.2007
15. Práce se soubory, úvod do objektově orientovaného programování 19.11.2007
14. Vykreslujeme graf 31.08.2007
13. Úvod do grafiky 27.08.2007
12. Práce s textem a řetězci 17.08.2007
11. Kolekce a pole 27.07.2007
10. Funkce a procedury 01.06.2007
9. Přidáváme druhý formulář 18.05.2007
8. Pole, cykly a práce se soubory 14.05.2007
7. Pole 09.05.2007
6. Cyklus For 05.05.2007
5. Složitější podmínky a rozhodovací struktury 26.04.2007
4. Podmínky a operátory 26.04.2007
3. Proměnné a datové typy 25.04.2007
2. Začínáme programovat 25.04.2007
1. Úvod, vývojové prostředí a základní pojmy 25.04.2007

 

Mohlo by vás také zajímat

Tipy a triky pro ASP.NET - díl 5.: Komponenta pro zadávání data a času

V tomto díle se podíváme na to, jak s využitím komponenty CalendarExtender z knihovny AjaxControlToolkit napsat komponentu pro snadné zadávání data, která podporuje validaci a datové zdroje.

Windows Presentation Foundation (WPF) - díl 5.: Device independent pixels

Co je to DPI a proč by vás to mělo zajímat? Jak se aplikují automatické transformace při změně této hodnoty? Článek je prvním pohledem tohoto seriálu do transformací a pozičního systému WPF.

Práce s časovými pásmy a letním časem v aplikaci a databázi - díl 3.: DateTimeOffset v .NET Frameworku

DateTimeOffset je méně využívanou alternativou struktury DateTime v .NET Frameworku. Navíc dovoluje ukládat časové pásmo a pohodlně s ním pracovat.

 

 

Nový příspěvek

 

Mr.

1'

csharp|

xml|

css|


'

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Objektově orientované programování

Dobrý den,

děkuji za vhled do hodnotových a referenčních typů, je to zajímavé, jako všechno zde. V se píše, že String též referenčí typ. Analogický příklad k výše uvedenému s objekty však nefunguje:

Dim text1 As String = "David"
Dim text2 As String = "Michal"

text1 = text2
text1 &= " je kamarád. "
MsgBox(text1 & text2)

Dle výše uvedeného jsem očekával: "Michal je kamarád. Michal je kamarád. "

Dostal jsem však jen "Michal je kamarád. Michal" - Odpovídá hodnotovému typu.

Prosím kde je zakopán pes? Díky předem

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

String je opravdu referenční typ. To, co zde popisujete, je projev toho, že string je immutable, což volně přeloženo znamená "nezměnitelný".

Kód

text1 &= " je kamarád. "

ve skutečnosti nezmění string, který byl uložen v text1, ale vytvoří nový string, který přiřadí do text1. Tím vlastně v text1 změní referenci na něco jiného a tím pádem text1 a text2 ukazují každé na jiný string.

Podobně se chovají třeba i pole, jak ho jednou vytvoříte, už se nedá změnit. Jenže u polí není operátor, který by vypadal, jako že to pole mění, kdežto u stringu ano. Je to trochu matoucí.

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

Díky moc. jo jo jo - immutable - jo jo jo, není to jednoduchý, ale co, kdyby to bylo, to by byl hned každej programátor... Jen houšť, jdu na další díl... Nemůžete doporučit nějakou nejlépe čj literaturu, ve které by se všechno tohle dalo najít?

Vím, už se Vás někdo ptal dříve, ale po x letech se třeba něco nového objevilo.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Neznám, nesleduji, nemůžu doporučit.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Halvorson.M-MS Visual Basic NET Krok za krokem

Je tam toho dost, este som to necital, ale zacal som tymto webom, a co nebolo tu si chcem dostudovat v tejto knihe, vyzera tiez celkom fajn... Da sa zohnat aj na nete spolu s ukazkovymi subormi k jednotlivym lekciam...

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Diskuse: Objektově orientované programování

Dobrý den.

Při programování své aplikace objektově orientované programování nevyužívám. Při psaní aplikace postupuji tak, že si všechny procedury a funkce pro přehlednost zakládám do modulů a z třídy formuláře se pak jen při volání události odkazuji na příslušné fce a procedury. Pro usnadnění práce se snažím v maximální míře využít třídy .NET framework ale stále se jedná o strukturované programování.

Přečetl jsem si Váš článek a rád bych se zeptal na následující. Je v mém postupu programování nějaký problém, který by mi mohl později (až bude aplikace velmi rozsáhlá) způsobovat obtíže? A zda bych se místo svého postupu měl tedy radši zaměřit na objektově orientované programování a změnit přístup.

Předem děkuji za odpověď. (soft. - VB 2008 Xpress)

nahlásit spamnahlásit spam -2 / 2 odpovědětodpovědět

Diskuse: Objektově orientované programování

Dbrý den,

předem - bezva web - chci se zeptat, je možné v příkladu z1 komletně kopírovat do z2 aniž bych musel psát proceduru ?Dejme tomu , že struktura z1 obsahuje mnohem více položek a před úpravou libovolné z nich bychchtěl vyrobit něco jako zálohu

Jirka

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Tohle je velmi zajímavé téma, v nejbližších dnech na to napíšu článek na blog, mnoho lidí v tom má zmatek. Díky za námět.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Objektově orientované programování

Dobrý den, mám jenom dotaz jestli bude v brzké době další pokračování... Doufám že jo.

nahlásit spamnahlásit spam 3 / 5 odpovědětodpovědět

Diskuse: Objektově orientované programování

Děkuji za upozornění na chyby, už jsem je opravil.

nahlásit spamnahlásit spam 1 / 3 odpovědětodpovědět

Dobry , mali by ste cas a pomohli mi s jednov vecov a to : ako docielit aby sa pri spusteni aplikacie pustali nejaka mp3 , ak odburate ze kodeky su. len aby to proste pustilo mp3 . za hociaku odpoved diki

nahlásit spamnahlásit spam -2 / 2 odpovědětodpovědět

Sice to nepatří pod tento článek, ale zkuste vyhledávat DirectX nebo MP3 na tomto webu.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Objektově orientované programování

Tyhle stránky určitě někdy využiji, díky autorovi za články, měl bych takový návrh na článek: Potřeboval bych poradit s přístupem k databázi z accessu přes RDO. Ve Visual Basicu 6.0 jsem neměl s tím problém, ale teď v .netu se mi nějak nedaří ani navázat spojení. Díky, Rosz.

nahlásit spamnahlásit spam -2 / 2 odpovědětodpovědět

Diskuse: Objektově orientované programování

Zdravím, v kódu článku je malá chybička, v rozcestníku nahoře v odkazu na rozhodovací struktury je špatně vyplněn cíl odkazu.

A jak bych se zeptal k článku: zmiňuješ se o tzv. 'haldě', jaký je ekvivalent v anglické terminologii?

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Heap

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

Diskuse: Objektově orientované programování

Asi po kopírování bloku kódu a jeho následné úpravě nedošlo na změnu komentáře:

Ve třetím bloku kódu v kapitole "Hodnotové a referenční typy" je za vytvořením objektů z1 a z2:

  '******* nyní přiřadíme z2 do z1         
  z1 = z2          
  'vypíšeme vizitky obou zaměstnanců, každá bude jiná, protože každý objekt má jiné hodnoty svých vlastností         
  z1.Vizitka()         
  z2.Vizitka()

a podobně v kapitole "Předávání parametrů metodám hodnotou a referencí" po změně ByVal na ByRef zůstal komentář k přiřazení stejný

  Sub Zmen(ByRef z1 As Zamestnanec, ByVal z2 As Zamestnanec)
    z1.Vek = 13     'změna vlastnosti objektu se projeví ven         
    z1 = z2         'přiřazení do samotné proměnné ale ne, máme ByVal    
  End Sub

Jde o maličkosti, vysvětlující texty jsou perfektní. Šetřil jsem čas a procházel jen kód, tak mě komentáře trochu zmátly.

nahlásit spamnahlásit spam 1 / 3 odpovědětodpovědět

Diskuse: Objektově orientované programování

Super Tomas! Dakujem za pokracovanie tohoto serialu uz som sa bal ze serial nebude pokracovat...

Idem sa vrhnut do citania vyzera to vsetko zaujimavo...

dodo

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • 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