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

Tvorba a implementace rozhraní

Překrytí metody v odvozené třídě

Rotace rastrového obrázku

 

 

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:

 

  1. Spusťte Visual Basic .NET a přikažte vytvoření aplikace pro Windows (Windows Application).
  2. Do projektu přidejte soubor pro programový kód třídy. Vyberte nabídku Project a klepněte na položku Add Class (třídu můžete nechat implicitně pojmenovanou).
  3. Do právě vytvořeného souboru třídy zapište kód abstraktní třídy:

 

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.

  

  1. Přidejte kód pro odvozenou třídu, která dědí z abstraktní třídy:

 

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. 

   

  1. Přidejte na formulář jednu instanci ovládacího prvku Button a její událostní proceduru Click vyplňte tímto programovým kódem:

 

        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.

 

Zpět na obsah

 

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:

 

  1. Spusťte Visual Basic .NET a vytvořte aplikace pro Windows (Windows Application).
  2. Do projektu přidejte soubor pro kód třídy (nabídka Project, položka Add Class).
  3. Do třídy začleňte kód pro rozhraní:

 

 

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.

 

  1. Pokračujte zapsáním programového kódu třídy, která bude implementovat členy rozhraní:

 

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í.

 

  1. Přidejte na formulář instanci ovládacího prvku Button a do jeho událostní procedury Click napište tento kód:

 

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. 

 

Zpět na obsah

 

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.

 

  1. Spusťte Visual Basic .NET a vytvořte aplikaci pro Windows (Windows Application).
  2. Pokračujte přidáním souboru pro programový kód třídy (nabídka Project a příkaz Add Class).
  3. Do souboru třídy vložte následující kód pro definici bázové a odvozené třídy:

 

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ě.

 

  1. Na formulář umístěte jednu instanci ovládacího prvku Button a do události Click instance přidejte tento kó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

 

Zpět na obsah

 

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:

 

  1. Na formulář umístěte instanci ovládacího prvku PictureBox, kterou nechejte implicitně pojmenovanou (PictureBox1).
  2. Na plochu formuláře nakreslete dvě instance ovládacího prvku Button, které pojmenujte jako btnNačístObrázek a btnRotovat. 
  3. Vlastnost Text prvního tlačítka změňte na „Načíst obrázek“.
  4. Vlastnost Text druhého tlačítka změňte na „Rotovat“.
  5. Do událostní procedury Click tlačítka btnNačístObrázek vepište tento fragment programového kódu:

 

        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. 

 

  1. Do událostní procedury Click tlačítka btnRotovat zadejte tento zdrojový kód:

 

        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

 

Zpět na obsah

 

 

Ján Hanák