IntegrovanΘ prost°edφ rubriky Visual Basic |
|||||||
|
Programßtorskß laborato° |
||||||
Prostor pro experimentovßnφ |
|||||||
╚asovß nßroΦnost (min): 85 |
ZaΦßteΦnφk |
PokroΦil² |
Profesionßl |
||||
|
|
|
|||||
|
Pou₧it² operaΦnφ systΘm : Hlavnφ v²vojov²
nßstroj : DalÜφ v²vojov² software : Jin² software : |
Windows 2000 SP3 Visual Basic .NET 2002 Äßdn² Äßdn² |
|||||
|
|
|
||
|
|
||
|
|
||
|
|
Tvorba abstraktnφ t°φdy
Jednou z v²znamn²ch vlastnostφ, kterΘ spadajφ do oblasti objektov∞ orientovanΘho programovßnφ ve Visual Basicu .NET, je tvorba abstraktnφch t°φd. Hned na zaΦßtek si ovÜem musφme °φci, ₧e psanφ abstraktnφch t°φd nepat°φ zrovna mezi b∞₧nΘ ·koly programßtora ve VB .NET. Na druhou stranu, pochopenφ principu, na n∞m₧ spoΦφvajφ zßklady tematiky abstraktnφch t°φd, vßs katapultuje do vyÜÜφch ·rovnφ hry, kterΘ se °φkß profesionßlnφ programovßnφ.
Abstraktnφ t°φdy jsou t°φdy, kterΘ nejsou urΦeny pro p°φmou tvorbou objekt∙ jistΘho typu. Znamenß to, ₧e abstraktnφ t°φda nem∙₧e slou₧it jako ätovßrna na objektyô. Ve skuteΦnosti zastßvß abstraktnφ t°φda pozici bßzovΘ t°φdy, ze kterΘ mohou jinΘ t°φdy d∞dit veÜkerou funkcionalitu. OvÜem v²raz, ₧e jinΘ t°φdy m∙₧ou d∞dit z abstraktnφ t°φdy, je pon∞kud slab². SkuteΦnost je takovß, ₧e jinΘ t°φdy musφ d∞dit z abstraktnφ t°φdy. Tato vskutku fundamentßlnφ vlastnost abstraktnφ t°φdy je umocn∞na pou₧itφm klφΦovΘho slova MustInherit v deklaraci abstraktnφ t°φdy. I kdy₧ abstraktnφ t°φda m∙₧e obsahovat definice Φlensk²ch funkcφ a procedur, obvykle jsou v abstraktnφ t°φdy uvedeny pouze deklarace t∞chto entit. Kdy₧ vychßzφme ze skuteΦnosti, ₧e abstraktnφ t°φdou nelze p°φmo pou₧φt pro tvorbu objekt∙, je toto chovßnφ pochopitelnΘ. V praxi se zvyΦejn∞ postupuje tak, ₧e do abstraktnφ t°φdy se umφstφ pouze deklarace Φlen∙ t°φdy, a konkrΘtnφ implementace t∞chto Φlen∙ je nßsledn∞ ponechßna na odvozenΘ t°φd∞. Jestli₧e ji₧ netrp∞liv∞ Φekßte na ukßzku abstraktnφ t°φdy, nebudu vßs dßle napφnat. V nßsledujφcφ p°φpadovΘ studii si ukß₧eme, jak zhotovit jednoduchou abstraktnφ t°φdu. Postupujte takto:
Public MustInherit Class A
ááá Public
MustOverride Sub
Vytvo°itFormulß°()
End Class
Jak jsme si ji₧ °ekli, v deklaraci abstraktnφ t°φdy se musφ nachßzet klφΦovΘ slovo MustInherit, kterΘ indikuje, ₧e tato t°φda je urΦena pouze pro tvorbu z nφ odvozen²ch podt°φd. V t∞le abstraktnφ t°φdy se nachßzφ deklarace jednoho abstraktnφho Φlenu tΘto t°φdy. P°esn∞ji jde o deklaraci procedury Sub s nßzvem Vytvo°itFormulß°. Jak m∙₧ete vid∞t, v deklaraci ΦlenskΘ procedury se nachßzφ klφΦovΘ slovo MustOverride, kterΘ °φkß, ₧e jeÜt∞ p°edtφm, ne₧ bude tato procedura pou₧ita, musφ b²t p°ekryta v k≤du odvozenΘ t°φdy. P°i deklaraci ΦlenskΘ procedury v abstraktnφ t°φd∞ je zapot°ebφ urΦit jenom indikßtor p°φstupu (Public), klφΦovΘ slovo MustOverride a jmΘno procedury (Vytvo°itFormulß°), kterΘ je nßsledovßno zßvorkami (v tomto p°φpad∞ prßzdn²mi). Pokud byste cht∞li, nic vßm nebrßnφ v tom, abyste p°idali vlastnφ parametry s p°φsluÜn²mi datov²mi typy a nßvratovou hodnotu (v p°φpad∞ deklarace funkce).
|
Proceduru typu Sub m∙₧ete snadno äp°ed∞latô na funkci nahrazenφ
klφΦovΘho slova Sub v deklaraci klφΦov²m slovem Function. Pokud
se rozhodnete implementovat funkci, nezapome≥te takΘ °ßdn∞ specifikovat jejφ nßvratovou
hodnotu. |
áá
Public Class B
ááá Inherits
A
ááá Public
Overrides Sub
Vytvo°itFormulß°()
ááááááá Dim
frm As New Form()
ááááááá With
frm
ááááááááááá .Text = "Formulß° Φ. 1"
áááá ááááááá.Show()
ááááááá End
With
ááá End
Sub
End Class
SkuteΦnost, ₧e t°φda B je odvozenß do abstraktnφ t°φdy A, demonstruje p°φkaz Inherits. Proto₧e abstraktnφ t°φda nabφzφ jenom deklaraci ΦlenskΘ procedury, le₧φ povinnost jejφ implementace na bedrech odvozenΘ t°φdy. Odvozenß t°φda B se tedy tΘto ·lohy musφ cht∞-necht∞ zhostit, a proto p°ekryje proceduru z abstraktnφ t°φdy A. Aby bylo na prvnφ pohled jasnΘ, ₧e procedura p°ekr²vß proceduru z abstraktnφ t°φdy, je do deklarace p°ekrytΘ procedury vlo₧eno klφΦovΘ slovo Overrides. V t∞le p°ekrytΘ procedury je vytvo°ena novß instance t°φdy Form, kterΘ je p°i°azen text, jen₧ se bude zobrazovat v titulkovΘm pruhu okna instance a tato instance je poslΘze zobrazena.
|
Mo₧nß se divφte, jak m∙₧e b²t vytvo°en objekt t°φdy Form, kdy₧ ani jedna ze t°φd ned∞dφ z t°φdy System.Windows.Forms.Form.
Fφgl spoΦφvß v tom, ₧e vaÜe odvozenß t°φda vφ o t°φd∞ Form, a
takΘ vφ, kde se tßto t°φda nachßzφ. ╪ekne jφ to toti₧ Visual Basic .NET,
proto₧e odkaz na vzpomφnanou t°φdu se nachßzφ v sekci odkaz∙ (References)
v okn∞ Solution Explorer.á |
ááá
ááááááá Dim
ObjektovßProm∞nnß As New B()
áááá ObjektovßProm∞nnß.Vytvo°itFormulß°()
Jestli₧e spustφte aplikaci a klepn∞te na tlaΦφtko, zobrazφ se nov² formulß° s p°edem urΦen²m textem v titulkovΘm pruhu.
Tvorba a implementace
rozhranφ
Ve sv∞t∞, v n∞m₧ vlßdnou objekty, je velmi d∙le₧itΘ, aby se tyto objekty dokßzali mezi sebou domluvit. Aby ovÜem bylo mo₧nΘ uskuteΦnit v∙bec n∞jakou konverzaci mezi objekty, musφ nejprve existovat jist² protokol, neboli rozhranφ, kterΘ umo₧nφ p°istupovat k metodßm a vlastnostem objekt∙. Pod pojmem rozhranφ si tedy m∙₧ete p°edstavit jistou smlouvu, nebo dohodu, kterß °φkß, jak bude uskuteΦ≥ovßn komunikaΦnφ proces mezi objekty. Jestli₧e jste pou₧φvali ni₧Üφ verze Visual Basicu, mohli jste rozhranφ pou₧φvat, ovÜem jejich tvorba byla sv∞°ena jin²m programovacφm jazyk∙m (p°edevÜφm Visual C++). S p°φchodem .NET verze jazyka Visual Basic se situace radikßln∞ zm∞nila, a proto se i my m∙₧eme t∞Üit na programovanφ rozhranφ.
Z technickΘho hlediska je rozhranφ ryzφ informaΦnφ protokol, kter² mß jistΘ charakteristiky spoleΦnΘ s tvorbou abstraktnφ t°φdy. Rozhranφ se deklaruje p°φkazem Interface a v t∞le tohoto p°φkazu se uvßd∞jφ prototypy pot°ebn²ch procedur, funkcφ, vlastnostφ a udßlostφ, kterΘ mß rozhranφ podporovat. Prototypem se rozumφ pouze specifikace Φlenu rozhranφ, jeho jmΘna, signatury a nßvratovΘ hodnoty (jestli₧e je zapot°ebφ). Je velmi d∙le₧itΘ si uv∞domit, ₧e definice rozhranφ poz∙stßvß jenom z uveden²ch prototyp∙ Φlen∙. VeÜkerß implementace Φlen∙ rozhranφ je (op∞t podobn∞ jako u abstraktnφch t°φd) p°enesena do t°φdy, kterß bude uvedenΘ rozhranφ implementovat. ZjednoduÜen∞ by se dalo °φct, ₧e rozhranφ definuje pouze to, äco se mß ud∞latô a implementaΦnφ t°φda zase na°izuje äjak se to mß ud∞latô.
Aby ovÜem nez∙stalo jen u teorie, pokusφme se sestavit rozhranφ, potΘ jej implementovat a vyu₧φt ve t°φd∞. Zde jsou vÜechny pot°ebnΘ instrukce:
á
Public Interface
IRozhranφ
ááá Sub
SpustitProgram(ByVal JmΘnoProgramu As String)
ááá ReadOnly
Property ZjistitIDProcesu()
End Interface
Rozhranφ je definovßno mezi p°φkazy Interface a End Interface. P°φkazu Interface p°edchßzφ urΦenφ modifikßtoru p°φstupu (Public). Rozhranφ je v naÜem p°φpad∞ ve°ejnΘ, je tedy p°φstupnΘ v rßmci celΘho projektu. Za p°φkazem Interface nßsleduje jmΘno rozhranφ a podle konvenceá zaΦφnß toto jmΘno na pφsmeno äIô. V t∞le rozhranφ se nachßzejφ deklarace Φlen∙ rozhranφ, kterΘ majφ stejnou ·rove≥ p°φstupu jako celΘ rozhranφ (Public). M∙₧ete zde vid∞t jednu Sub proceduru s nßzvem SpustitProgram, kterß pracuje s jednφm parametrem typu String s nßzvem JmΘnoProgramu. DalÜφm Φlenem je vlastnost ZjistitIDProcesu, kterß je urΦena jenom pro Φtenφ, co₧ indikuje pou₧itφ klφΦovΘho slova ReadOnly.
Public Class C
ááá Implements
IRozhranφ
ááá Dim
m_Proces_ID As Integer
ááá Public
Sub SpustitProgram(ByVal
JmΘnoProgramu As String)
_
ááá Implements
IRozhranφ.SpustitProgram
ááááááá Dim
proc As New
Process()
ááááááá With
proc
ááááááááááá .StartInfo.FileName
= JmΘnoProgramu
ááááááááááá .Start()
ááááááá End
With
ááááááá m_Proces_ID
= proc.Id
ááá End
Sub
ááá Public
ReadOnly Property
ZjistitIDProcesu() _
ááá Implements
IRozhranφ.ZjistitIDProcesu
ááááááá Get
ááááááááááá Return
m_Proces_ID
ááááááá End
Get
ááá End
Property
End Class
Zde vidφte v²pis k≤du pro t°φdu C. Ihned za deklaraΦnφm p°φkazem t°φdy se nachßzφ p°φkaz Implements s nßzvem rozhranφ pro implementaci. P°φkaz Implements determinuje, ₧e t°φda C bude podporovat rozhranφ IRozhranφ a je nutnΘ, aby t°φda definovala vÜechny Φleny rozhranφ. To t°φda C takΘ na nßsledujφcφch °ßdcφch d∞lß. Nejd°φv je pln∞ implementovßna Sub procedura SpustitProgram. VÜimn∞te si prosφm, ₧e za signaturou procedury SpustitProgram je op∞t uveden p°φkaz Implements, za kter²m je uveden Φlen rozhranφ, kter² je prost°ednictvφm procedury implementovßn. V rßmci procedury je vytvo°ena instance t°φdy Process s nßzvem proc. JmΘno programu, jen₧ se bude spouÜt∞t je ulo₧eno do vlastnosti Filename. B∞h k≤du pokraΦuje zavolßnφm metody Start, kterß zabezpeΦφ spuÜt∞nφ specifikovanΘho souboru.
Implementovßna je i vlastnost ZjistitIDProcesu, kterß vracφ identifikaΦnφ Φφslo spuÜt∞nΘho procesu. Op∞t si vÜimn∞te, ₧e je pot°ebnΘ zapsat p°φkaz Implements za jmΘno vlastnosti a urΦit odpovφdajφcφ prot∞jÜek z definice rozhranφ.
Dim x As New C()
x.SpustitProgram("Notepad.exe")
Me.Text = "ID procesu: " & x.ZjistitIDProcesu
áááááááá
Tento k≤d vytvß°φ objektovou prom∞nnou x, kterß obsahuje referenci na instanci t°φdy C. Ve druhΘm kroku je zavolßna metoda SpustitProgram, kterΘ je p°edßn nßzev programu, jen₧ se mß spustit. Poslednφ p°φkaz zobrazuje identifikaΦnφ k≤d prßv∞ spuÜt∞nΘho programu (procesu) v titulkovΘm pruhu testovacφ aplikace.á
P°ekrytφ metody v odvozenΘ t°φd∞
V tomto tipu si ukß₧eme, jak p°ekr²t metodu bßzovΘ t°φdy v odvozenΘ t°φd∞. ZaΦneme vÜak zvolna a vysv∞tlφme si, co se pod pojmem p°ekr²vßnφ metod ve skuteΦnosti rozumφ. Proces p°ekr²vßnφ metod nenφ ve sv∞t∞ programovßnφ nijak nov², ostatn∞ mnohΘ jazyky, nap°φklad C++, jej pou₧φvajφ ji₧ n∞jak² ten pßtek. Hlavnφ myÜlenka je takovßto: Pomocφ p°ekr²vßnφ metod m∙₧ete jednoduÜe nahradit metodu bßzovΘ t°φdy svou vlastnφ metodou, kterß m∙₧e mφt zcela jinou implementaci. Jak je jist∞ patrnΘ, proces p°ekr²vßnφ metod je velice ·zce spjat s procesem d∞d∞nφ. P°edstavte si nßsledujφcφ p°φklad: Mßte dv∞ t°φdy, jednu bßzovou a druhou odvozenou z bßzovΘ t°φdy. S funkcionalitou bßzovΘ t°φdy jste vcelku spokojeni, ovÜem p°ßli byste si, aby n∞kolik metod bßzovΘ t°φdy disponovalo nov∞jÜφ stavbou programovΘho k≤du, a zajiÜ¥ovalo lepÜφ funkcionalitu. Pokud se n∞kdy dostanete do podobnΘ situace, urΦit∞ p°ivφtßte pomocnou ruku, kterou vßm mechanizmus p°ekr²vßnφ metod m∙₧e nabφdnout. V²sledkem bude jednoduÜe p°ekrytφ metody bßzovΘ t°φdy (programov² k≤d p°ekrytΘ metody bude zcela jin² a bude tak poskytovat modifikovanou funkcionalitu).
|
P°i p°ekr²vßnφ metody ovÜem nesmφte zapomenout na skuteΦnost, ₧e novß
implementace metody musφ mφt stejn² modifikßtor p°φstupu, nßzev a rovn∞₧ tak
i stejnou signaturu jako metoda, kterou se chystßte p°ekr²t.á |
P°ekr²vßnφ metody v odvozenΘ t°φd∞ si budeme demonstrovat na nßsledujφcφ programovΘ ukßzce.
Public Class BßzovßT°φda
ááá Public
Overridable Sub Zobrazit╚as()
ááááááá MessageBox.Show("Prßv∞ te∩ je " & _
ááááááá DateTime.Now.TimeOfDay.Hours
& _
ááááááá " hodin.")
ááá End
Sub
End Class
Public Class OdvozenßT°φda
ááá Inherits
BßzovßT°φda
ááá Public
Overrides Sub
Zobrazit╚as()
ááááááá Form.ActiveForm.Text
= "Prßv∞ te∩ je "
& _
ááááááá DateTime.Now.TimeOfDay.Hours
& " hodin."
ááá End
Sub
End Class
P°edm∞tem naÜeho zßjmu je procedura Zobrazit╚as. Tato procedura je v bßzovΘ t°φd∞ definovßna s klφΦov²m slovem Overridable, kterΘ z procedury d∞lß vhodnΘho kandidßta pro pozd∞jÜφ p°ekrytφ. Mimochodem, metoda Zobrazit╚as v bßzovΘ t°φd∞ je zodpov∞dnß za zobrazenφ dialogovΘho okna s poΦtem uplynul²ch hodin dne.
T°φda s nßzvem OdvozenßT°φda d∞dφ svou funkcionalitu z bßzovΘ t°φdy. I v tΘto t°φd∞ se nachßzφ k≤d s metodou Zobrazit╚as, ovÜem jak si m∙₧ete vÜimnout, tato metoda:
╖ je deklarovßna s pou₧itφm klφΦovΘho slova Overrides,
╖ provßdφ jinou Φinnost ne₧li jejφ p°edch∙dkyn∞ v bßzovΘ t°φd∞ (zobrazuje poΦet hodin v titulkovΘm pruhu aktivnφho formulß°e),
╖ mß stejn² modifikßtor p°φstupu (Public), nßzev (Zobrazit╚as) i signaturu.
M∙₧eme prohlßsit, ₧e metoda Zobrazit╚as v odvozenΘ t°φd∞ p°ekr²vß metodu Zobrazit╚as v bßzovΘ t°φd∞.
ááááááá Dim obj As New OdvozenßT°φda()
ááááááá obj.Zobrazit╚as()
ááá
áááá V²sledek m∙₧ete vid∞t na obr. 1.
Obr. 1 û Zavolßnφ p°ekrytΘ metody
z odvozenΘ t°φdy
Rotace rastrovΘho obrßzku
Programßto°i grafick²ch aplikacφ se zcela urΦit∞ nezaobejdou bez techniky rotovßnφ rastrov²ch obrßzk∙. Dobrou zprßvou je, ₧e platforma .NET poskytuje mno₧stvφ t°φd, kterΘ vßm mohou p°i programovßnφ r∙zn²ch grafick²ch efekt∙ v mnohΘm pomoci. My se nynφ podφvßme na to, jak rotovat jednoduch²m rastrov²m obrßzkem, jen₧ je ulo₧en ve formßtu GIF. Budeme postupovat takto:
ááááááá With
PictureBox1
ááááááááááá .BorderStyle = BorderStyle.FixedSingle
ááááááááááá .SizeMode = PictureBoxSizeMode.CenterImage
ááááááááááá .Image = Image.FromFile("D:\obr1.gif")
ááááááá End With
Aby m∞l ovlßdacφ prvek PictureBox1 vizußln∞ ohraniΦenou plochu, upravφme jeho vlastnost BorderStyle na hodnotu FixedSingle. Dßle je nastavena vlastnost SizeMode na hodnotu CenterImage, co₧ znamenß, ₧e obrßzek, jen₧ bude vykreslen na ploÜe tohoto ovlßdacφho prvku, bude okam₧it∞ vycentrovßn horizontßln∞ i vertikßln∞. V dalÜφ etap∞ je do vlastnosti Image ovlßdacφho prvku PictureBox1 umφst∞na reference na objekt Image, kter² je tvo°en rastrov²m obrßzkem naΦten²m z p°edem p°ipravenΘho grafickΘho souboru.á
ááááááá Dim g As Image = PictureBox1.Image
ááááááá g.RotateFlip(RotateFlipType.Rotate270FlipNone)
ááááááá PictureBox1.Refresh()
áááááááá Zde jsou realizovßny tyto ·kony:
áááááááá
╖
je
vytvo°ena objektovß prom∞nnß g, do kterΘ je ulo₧ena
reference na objekt s rastrov²m obrßzkem (tato reference je zφskßna z vlastnosti
Image ovlßdacφho prvku PictureBox1),
╖ je pou₧ita metoda RotateFlip, kterß provede rotaci obrßzku o 270 stup≥∙,
╖ je p°ekreslena plocha ovlßdacφho prvku PictureBox1 pou₧itφm metody Refresh.
NaΦten² obrßzek a jeho modifikovanou verzi m∙₧ete vid∞t na obr. 2.
Obr. 2 û Rotace rastrovΘho
obrßzku
Jßn Hanßk