Objektov↓ orientovan← programov£n
Transkript
OBCHODNÍ AKADEMIE ORLOVÁ STŘEDNÍ ODBORNÁ ŠKOLA BLATNÁ OBJEKTOVĚ ORIENTOVANÉ PROGRAMOVÁNÍ UČEBNÍ TEXT PRO DISTANČNÍ FORMU VZDĚLÁVÁNÍ MGR. PAVEL KOZLOVSKÝ ORLOVÁ 2006 Objektově orientované programování - Studijní opora 1 Cíle předmětu Po prostudování textu budete znát: Základy objektově orientovaného programování. Základní ovládací prvky a jejich vlastnosti. Získáte: Představu, jak fungují windowsové aplikace. Posílíte si svůj orientační smysl při bloudění v rozsáhlém zdrojovém textu Budete schopni: Pochopit kód jednoduché aplikace. Navrhnout grafický design aplikace. Samostatně provést drobná vylepšení. Čas potřebný k prostudování učiva předmětu: ,- hodin Objektově orientované programování - Studijní opora 2 Obsah Předmluva Kapitola /. První program Kapitola 0. Vizuální vývojové prostředí Kapitola 2. Syntaktická gramatika Kapitola 3. Vlastnosti formuláře Kapitola -. Události formuláře Kapitola ,. Ovládací prvky Kapitola 6. Jednoduchá kalkulačka Kapitola 8. Deklarace datových typů Kapitola :. Deklarace členů Závěr Příloha A: Lexikální gramatika Příloha B: Unicode Příloha C: Datové typy Příloha D: Příkazy Příloha E: Výrazy Objektově orientované programování - Studijní opora 3 Předmluva Studijní opora Objektově orientované programování vznikla v létě roku 0AA, na základě zkušeností z výuky programování na Střední odborné škole v Blatné. Přestože text je primárně určen pro distanční formu vzdělávání, je možné jej využít i jako učebnici pro denní studium nebo dokonce samostudium. Cílem tohoto textu je seznámit čtenáře se základy objektově orientovaného programování prostřednictvím jednoduchých aplikací. Ačkoliv základní principy a programovací techniky jsou obecně platné, nelze se vyhnout volbě konkrétní platformy a programovacího jazyka. Bez této volby by byl text příliš abstraktní a odtažený od praxe. Původním záměrem bylo zahrnout do textu více jazyků případně platforem, ale ukázalo se, že rozsah vytvořené opory je i bez toho značný. Bylo tedy nutné vybrat jen jednu platformu a jen jeden jazyk. Volba jazyka Volba celkem logicky padla na technologie používané na Střední odborné škole v Blatné. Vzhledem k dominantní pozici operačního systému Microsoft Windows na trhu není možné tento systém vynechat. Nativním objektově orientovaným aplikačním rozhraním tohoto systému je Microsoft .NET Framework, který byl zvolen jako platforma pro výuku programování. Platforma .NET Framework umožňuje použití různých programovacích jazyků. Základním jazykem je C#, který byl zvolen jako jazyk pro výuku programování. Jazyk C# je následovníkem jazyků C a C++, do kterého je zabudována řada dobrých věcí z Javy a Visual Basicu. Jazyk C++ je v praxi velmi rozšířen, ale není vhodný pro začátečníky, protože je nutné zvládnout poměrně složitou práci s ukazateli. V jazyce C# jsou ukazatele skryty. Navíc má C# silnější typovou kontrolu. Dalším v praxi velmi rozšířeným jazykem je Visual Basic. Jeho velkou slabinou je příliš silná vazba na platformu Windows. Jazyk Pascal je velmi rozšířen v akademickém prostředí. Často je zvolen jako první jazyk pro výuku programování. Proti hovoří složitější možnost přeškolení se na v praxi užívané jazyky C++ a Java. Java je asi jedinou smysluplnou alternativou, která přichází v úvahu. Je to zárověň jazyk i platforma. V praxi je značně rozšířena. Jazyky Java a C# jsou si velmi blízké, takže přeškolení z jednoho na druhý by nemělo činit větší potíže. Zbývá snad ještě krátká zmínka o JavaScriptu, který se hojně používá na webových stránkách. Přechod na JavaScript z Javy nebo ze C# je snadný. JavaScript ale nemá typovou kontrolu, což vede zvláště u začátečníků k těžko odhalitelným chybám. Zvolený jazyk C# je tedy v praxi rozšířený, objektově orientovaný jazyk s dostatečně silnou typovou kontrolou, který je vhodný i pro začínající programátory. Protože s velmi rozšířenými jazyky C++ a Java má společný základ v jazyce C, je značně usnadněn případný pozdější přechod tyto jazyky. Co je třeba znát Tento studijní text není určen k výuce základů programování. Je tedy vhodný pro čtenáře, kteří již něco sami naprogramovali. Studijní opora Objektově orientované programování přímo navazuje na studijní opory Algoritmizace a Programování. Studium této opory lze tedy doporučit až po prostudování předchozích dvou. Protože výklad a příklady jsou založeny na jazyce C#, bylo by dobré znát základy tohoto jazyka. Jenže v předchozích oporách je použit jazyk Pascal. Proto tato opora obsahuje poměrně rozsáhlé přílohy, které shrnují základy jazyka C#. Je samozřejmě možné využít i velmi rozsáhlou originální anglickou dokumentaci (v elektronické formě a na webu) nebo českou odbornou literaturu (viz seznam doporučené literatury). Dále se předpokládají znalosti z Úvodu do výpočetní techniky, zejména uživatelského rozhraní windowsových aplikací, a základů matematiky (logika, množiny). Objektově orientované programování - Studijní opora 4 Protože vývojářské nástroje jsou v drtivé většině v angličtině, je znalost angličtiny alespoň na úrovni čtení odborného textu nutná a předpokládá se. Odborná slovní zásoba je v textu vyznačena včetně výslovnosti a na konci publikace je zařazen oboustranný slovníček. Kapitoly Kapitola První program obsahuje stručný návod jak ze zdrojového kódu přeložit windowsovou aplikaci, jak nastavit vlastnosti aplikace a vlastnosti okna. Závěr kapitoly je věnován tomu, jak změnit barvu okna po kliknutí myší. Vizuální vývojové prostředí je popsáno v druhé kapitole. Na příkladu z předchozí kapitoly je ukázáno jak lze totéž udělat mnohem pohodlněji, máme-li k dispozici pořádné nářadí. Kapitola končí porovnáním ručně psaného kódu z první kapitoly a kódu, který vygenerovalo vývojové prostředí. Třetí kapitola se zabývá výkladem syntaktické gramatiky jazyka C#. Popisuje obecnou strukturu zdrojového kódu zejména pak jaké datové typy lze deklarovat a jak s pomocí jmenných prostorů zabránit duplicitě v pojmenování různých typů. Kapitola Vlastnosti formuláře uvádí přehled základních vlastností okna, které lze nastavit. Kromě velikosti a barvy známé již z první kapitoly jsou vysvětleny kurzory, ikony, tlačítka a mnohé další. Pravá aplikace však vznikne až přidáním reakcí na události, jejichž popisem se zabývá další kapitola. Od jednoduchých událostí typu myšího kliknutí nebo stisku klávesy až po změnu klávesnice a kreslení. Důležitou součástí aplikací jsou ovládací prvky. Těm je věnována další kapitola. Namátkou uveďme tlačítko, textové pole, zaškrtávací políčko. Součástí kapitoly je opět ukázka toho, jak vizuální vývojové prostředí zrychluje práci. Trošku rozsáhlejší aplikace je uvedena v kapitole Jednoduchá kalkulačka. Zdrojový kód je bohatě okomentován a části kódu jsou následujících kapitolách k výkladu pojmů. Deklarace datových typů jsou popsány ve stejnojmenné kapitole vysvětlující mimo jiné pojmy třída, rozhraní, dědičnost a zapouzdření. Závěrečná kapitola Deklarace členů popisuje zejména deklaraci vnitřních proměnných (polí) a metod. V této kapitole je vysvětlen podstatný rozdíl mezi objektovou a neobjektovou technologií tvorby programů. Následuje podrobný popis vlastností a událostí. V pojednání o objektově orientovaném programování nemůže chybět ani zmínka o virtuálních metodách. Přílohy Protože nelze předpokládat znalost jazyka C# a dostupnost vhodné literatury, je tato studijní opora doplněna velmi rozsáhlými přílohami. V příloze A je popsána lexikální gramatika jazyka C#, čili pravidla, jak se ze znaků skládají tokeny. Klasifikace znaků sady Unicode je předmětem přílohy B. Důležité jsou i zde uvedené anglické názvy znaků, které se často vyskytují v chybových hlášeních překladače. Praktickou informací je i to, jak některé znaky napsat na klávesnici. Problematika datových typů by si zasloužila podstatně větší prostor, ale protože jde víceméně o opakování známých věcí, je soustředěna do přílohy C. Příloha D by též vydala na samostatnou publikaci. Pojednává o příkazech. Nejsou zde však vůbec vysvětlovány, protože se předpokládá, že čtenář již tyto příkazy zná byť v jiném programovacím jazyce. Příloha je tedy koncipována jako stručný přehled toho, jak se příkazy zapisují v C#. Naprosto totéž lze říci i o příloze E zabývající se výrazy. Objektově orientované programování - Studijní opora 5 Poděkování Rád bych na tomto místě poděkoval ing. Šromkové, RNDr. Štěrbové a dalším kolegům z Obchodní akademie v Orlové za ohromný kus práce, který odvedli v rámci projektu jehož součástí je i tvorba této studijní opory. Dále chci poděkovat RNDr. Nagyové z Ostravské univerzity za cenné připomínky a rady při tvorbě tohoto textu. Velký dík patří i studentům Střední odborné školy v Blatné za jejich trpělivost při hodinách, na kterých často zakusili na vlastní kůži části (a ne vždy zcela připravené) této studijní opory. Svými dotazy a nápady však přispěli velkou měrou k tomuto dílu, proto jim ještě jednou děkuji. Poděkování patří i vedení Střední odborné školy v Blatné v čele s RNDr. Pavlíkem za vstřícný přístup, kdykoliv ho bylo zapotřebí. V neposlední řadě děkuji své ženě a dětem za podporu po celou dobu tvorby opory. Bez jejich ochoty snášet moje ne vždy příjemné nálady během dlouhého vysedávání u počítače by tato publikace nikdy nevznikla. Pavel Kozlovský Objektově orientované programování - Studijní opora 6 Kapitola B. První program V této kapitole se dozvíte: Jak napsat zdrojový kód jednoduchého programu. Jak nastavení je třeba k tomy, aby šel program snadno přeložit. Jak nastavit barvu okna. Jak změnit barvu při kliknutí myší. Klíčová slova této kapitoly: Zdrojový kód, překlad, okno, barva, klik. Čas potřebný k prostudování učiva kapitoly: - hodin Průvodce studiem. Vítejte ve světě objektů, vlastností, událostí a metod. Vítejte ve světě tříd a rozhraní. Vítejte ve světě objektově orientovaného programování. Při letmém pohledu se Vám může zdát, že je to svět velmi jednotvárný − vše na co narazíte je objekt. Ale zadíváte-li se pozorněji, zjistíte, že tyto objekty se seskupují do velmi rozmanitých tříd, kterými lze ve virtuální realitě počítačového světa modelovat téměř cokoliv ze světa reálného. Vstupní branou do světa objektově orientovaného programování je dobře nainstalovaný počítač s patřičnými vývojářskými nástroji. Tím nejjednošším nástrojem je editor obyčejného textu − bohatě postačí poznámkový blok − a překladač. Přeji Vám, aby technických komplikací během tvorby Vašeho prvního objektově orientovaného programu bylo co nejméně. Vytvoření zdrojového kódu Programy vznikají překladem zdrojových kódů. Vytvoříme si zdrojový soubor PrvniProgram.cs s následujícím obsahem: [assembly: System.Reflection.AssemblyTitle("První program určený pro výuku programování."), System.Reflection.AssemblyVersion("M.1.0.0"), System.Reflection.AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), System.Reflection.AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.PrvniProgram { public static class Program { public static void Main() { System.Windows.Forms.Application.Run(new PrvniOkno()); } } public class PrvniOkno: System.Windows.Forms.Form { } } Objektově orientované programování - Studijní opora 7 Akce Přeložit Protože překladač budeme spouštět často a příkaz pro jeho spuštění je poměrně komplikovaný, usnadníme si budoucí práci nastavením akce Přeložit pro soubory s příponou .cs. V možnostech složky vybereme soubory s příponou .cs a stiskeneme tlačítko Upřesnit: V okně Upravit typ souboru přidáme novou akci tlačítkem Nová: Akci pojmenujeme „Přeložit“ a do pole „Aplikace použitá k provedení akce“ napíšeme: C:\WINDOWS\Microsoft.NET\Framework\vZ.0.5M\Z\\csc.exe /t:winexe /out:"%B.exe" "%B" /bugreport:"%B.log" Umístění překladače csc.exe se může na Vašem počítači lišit, zejména v čísle verze .NET Frameworku. Není-li na Vašem počítači soubor csc.exe, je velmi pravděpodobně třeba doinstalovat .NET Framework. Objektově orientované programování - Studijní opora 8 Přidání akce Přeložit dokončíme stiskem tlačítka OK: Překlad Z místní nabídky zdrojového souboru (vyvolané pravým tlačítkem myši) spustíme překlad položkou Přeložit: Překlad dokončíme dvojím stisknutím klávesy Enter: Objektově orientované programování - Studijní opora 9 Po překladu vznikne protokol o překladu v souboru s příponou .log a, je-li to možné, spustitelný soubor s příponou .exe: Průvodce studiem. Povedlo se Vám to? Věřím, že ano. Ale jestli přece jenom ne, nezoufejte. Ve hře je toho příliš mnoho a záleží opravdu na každé maličkosti. Jen jedna zapomenutá čárka nebo třeba tečka napsaná místo středníku dokáže vše pokazit. Podívejte se do protokolu a určitě najdete v čem je problém. Objektově orientované programování - Studijní opora 10 Protokol Protokol obsahuje informace o verzi překladače a .NET Frameworku, parametry z příkazové řádky, včetně seznamu automaticky používaných .dll knihoven. Dále obsahuje zdrojový kód a případná chybová hlášení překladače. Protokol může vypadat například takto: ### Visual C# ZMM` Compiler Defect Report, created MQ/Ba/Mb B`:`Q:c` ### Compiler version: a.0M.5M\Z\.4Z ### .NET common language runtime version: Z.0.5M\Z\ ### Operating System: Windows NT `.1.2bMM ### Console and Defect Report Code Page: a`Z ### Compiler command line /r:Accessibility.dll /r:Microsoft.Vsa.dll /r:System.Configuration.dll /r:System.Configuration.Install.dll /r:System.Data.dll /r:System.Data.OracleClient.dll /r:System.Data.SqlXml.dll /r:System.Deployment.dll /r:System.Design.dll /r:System.DirectoryServices.dll /r:System.dll /r:System.Drawing.Design.dll /r:System.Drawing.dll /r:System.EnterpriseServices.dll /r:System.Management.dll /r:System.Messaging.dll /r:System.Runtime.Remoting.dll /r:System.Runtime.Serialization.Formatters.Soap.dll /r:System.Security.dll /r:System.ServiceProcess.dll /r:System.Transactions.dll /r:System.Web.dll /r:System.Web.Mobile.dll /r:System.Web.RegularExpressions.dll /r:System.Web.Services.dll /r:System.Windows.Forms.Dll /r:System.Xml.dll /t:winexe /out:"C:\Documents and Settings\Pavel\Dokumenty\csharp\PrvniProgram.cs.exe" C:\Documents and Settings\Pavel\Dokumenty\csharp\PrvniProgram.cs ### Source file: 'c:\Documents and Settings\Pavel\Dokumenty\csharp\PrvniProgram.cs' [assembly: System.Reflection.AssemblyTitle("První program určený pro výuku programování."), System.Reflection.AssemblyVersion("M.1.0.0"), System.Reflection.AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), System.Reflection.AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.PrvniProgram { public static class Program { public static void Main() { System.Windows.Forms.Application.Run(new prvniOkno()); } } class prvniOkno: System.Windows.Forms.Form { } } ### User description ### User suggested correct behavior Spustitelný soubor (.exe) Vzniklý .exe soubor je možné spouštět jen na počítačích s naistalovaným .NET Frameworkem. Vlastnosti aplikace, byly zadány pomocí atributů ve zdrojovém kódu: [assembly: System.Reflection.AssemblyTitle("První program určený pro výuku programování."), System.Reflection.AssemblyVersion("M.1.0.0"), System.Reflection.AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), System.Reflection.AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena."), ] Objektově orientované programování - Studijní opora 11 Můžeme se o tom přesvědčit zobrazením vlastností souboru: Třída System.Windows.Forms.Form Po spuštění aplikace (poklepáním na ikonu) se zobrazí prázdné okno (formulář): Objektově orientované programování - Studijní opora 12 Průvodce studiem. Blahopřeji Vám k úspěšnému překonání počátečních obtíží, které se vyskytnou vždy, když začnete něco opravdu dělat. Okno Vaší první aplikace se Vám určitě zdá příliš obyčejné a konec konců vlastně ani nic pořádného neumí. Pusťme se tedy do jeho vylepšování. Vzhled formuláře můžeme změnit nastavením jeho vlastností. Vlastnost Size Vlastnost Size určuje velikost formuláře. Do kódu přidáme následující řádky: [assembly: System.Reflection.AssemblyTitle("První program určený pro výuku programování."), System.Reflection.AssemblyVersion("M.1.0.B"), System.Reflection.AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), System.Reflection.AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.PrvniProgram { public static class Program { public static void Main() { System.Windows.Forms.Application.Run(new PrvniOkno()); } } public class PrvniOkno: System.Windows.Forms.Form { public PrvniOkno() { Size = new System.Drawing.Size(cMM, BMM); } } } Výsledné okno má nyní šířku x = 3AA px a výšku y = /AA px. Jednotka px (pixel) je jeden bod na monitoru. Vlastnost Text Vlastností Text zadáváme nápis v záhlaví okna. Přidáme do kódu: … public PrvniOkno() { Size = new System.Drawing.Size(cMM, BMM); Text = "První okno"; } … Objektově orientované programování - Studijní opora 13 Dostaneme: Vlastnost BackColor Barvu okna nastavíme vlastností BackColor: … public PrvniOkno() { Size = new System.Drawing.Size(cMM, BMM); Text = "První okno"; BackColor = System.Drawing.Color.Lime; } … A výsledek? Tady je: Průvodce studiem. Tak jak se Vám líbí Vaše nové barevné okénko? Hezké, že? Nebo máte raději jinou barvu? Zkuste si vzpomenout na Vaše začátky angličtiny (Red, Blue, Yellow… ) a vyberte si barvu dle vlastních představ. Ale až Vás přebarvování omrzí, zkusme to zařídit tak, aby barvu okna změnil počítač sám. Třeba po myším kliknutí. Událost Click Chod programu je řízen událostmi (event driven programming). Když uživatel klikne na okno myší, vyvolá systém událost Click, čímž spustí ovladače (handler) k události připojené. Připojíme tedy ovladač pro změnu barvy: … public PrvniOkno() { Size = new System.Drawing.Size(cMM, BMM); Text = "První okno"; BackColor = System.Drawing.Color.Lime; Click += delegate(object sender, System.EventArgs e) { BackColor = System.Drawing.Color.Red; }; } … Objektově orientované programování - Studijní opora 14 Vyzkoušíme jak to funguje. Po spuštění je okno zelené: Po kliknutí je okno červené: Výsledný zdrojový kód Po těchto úpravách vypadá zdrojový kód takto: [assembly: System.Reflection.AssemblyTitle("První program určený pro výuku programování."), System.Reflection.AssemblyVersion("B.0.0.0"), System.Reflection.AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), System.Reflection.AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.PrvniProgram { public static class Program { public static void Main() { System.Windows.Forms.Application.Run(new PrvniOkno()); } } public class PrvniOkno: System.Windows.Forms.Form { public PrvniOkno() { Size = new System.Drawing.Size(cMM, BMM); Text = "První okno"; BackColor = System.Drawing.Color.Lime; Click += delegate(object sender, System.EventArgs e) { BackColor = System.Drawing.Color.Red; }; } } } Objektově orientované programování - Studijní opora 15 Shrnutí kapitoly. Programy vznikají ze zdrojového kódu překladačem css.exe. Současně vzniká protokol o překladu, který obashuje popis případných chyb. Lze nastavit vlastnosti programu (např. AssemblyTitle, AssemblyVersion, AssemblyCompany, AssemblyCopyright). Vlastnostmi měníme vzhled oken (např. Text, BackColor). Programujeme reakce počítače na události (např. změna barvy po události Click). Průvodce studiem. Výborně! Už to funguje! A teď si dejte něco dobrého na posilněnou. V další kapitole si totiž ukážeme, jak totéž udělat mnohem jednodušeji. Tak ať to s Vámi nepraští. Objektově orientované programování - Studijní opora 16 Kapitola Z. Vizuální vývojové prostředí V této kapitole se dozvíte: Jak jednoduše vytvořit program z předešlé kapitoly pomocí vizuálního vývojového prostředí. Jak program přeložit. Jak vypadají zdrojové kódy vygenerované vývojovým prostředím. Klíčová slova této kapitoly: Vývojové prostředí, Vlastnosti, Události, Překlad Čas potřebný k prostudování učiva kapitoly: 2 hodiny Průvodce studiem. Pokud Vás nebaví psaní zdrojového kódu (a mezi námi: „koho by bavilo?“), pořiďte si vizuální vývojové prostředí a kód napíše počítač za Vás. Budete pak „jen“ pohodlně sedět u svého počítače nazvaného dejme tomu Žán a ukazovat myškou: „Žán, takhle! Žán, tohle okénko trochu větší! Žán, tuhle barvu ne, ta se mi nelíbí. Raději tamhletu! Nebo tuhle, ta je přece tak úžasná! Žán, Žán, Žán? Proč si se najednou zresetoval?“ Vývojové prostředí Zdrojový kód nemusíme psát ručně. Můžeme využít některý z vývojových nástrojů. Aplikace se navrhuje vizuálně, což je velmi názorné a rychlé. Ručně se dopisuje jen malá část kódu. Nyní si ukážeme, jak vytvořit první program z předešlé kapitoly pomocí vývojového prostředí Microsoft Visual C# Express Editon. Objektově orientované programování - Studijní opora 17 Nový projekt Nejprve vytvoříme nový projekt. Vybereme typ projektu Windows Application. Projekt nazveme blek.cz.Programovani.PrvniProgram. Stiskneme tlačítko OK. Objektově orientované programování - Studijní opora 18 V Solution Exploreru vybereme z místní nabídky projektu položku Vlastnosti. Stiskneme tlačítko Assembly Information. Objektově orientované programování - Studijní opora 19 Vyplníme informace o aplikaci a potvrdíme tlačítkem OK. Vrátíme se do okna s designem formuláře a z místní nabídky vyberem položku Properties. Objektově orientované programování - Studijní opora 20 Velikost okna nastavíme myší pomocí čtverečku v pravém dolním rohu formuláře. Text zadáme v tabulce vlastností. Objektově orientované programování - Studijní opora 21 Barvu pozadí vybereme z nabízených možností. Události zobrazíme tlačítkem Event (žlutý blesk). Poklepeme na událost Click. Objektově orientované programování - Studijní opora 22 Do připraveného kódu pro ovladač události dopíšeme příkaz pro změnu barvy na červenou. Nyní můžeme náš první program vyzkoušet. Stiskneme tlačítko Start. Objektově orientované programování - Studijní opora 23 Teď je na řadě počítač. Nejprve uloží všechny změněné soubory. Potom přeloží zdrojové kódy do spustitelného souboru. Pokud je vše v pořádku, nakonec aplikaci spustí. Aplikaci ukončíme obvyklým zavřením okna aplikace. Pokud by to nešlo, můžeme použít tlačítko Stop. Objektově orientované programování - Studijní opora 24 Zdrojový kód Zdrojový kód je umístěn v několika souborech. Části odpovídající ručně psanému kódu z předchozí kapitoly jsou vyznačeny žlutě. Soubor AssemblyInfo.cs Soubor AssemblyInfo.cs obsahuje vlastnosti aplikace. using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("blek.cz.Programovani.PrvniProgram")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Střední odborná škola, Blatná (blek.cz)")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("© Pavel Kozlovský")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("lebcZQdQ−ddfc−c\\M−bQZe−bc`fdZeec`Qd")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // [assembly: AssemblyVersion("M.1.0.0")] [assembly: AssemblyFileVersion("M.1.0.0")] Soubor Program.cs Soubor Program.cs obsahuje metodu Main volanou při spuštění programu. using System; using System.Collections.Generic; using System.Windows.Forms; namespace blek.cz.Programovani.PrvniProgram { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new FormB()); } } } Objektově orientované programování - Studijní opora 25 Soubor FormB.Designer.cs Soubor Form/.Designer.cs obsahuje nastavení vlastností. namespace blek.cz.Programovani.PrvniProgram { partial class FormB { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support − do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // FormB // this.AutoScaleDimensions = new System.Drawing.SizeF(bF, BlF); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.Lime; this.ClientSize = new System.Drawing.Size(ZQZ, bb); this.Name = "FormB"; this.Text = "První okno"; this.Click += new System.EventHandler(this.FormB_Click); this.ResumeLayout(false); } #endregion } } Objektově orientované programování - Studijní opora 26 Soubor FormB.cs Soubor Form/.cs je určen pro ruční psaní částí kódu. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace blek.cz.Programovani.PrvniProgram { public partial class FormB : Form { public FormB() { InitializeComponent(); } private void FormB_Click(object sender, EventArgs e) { BackColor = Color.Red; } } } Shrnutí kapitoly. Zdrojový kód můžeme vytvořit pomocí vizuálního vývojového prostředí (např. Microsoft Visual C# 0AA- Express Edition). Prostředí generuje více souborů (AssemblyInfo.cs, Program.cs, Form/.Designer.cs, Form/.cs). Objektově orientované programování - Studijní opora 27 Kapitola l. Syntaktická gramatika V této kapitole se dozvíte: Jaká je struktura zdrojového kódu. Jak deklarovat datové typy. Co jsou to jmenné prostory. Klíčová slova této kapitoly: Zdrojový kód, deklarace typu, jmenný prostor, direktiva using. Čas potřebný k prostudování učiva kapitoly: 0 hodiny Průvodce studiem. Tahle kapitolka je sice krátká, ale pomůže Vám se zorientovat v textu zdrojového kódu. Velmi důležitá jsou jména. Tuhle jsem potkal kamaráda a ten mi říkal, že si jde koupit novou myš, protože jeho kočka, když honila myš, shodila mu myš ze stolu. Celkem jsem ho chápal, i když mi nebylo jasné, kde se u něj bere tolik myší. Inu není myš jako myš. Ale jak to vysvětlit počítači? Celky compilation unit → extern alias directive A – N ( using alias directive | using namespace directive )A – N attributes A – / ( namespace declaration | type declaration )A – N Zdrojový kód se skládá z jednoho nebo více celků – compilation unit [kǝmpileišn junit] uložených v samostatných souborech. Celek se skládá z deklarací (prohlášení) – declaration [deklǝˡreišn], direktiv (pokynů) – directive [diˡrektiv] a skupin atributů – attribute section. Deklarace typu type declaration → class declaration | struct declaration | interface declaration | enum declaration | delegate declaration Příklad. class ZeleneOkno{…} class ZluteOkno{…} class CerveneOkno{…} Příklad. V prvním programu jsme deklarovali dva nové datové typy – statickou třídu Program (vyznačeno žlutě) a třídu oken PrvniOkno (vyznačeno zeleně). Objektově orientované programování - Studijní opora 28 [assembly: System.Reflection.AssemblyTitle("První program určený pro výuku programování."), System.Reflection.AssemblyVersion("B.0.0.0"), System.Reflection.AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), System.Reflection.AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.PrvniProgram { public static class Program { public static void Main() { System.Windows.Forms.Application.Run(new PrvniOkno()); } } public class PrvniOkno: System.Windows.Forms.Form { public PrvniOkno() { Size = new System.Drawing.Size(cMM, BMM); Text = "První okno"; BackColor = System.Drawing.Color.Lime; Click += delegate(object sender, System.EventArgs e) { BackColor = System.Drawing.Color.Red; }; } } } {} Jmenný prostor Deklarujme-li datový typ musíme určit zejména jeho jméno. Může se nám snadno stát, že některé jméno použijeme dvakrát. Často jednu aplikaci vytváří více programátorů. Dokonce i když programujeme na první pohled úplně sami, používáme systémové, případně i jiné knihovny, které programoval někdo úplně jiný. Potom je pravděpodobnost výskytu homonym (stejně znějících slov různého významu) značná. Situace je podobná jako se jmény souborů. Můžeme mít na počítači dva různé soubory se stejným jménem? Můžeme, ale musí být v různých adresářích. Můžeme tedy deklarovat dva různé typy se stejným jménem, ale musí být deklarovány v jiném jmenném prostoru (namespace). Jmenné prostory jsou vlastně takové „složky“ na jména typů. Příklad. V systémových knihovnách najdeme dva datové typy pro tlačítka se stejným názvem Button. Jedno se používá ve windowsových aplikacích a druhé na webových stránkách. Aby se daly oba typy od sebe rozlišit, jsou deklarovány v jiných jmenných prostorech. System.Windows.Forms.Button // Windowsové tlačítko System.Web.UI.Button // Webové tlačítko Deklarace jmenného prostoru namespace declaration → namespace ( identifier . )A – N identifier { A – N using directive A – N ( namespace declaration | type declaration )A – N } extern alias directive ; A–/ Deklarace jmenného prostoru se skládá z klíčového slova namespace, jména (identifier) jmenného prostoru, kterému může předcházet cesta jmen oddělených tečkou. Následuje levá složená závorka, za kterou můžou následovat direktivy (directive) a deklarace (declaration). Na závěr napíšeme pravou složenou závorku a můžeme připsat i středník. Objektově orientované programování - Studijní opora 29 Příklad. Karel a Jitka programují společně windowsovou aplikaci. Aby nedošlo ke kolizi jmen, používá každý z nich svůj vlastní jmenný prostor. namespace Karel { class ZeleneOkno{…} class ZluteOkno{…} class CerveneOkno{…} } namespace Jitka { class ModreOkno{…} class BileOkno{…} class ZluteOkno{…} } Příklad. V prvním programu jsme deklarovali jmenný prostor blek.cz.Programovani.PrvniProgram. [assembly: System.Reflection.AssemblyTitle("První program určený pro výuku programování."), System.Reflection.AssemblyVersion("B.0.0.0"), System.Reflection.AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), System.Reflection.AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.PrvniProgram { public static class Program { public static void Main() { System.Windows.Forms.Application.Run(new PrvniOkno()); } } public class PrvniOkno: System.Windows.Forms.Form { public PrvniOkno() { Size = new System.Drawing.Size(cMM, BMM); Text = "První okno"; BackColor = System.Drawing.Color.Lime; Click += delegate(object sender, System.EventArgs e) { BackColor = System.Drawing.Color.Red; }; } } } Příklad. Deklarace systémového tlačítka vypadá takto: namespace System { namespace Windows { namespace Forms { class Button … } } } Objektově orientované programování - Studijní opora 30 Stejný význam má i zkrácený zápis: namespace System.Windows.Forms { class Button … } Jména typů type name → ( identifier | identifier identifier ) ( < type ( , :: identifier | namespace name . identifier | type name . type )A – N > )A – / Jméno typu se skládá z identifikátoru typu, kterému může předcházet určení jmenného prostoru. Používáme-li generické typy, jsou součástí jména typu i typové argumenty uzavřené do lomených závorek. Příklad. ZeleneOkno Karel.ZluteOkno global::System.Windows.Forms.Button System.Web.UI.WebControls.Button System.Collection.Generic.List<System.Windows.Forms.Button> Příklad. Jména typů v prvním programu jsou uvedena žlutě. [assembly: System.Reflection.AssemblyTitle("První program určený pro výuku programování."), System.Reflection.AssemblyVersion("B.0.0.0"), System.Reflection.AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), System.Reflection.AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.PrvniProgram { public static class Program { public static void Main() { System.Windows.Forms.Application.Run(new PrvniOkno()); } } public class PrvniOkno: System.Windows.Forms.Form { public PrvniOkno() { Size = new System.Drawing.Size(cMM, BMM); Text = "První okno"; BackColor = System.Drawing.Color.Lime; Click += delegate( object sender, System.EventArgs e) { BackColor = System.Drawing.Color.Red; }; } } } Objektově orientované programování - Studijní opora 31 Jména jmenných prostorů namespace name → idntifier | global . :: identifier | alias name :: identifier | namespace name identifier Jména jmenných prostorů jsou jednodušší obdobou jmen typů. Příklad. System System.Drawing System.Windows System.Windows.Forms Část pro zájemce. Direktiva extern alias extern alias directive → extern alias alias name ; alias name → identifier Příklad. Máme dvě verze knihovny tlačítek „tlacitka.dll“ a „tlacitka0.dll“ a chceme použít obě najednou. Překlad voláme s parametry: csc … /r:stare=tlacitka.dll /r:nove=tlacitkaZ.dll … V kódu použijeme: extern alias nove; extern alias stare; … … nove::Tlacitko … … stare::Tlacitko … Direktiva using namespace using namespace directive → using namespace name ; Direktiva using namespace se skládá z klíčového slova using, jména jmenného prostoru a středníku. Jmenné prostory uvedené v direktivách using, nemusíme vypisovat v kódu. Objektově orientované programování - Studijní opora 32 Příklad. Velmi často začíná zdrojový kód windowsové aplikace těmito řádky: using System; using System.Drawing; using System.Windows; using System.Windows.Forms; Příklad. Využitím direktivy using zkrátíme zdrojový kód prvního programu. using System; using System.Drawing; using System.Reflection; using System.Windows.Forms; [assembly: AssemblyTitle("První program určený pro výuku programování."), AssemblyVersion("B.0.0.0"), AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.PrvniProgram { public static class Program { public static void Main() { Application.Run(new PrvniOkno()); } } public class PrvniOkno: Form { public PrvniOkno() { Size = new Size(cMM, BMM); Text = "První okno"; BackColor = Color.Lime; Click += delegate( object sender, EventArgs e) { BackColor = Color.Red; }; } } } Objektově orientované programování - Studijní opora 33 Direktiva using alias using alias directive → using identifier = ( namespace name | type name ) ; Direktivou using alias definujeme krycí jméno (alias), které pak používáme místo původního jména. Příklad. using KarlovoOkno=Karel.ZluteOkno; using JitcinoOkno=Jitka.ZluteOkno; Místo Karel.ZluteOkno můžeme psát jen alias KarlovoOkno. Příklad. Aby nedošlo ke kolizi jmen jmenných prostorů, doporučuje se, aby jméno prvního jmenného prostoru identifikovalo výrobce a druhé výrobek (produkt, aplikaci). using System; using System.Drawing; using System.Windows; using System.Windows.Forms; namespace Vyrobce.Aplikace { class HlavniOkno{…} class DalsiOkno{…} class OvladaciPanel{…} } Shrnutí kapitoly. Zdrojový kód se skládá z deklarací datových typů. Pro větší přehlednost a odstranění případných kolizí jmen se používají jmenné prostory (namespace). Průvodce studiem. Tak to bylo trochu nudné, co říkáte? Odpočiňte si tedy a těšte se na další kapitolu, kde bude zase něco k vidění. Objektově orientované programování - Studijní opora 34 Kapitola c. Vlastnosti formuláře V této kapitole se dozvíte: Jak nastavit velikost okna. Jak nastavit barvu okna. Jak nastavit kurzor. Jak nastavit ikonu. Klíčová slova této kapitoly: Vlastnost, velikost, barva, kurzor, ikona. Čas potřebný k prostudování učiva kapitoly: - hodin Průvodce studiem. Nastavování vlastností formulářů je velmi názorné a určitě se Vám bude líbit. Nemusíte se toho mnoho učit (obvykle stačí jedna řádka kódu), ale výsledek − ten je vidět hned. Opravdu hned jak nějakou vlastnost nastavíte, můžete se podívat jak okno vypadá. Využijte toho a pohrajte si s vlastnostmi jak malé děti. Jé tahle pastelka pěkně maluje. A co když si vezmu jinou? A tahle kostička se mi tady nelíbí, dám tam jinou. Takže si obarvujte, měňte ikonky a kurzorky dle libosti a pak, prosím, pošlete splněný úkol, který pro Vás jistě taky bude hračkou! Vlastnosti Uveďme si nyní některé důležité vlastnosti formulářů. Size Velikost formuláře. První číslo udává šířku a druhé výšku. Obojí se měří v obrazovkových bodech (pixelech). Size = new Size(cMM, BMM); MinimumSize Nejmenší velikost formuláře. Uživatel nemůže zmenšit okno pod zadanou velikost. MinimumSize = new Size(cMM, BMM); MaximumSize Největší velikost formuláře. Uživatel nemůže zvětšit okno nad zadanou velikost. MaximumSize = new Size(`MM , ZMM); Text Nadpis zobrazovaný v záhlaví okna. Objektově orientované programování - Studijní opora 35 Text = "První okno"; BackColor Barva formuláře. BackColor = Color.LightYellow; Vlastnost BackColor je typu Color. Color Struktura Color představuje barvu. Je možné vybírat z předdefinovaných barev jako jsou např. Color.White, Color.Yellow, Color.Orange, Color.Pink, Color.Red, Color.Violet, Color.Blue, Color.Green, Color.Brown, Color.Gray, Color.Black a mnoho dalších. Můžete si i „namíchat“ vlastní barvu z červené (R), zelené (G) a modré (B) pomocí metody Color Color.FromArgb(int red, int green, int blue) Hodnoty parametrů red, green a blue jsou z intervalu od A do 0--. BackColor = Color.FromArgb(Z``, Z``, M); Cursor Kurzor je možné vybírat z předdefinovaných kurzorů třídy Cursors. Cursor = Cursors.Hand; Další možnosti jsou např. Cursor = Cursors.Arrow; Cursor = Cursors.Cross; Cursor = Cursors.Default; Cursor = Cursors.Help; Cursor = Cursors.IBeam; Cursor = Cursors.No; Cursor = Cursors.VSplit; Cursor = Cursors.WaitCursor; FormBorderStyle Vlastností FormBorderStyle nastavujeme styl okraje okna. Pevný okraj bez možnosti změny velikosti okna uživatelem nastavíme volbou FixedSingle. FormBorderStyle = FormBorderStyle.FixedSingle; Objektově orientované programování - Studijní opora 36 Okno může být i zcela bez okraje. FormBorderStyle = FormBorderStyle.None; Icon Ikona formuláře. Je možné vybírat z systémových ikon třídy SystemIcons. Icon = SystemIcons.Exclamation; Další možnosti jsou: Icon = SystemIcons.Application; Icon = SystemIcons.Asterisk; Icon = SystemIcons.Error; Icon = SystemIcons.Hand; Icon = SystemIcons.Information; Icon = SystemIcons.Question; Icon = SystemIcons.Warning; Icon = SystemIcons.WinLogo; MaximizeBox a MinimizeBox Maximalizační tlačítko lze zakázat nastavením vlastnosti MaximizeBox na false. Obdobně lze zakázat i minimalizační tlačítko. Můžeme zakázat i obě najednou. MaximizeBox = MinimizeBox = false; Opacity Okno může být i průhledné. Vlastnost Opacity může nabývat hodnot od A (zcela průhledné a tedy neviditelné) do / (zcela neprůhledné). Objektově orientované programování - Studijní opora 37 Opacity = M.3; ShowIcon Nastavením ShowIcon lze zakázat zobrazování ikony. ShowIcon = false; ShowInTaskBar Zobrazení tlačítka okna na hlavním panelu lze zakázat vlastností ShowInTaskBar. ShowInTaskBar = false; SizeGripStyle „Grip“ pro snadnější změnu velikosti okna zobrazíme pomocí vlastnosti SizeGripStyle. Všimněte si změny v pravém dolním rohu okna. SizeGripStyle = SizeGripStyle.Show; StartPosition Výchozí umístění okna určíme nastavením vlastnosti StartPosition. Možnosti jsou: StartPosition = FormStartPosition.CenterParent; StartPosition = FormStartPosition.CenterScreen; StartPosition = FormStartPosition.Manual; StartPosition = FormStartPosition.WindowsDefaultBounds; StartPosition = FormStartPosition.WindowsDefaultLocation; TopMost Nastavením vlastnosti TopMost na true dosáhneme toho, že okno bude vidět stále nahoře i při přepnutí na jiné okno. TopMost = true; Objektově orientované programování - Studijní opora 38 TransparencyKey TransparencyKey je barva klíče průhlednosti. Zadaná barva není vykreslována a na obrazovce je vidět skrz okno. Používá se např. pro atypické tvary oken (různé skiny přehrávačů apod.). TransparencyKey = Color.LightBlue; UseWaitCursor Většinou uživatelů nenáviděné hodiny zobrazíme vlastnosti UseWaitCursor. UseWaitCurosor = true; WindowState Stav okna (normální, maximalizované a minimalizované) nastavíme vlastností WindowState. Možnosti jsou: WindowState = FormWindowState.Normal; WindowState = FormWindowState.Maximized; WindowState = FormWindowState.Minimized; Příklad. Napište kód pro nastavení vlastností okna tak, aby vypadalo jako vyobrazené okno. Řešení: Size = new Size(ZMM, BMM); BackColor = Color.Red; Cursor = Cursors.IBeam; Icon = SystemIcons.Error; SizeGripStyle = SizeGripStyle.Show; MaximizeBox = false; Korespondenční úkol. Napište kód pro nastavení vlastností okna tak, aby vypadalo jako vyobrazené okno. Objektově orientované programování - Studijní opora 39 Shrnutí kapitoly. Ke změně vzhledu formulářů (oken) používáme vlastnosti. Mezi základní patří Size, Text, BackColor, Cursor a Icon. Objektově orientované programování - Studijní opora 40 Kapitola `. Události formuláře V této kapitole se dozvíte: Klíčová slova této kapitoly: Myší události, klávesové události. Čas potřebný k prostudování učiva kapitoly: - hodin Průvodce studiem. A nyní, velectěné publikum, račte jít dál. Uvidíte co jste ještě neviděli. Jen račte dál − vstupenky zakupujte u pokladny. Uvidíte drezúru myší pod vedením světoznámeho dua krotitelů Click & DoubleClick. Vše za klavírního doprovodu prvotřídních umělců zvučných jmen. Vystoupí pánové Key Down, Key Up a Key Press. Ano, ano, to jste ještě neviděli, postupujte nahoru… Události Již jsme si řekli, že chod programu je řízen událostmi. Události nejčastěji vznikají jako reakce na podněty od uživatele. Některé událostí jsou jednoduché (např. kliknutí myší, stisk klávesy), mohou být i složitější (např. přesun okna, změna klávesnice). Uveďme si nejpoužívanější události. Click Po kliknutí myší okno zčervená. Click += delegate(object sender, EventArgs e) { BackColor = Color.Red; }; DoubleClick Po poklepání myší bude okno fialové. DoubleClick += delegate(object sender, EventArgs e) { BackColor = Color.Violet; }; GotFocus Aktivní okno se zbarví na růžovo. GotFocus += delegate(object sender, EventArgs e) { BackColor = Color.Pink; }; Objektově orientované programování - Studijní opora 41 LostFocus Neaktivní okno bude šedivé. LostFocus += delegate(object sender, EventArgs e) { BackColor = Color.Gray; }; InputLanguageChanged Přepne-li uživatel klávesnici (např. z české na anglickou), je vyvolána událost InputLanguageChanged. Nadpis okna může záviset na vybraném jazyce. InputLanguageChanged += delegate(object sender, InputLanguageChangedEventArgs e) { switch (e.Culture.TwoLetterISOLanguageName) { case "cs": Text = "První okno"; break; case "en": Text = "First Window"; break; } }; InputLanguageChanging Těsně před změnou klávesnice je vyvolána událost InputLanguageChanging. Nastavením vlastnosti Cancel je možné změnu stornovat. Přepnutí na anglickou klávesnici můžeme zabránit třeba takto. InputLanguageChanging += delegate(object sender, InputLanguageChangingEventArgs e) { if (e.Culture.TwoLetterISOLanguageName == "en") { MessageBox.Show("Sorry, I don't speak English."); e.Cancel = true; } }; KeyDown Událost KeyDown je vyvolána vždy, když uživatel stiskne klávesu. Která klávesa byla stisknuta zjistíme z vlastnosti KeyCode. KeyDown += delegate(object sender, KeyEventArgs e) { switch (e.KeyCode) { case Keys.FB: BackColor = Color.Gold; break; case Keys.FZ: BackColor = Color.Silver; break; case Keys.Fl: BackColor = Color.Brown; break; case Keys.Up: BackColor = Color.Tomato; break; } } Objektově orientované programování - Studijní opora 42 KeyUp Událost KeyUp se podobá události KeyDown s tím rozdílem, že je volaná až při uvolnění klávesy. KeyUp += delegate(object sender, KeyEventArgs e) { switch (e.KeyCode) { case Keys.FB: BackColor = Color.Red; break; case Keys.FZ: BackColor = Color.Green; break; case Keys.Fl: BackColor = Color.Blue; break; } } Část pro zájemce. Vyzkoušejte si, co se stane, když bude stisknuto více kláves najednou. Stikněte a držte F/ (okno bude zlaté). Stiskněte ještě F0 (okno bude stříbrné). Uvolněte F/ (okno bude červené). Uvolněte F0 (okno bude zelené). KeyPress Událost KeyPress je volána při vložení znaku z klávesnice. Uvědomme si rozdíl mezi klávesami a znaky. K napsání některých znaků je třeba více kláves (např. Shift, Alt nebo diakritická znaménka). Vyzkoušíme si nastavení Červené, Žluté a Úžasné barvy. KeyPress += delegate(object sender, KeyPressEventArgs e) { switch (e.KeyChar) { case 'Č': BackColor = Color.Red; break; case 'Ž': BackColor = Color.Yellow; break; case 'Ú': BackColor = Color.Violet; break; } } MouseEnter Najede-li uživatel myší na okno, je vyvolána událost MouseEnter. MouseEnter += delegate(object sender, EventArgs e) { BackColor = Color.Lime; } MouseLeave Opustí-li uživatel myší okno, je vyvolána událost MouseLeave. MouseLeave += delegate(object sender, EventArgs e) { BackColor = Color.Magenta; } Objektově orientované programování - Studijní opora 43 MouseClick Událost MouseClik se podobá události Click, máme však navíc např. informaci o tom, které tlačítko na myši bylo použito. MouseClick += delegate(object sender, MouseEventArgs e) { switch (e.Button) { case MouseButtons.Left: BackColor = Color.Red; break; case MouseButtons.Right: BackColor = Color.Blue; break; } } Move Chceme-li uživateli naznačit, že okno nerado cestuje po monitoru a při přesunech mu není dobře, použijeme událost Move a při jejím výskytu obarvíme okno na zeleno. Move += delegate(object sender, EventArgs e) { BackColor = Color.Green; } Paint Paint je příkladem události, kterou nezpůsobil uživatel přímo. Je vyvolávána systémem vždy, když je třeba překreslit okno. Metody vlastnosti Graphics umožňují např. nakreslit čáru. Paint += delegate(object sender, PaintEventArgs e) { e.Graphics.DrawLine(Pens.Blue, ZM, ZM, BbM, `M); }; Objektově orientované programování - Studijní opora 44 Průvodce studiem. A nyní bych prosil jednoho dobrovolníka, třeba ten pán v červené vestě s hnědým kloboukem, pojďte, prosím, k nám na pódium. Potlesk pro pana − Programátora. Pane Programátore, vemte si tady to nářadí a pusťte se do toho. Ještě jednou potlesk pro pana Programátora. Úkol. Vyzkoušejte si prakticky události uvedené v této kapitole ve svém programu. Shrnutí kapitoly. Uživatel obvykle ovládá windowsové aplikace myší a klávesnicí. To vyvolává události, kterými je řízen chod aplikace. K událostem připojujeme kód, který je prováděn při jejich výskytu. Základní „myší“ události jsou Click a DoubleClick, klávesové KeyDown, KeyUp a KeyPress. Objektově orientované programování - Studijní opora 45 Kapitola b. Ovládací prvky V této kapitole se dozvíte: Jak přidat na formulář další ovládací prvky psaním zdrojového kódu. Jak učinit totéž ve vizuálním vývojovém prostředí. Jak nastavit vlastnosti.ovládacích prvků. Jak reagovat na události ovládacích prvků. Jak vytvořit menu. Klíčová slova této kapitoly: Ovládací prvek, tlačítko, popisek, textové pole, zaškrtávací políčko Čas potřebný k prostudování učiva kapitoly: /A hodin Průvodce studiem. Konec cirkusu a zábavy, vyhrňte si rukávy − jdeme stavět! A to je vážná věc. Jen toho materiálu co je zapotřebí. Cihly, trubky, trámy, dveře … Co říkáte? Aha, že nestavíme dům, ale program. Tak to mi promiňte a vemte si raději tlačítka, textová a zaškrtávácí políčka, různé popisky … Objektově orientované programování - Studijní opora 46 Ovládací prvky Formuláře obykle nejsou prázdné, ale obsahují další ovládací prvky, jako jsou např. tlačítka, textová pole, zaškrtávací políčka atd. V novém programu „OvladaciPrvky“ si ukážeme jak přidat do formuláře tlačítko. Kód pro tlačítko je vyznačen žlutě. using System; using System.Drawing; using System.Reflection; using System.Windows.Forms; [assembly: AssemblyTitle("Ovládací prvky."), AssemblyVersion("B.0.0.0"), AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.OvladaciPrvky { public static class Program { public static void Main() { Application.Run(new Okno()); } } public class Okno: Form { public Okno() { Size = new Size(cMM, BMM); Text = "Ovládací prvky"; { Button button = new Button(); button.Location = new Point(`M, lM); button.Text = "Žlutá"; button.Parent = this; button.Click += delegate(object sender, EventArgs e) { BackColor = Color.Yellow; }; } } } } Po stisknutí tlačítka je okno žluté. Objektově orientované programování - Studijní opora 47 Jak na to vizuálně? Ovládací prvky je možné jednoduše zadávat ve vizuálním vývojovém prostředí. Otevřeme ToolBox. A vybraný ovládací prvek jednoduše přesuneme myší na formulář. Objektově orientované programování - Studijní opora 48 Nakonec nastavíme vlastnost Text a doprogramujeme ovladač události Click. Úkol. Vytvořte aplikaci (soubor .exe) OvladaciPrvky. Průvodce studiem. Mohu blahopřát k vyřešení úkolu? Určitě ano, věřím Vám, že se to povedlo. A kdyby ne, udělejte si přestávku a zkoušejte to znova. Někdy s odpočatou hlavou vyřešíte za pár minut to, co předtím nešlo ani za několik hodin. Tak jako tak si udělejte větší či menší přestávku. Čeká nás totiž tvorba menu a s tím i trochu více kódu. Tak se na to dobře připravte. Ovládací prvky verze Z.0 Přidáme tlačítka Červená a Modrá. Umožníme nastavení barvy z menu Barva. Objektově orientované programování - Studijní opora 49 Kód vypadá takto: using System; using System.Drawing; using System.Reflection; using System.Windows.Forms; [assembly: AssemblyTitle("Ovládací prvky."), AssemblyVersion("Z.0.0.0"), AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.OvladaciPrvky { public static class Program { public static void Main() { Application.Run(new Okno()); } } public class Okno: Form { public Okno() { Size = new Size(cMM, BMM); Text = "Ovládací prvky"; { Button button = new Button(); button.Location = new Point(`M, lM); button.Text = "Žlutá"; button.Parent = this; button.Click += delegate(object sender, EventArgs e) { BackColor = Color.Yellow; }; } { Button button = new Button(); button.Location = new Point(B`M, lM); button.Text = "Červená"; button.Parent = this; button.Click += delegate(object sender, EventArgs e) { BackColor = Color.Red; }; } { Button button = new Button(); button.Location = new Point(Z`M, lM); button.Text = "Modrá"; button.Parent = this; button.Click += delegate(object sender, EventArgs e) { BackColor = Color.Blue; }; } MainMenuStrip = new MenuStrip(); { ToolStripMenuItem barva = new ToolStripMenuItem("Barva"); { EventHandler onClick = delegate(object sender, EventArgs e) { BackColor = Color.Yellow; }; barva.DropDownItems.Add("Žlutá", null, onClick); } { EventHandler onClick = delegate(object sender, EventArgs e) { BackColor = Color.Red; }; barva.DropDownItems.Add("Červená", null, onClick); } { EventHandler onClick = delegate(object sender, EventArgs e) Objektově orientované programování - Studijní opora 50 { BackColor = Color.Blue; }; barva.DropDownItems.Add("Modrá", null, onClick); } barva.Owner = MainMenuStrip; } MainMenuStrip.Parent = this; } } } Úkol. Odlaďte program Ovládací prvky verze 0.0. Button Tlačítko. Button button = new Button(); Location Umístění tlačítka (souřadnice levého horního rohu). button.Location = new Point(`M, lM); Parent Odkaz na rodičovský prvek, na kterém je tlačítko umístěno. V našem případě se jedná o tento (this) formulář. Nastavení je nutné k tomu, aby se tlačítko vůbec zobrazilo. button.Parent = this; Text Nápis uvedený na tlačítku. button.Text = "Tlačítko"; Objektově orientované programování - Studijní opora 51 Click Událost vyvolaná po stisknutí tlačítka. button.Click += delegate(object sender, EventArgs e) { BackColor = Color.Yellow; }; Label Popisek se používá k zobrazení textu. Lze nastavit i písmo a barvu. Události se obvykle nepoužívají. Label label = new Label(); label.Location = new Point(`M, ZM); label.Text = "Popisek."; label.Font = new Font("Arial", Zc); label.AutoSize = true; label.ForeColor = Color.Blue; label.Parent = this; Font Písmo použité z zobrazení textu. Zadává se jméno fontu a velikost v bodech. AutoSize Nastavíme-li vlastnost AutoSize na true, přizpůsobí se velikost popisku velikosti textu. ForeColor Barvu textu nastavíme vlastností ForeColor. TextBox Ovládací prvek TextBox představuje textové pole určené pro zadávání textu uživatelem. TextBox textBox = new TextBox(); textBox.Location = new Point(`M, lM); textBox.Width = ZMM; textBox.Text = "Textové pole."; textBox.Parent = this; Objektově orientované programování - Studijní opora 52 Width Šířku textového pole nastavíme vlastností Width. MaxLength Délku zadávaného textu lze omezit vlastností MaxLength. textBox.MaxLength = ZM; UseSystemPasswordChar Nastavíme-li vlastnost UseSystemPasswordChar, budou zadávané znaky skryté jako při zadávání hesla. textBox.UseSystemPasswordChar = true; TextAlign K zarovnání textu doprava použijeme vlastnost TextAlign. textBox.TextAlign = HorizontalAlignment.Right; TextChanged Po změně textu dojde k události TextChanged. Změněná pole můžeme třeba obarvit. textBox.TextChanged += delegate(object sender, EventArgs e) { textBox.BackColor = Color.Yellow; }; Objektově orientované programování - Studijní opora 53 CheckBox Zaškrtávací políčko pro zadávání hodnot ano − ne. CheckBox checkBox = new CheckBox(); checkBox.Location = new Point(`M, lM); checkBox.Text = "Zaškrtávací políčko."; checkBox.AutoSize = true; checkBox.Checked = true; checkBox.Parent = this; Checked Vlastnost Checked určuje, je-li políčko zaškrtnuto (true) nebo ne (false). CheckedChanged Po změně zaškrtnutí nastává událost CheckedChanged. CheckedChanged += delegate(object sender, EventArgs e) { BackColor = checkBox.Checked ? Color.Red : Color.Silver; }; MonthCalendar K dispozici jsou i mnohem komplikovanější prvky jako je např. kalendář. MonthCalendar monthCalendar = new MonthCalendar(); monthCalendar.Location = new Point(`M, lM); monthCalendar.Parent = this; Objektově orientované programování - Studijní opora 54 Průvodce studiem. Šedá je teorie, zelený strom života, říkává se. Ukážeme si nyní, jak lze využít získané vědomosti v praxi. V závěru Vás prosím o vypracování úkolu. Příklad. Naprogramujte malého průvodce na cesty Evropou. Při stisknutí tlačítka se zobrazí příslušná fráze. Řešení. Protože potřebujeme přistupovat k popisku label z více míst, musíme jeho deklaraci uvést výše (označeno žlutě). Objektově orientované programování - Studijní opora 55 using System; using System.Drawing; using System.Reflection; using System.Windows.Forms; [assembly: AssemblyTitle("Malý průvodce na cesty Evropou."), AssemblyVersion("B.0.0.0"), AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.MalyPruvodce { public static class Program { public static void Main() { Application.Run(new Pruvodce()); } } public class Pruvodce : Form { public Pruvodce() { Size = new Size(cMM, B`M); Text = "Malý průvodce na cesty Evropou"; Label label = new Label(); { Button button = new Button(); button.Location = new Point(lM, lM); button.Text = "Pozdrav"; button.BackColor = Color.Yellow; button.Parent = this; button.Click += delegate(object sender, EventArgs e) { label.Text = "Dobrý den."; }; } { Button button = new Button(); button.Location = new Point(BBM, lM); button.Text = "Dotaz"; button.BackColor = Color.Orange; button.Parent = this; button.Click += delegate(object sender, EventArgs e) { label.Text = "Hovoříte česky?"; }; } { Button button = new Button(); button.Location = new Point(BQM, lM); button.Text = "Rozloučení"; button.BackColor = Color.Red; button.Parent = this; button.Click += delegate(object sender, EventArgs e) { label.Text = "Na shledanou."; }; } { label.Location = new Point(lM, b`); label.Text = null; label.Font = new Font("Arial", Ba); label.AutoSize = true; label.BackColor = Color.Black; label.ForeColor = Color.Lime; label.Parent = this; } } } } Objektově orientované programování - Studijní opora 56 Korespondenční úkol. Vytvořte verzi 0.0 malého průvodce na cesty Evropou, který bude doplněn o možnost přepnutí do angličtiny. Shrnutí kapitoly. K rychlejšímu vývoji designu windowsových formulářů používáme ovládací prvky. Tlačítka (Button) mají vlastnost Text a událost Click. Popisky (Label) mají vlastnosti Text, Font a Color. Textová pole (TextBox) mají vlastnosti Text, Font, Width, TextAlign a událost TextChanged. Zaškrtávací pole (CheckBox) má vlastnost Checked a událost CheckedChanged. Objektově orientované programování - Studijní opora 57 Kapitola \. Jednoduchá kalkulačka V této kapitole se dozvíte: Jak naprogramovat jednoduchou kalkulačku Klíčová slova této kapitoly: Kalkulačka, displej, číslice, operace, funkce Čas potřebný k prostudování učiva kapitoly: , hodin Průvodce studiem. Uvedení slova „jednoduchá“ v nadpisu je ode mne velká škodolibost. Kód programu je totiž hrozně dlouhý, ale nebojte se, vše bude vysvětleno v dalších kapitolách. Příklad. Naprogramujte jednoduchou kalkulačku. Potom přidejte tlačítka pro výpočet funkcí. Objektově orientované programování - Studijní opora 58 Řešení. Protože kód je značně rozsáhlý, jsou podrobné vysvětlující komentáře uvedeny přímo v kódu. using System; using System.Drawing; using System.Reflection; using System.Windows.Forms; [assembly: AssemblyTitle("Jednoduchá kalkulačka."), AssemblyVersion("B.0.0.0"), AssemblyCompany("Střední odborná škola, Blatná (blek.cz)"), AssemblyCopyright("\uMMaQ Pavel Kozlovský. Všechna práva vyhrazena.") ] namespace blek.cz.Programovani.JednoduchaKalkulacka { /// <summary> /// Hlavní program. /// </summary> public static class Program { /// <summary> /// Vstupní bod aplikace. /// Spustí lepší kalkulačku. /// </summary> public static void Main() { Application.Run(new LepsiKalkulacka()); } } IDisplej /// <summary> /// Rozhraní displeje. /// Displej slouží k zobrazování hodnot uživateli. /// </summary> interface IDisplej { /// <summary> /// Vlastností Zapnuto zapínáme a vypínáme displej. /// </summary> bool Zapnuto { get; set;} /// <summary> /// Vlastností Hodnota nastavujeme zobrazované číslo. /// </summary> double Hodnota {set;} /// <summary> /// Metoda Vynulovat slouží k vymazání displeje. /// </summary> void Vynulovat(); /// <summary> /// Po vynulování je vyvolána událost Vynulovano. /// </summary> event EventHandler Vynulovano; } Objektově orientované programování - Studijní opora 59 Tlacitko /// <summary> /// Třída tlačítek na kalkulačce je podtřídou třídy Button. /// </summary> class Tlacitko : Button { /// <summary> /// Pole Kalkulačka, na které je tlačítko umístěno. /// </summary> public Kalkulacka Kalkulacka; /// <summary> /// Konstruktor nastavující velikost tlačítka. /// </summary> public Tlacitko() { Width=Z`; } } Kalkulacka /// <summary> /// Třída kalkulaček je podtřídou třídy formulářů. /// </summary> class Kalkulacka : Form { /// <summary> /// Pole Displej. Každá kalkulačka má displej. /// </summary> public IDisplej Displej; /// <summary> /// Pole X. Číslo, které si kalkulačka pamatuje. /// </summary> public double X; /// <summary> /// Pole Y. Číslo, které je obvykle zobrazeno na displeji. /// </summary> public double Y; /// <summary> /// Konstanta rastr udává vzdálenost mezi tlačítky. /// </summary> const int rastr = lM; /// <summary> /// Nastavení displeje při otvírání formuláře přeprogramováním virtuální metody OnLoad. /// </summary> protected override void OnLoad(EventArgs e) { base.OnLoad(e); Displej.Vynulovano += delegate(object sender, EventArgs eZ) { X = Y = M; }; Displej.Zapnuto = true; Displej.Vynulovat(); } /// <summary> /// Indexer (pole) tlačítek na kalkulačce. /// </summary> /// <param name="sloupec">Pořadí sloupce tlačítek počítáno zleva.</param> /// <param name="radek">Pořadí řádku tlačítek počítáno shora.</param> /// <returns>Tlačítko na kalkulačce.</returns> public Tlacitko this[int sloupec, int radek] { set { value.Location = new Point(sloupec * rastr, radek * rastr); value.Parent = this; value.Kalkulacka = this; } } } Objektově orientované programování - Studijní opora 60 Displej /// <summary> /// Implementace displeje pomocí labelu. /// </summary> class Displej : Label, IDisplej { /// <summary> /// Konstruktor pro nastavení vlastností displeje. /// </summary> public Displej() { Dock = DockStyle.Top; TextAlign = ContentAlignment.MiddleRight; Font = new Font("Arial", Ba); BackColor = Color.LightYellow; ForeColor = Color.DarkBlue; } /// <summary> /// Implementace vlastnosti Zapnuto vlastností Enabled. /// </summary> public bool Zapnuto { get { return Enabled; } set { Enabled = value; } } /// <summary> /// Implementace zobrazení hodnoty pomocí vlastnosti Text. /// </summary> public double Hodnota { set { Text = value.ToString(); } } /// <summary> /// Implementace metody Vynulovat sloužící k vymazání displeje. /// </summary> public void Vynulovat() { Hodnota = M; Vynulovano(this, EventArgs.Empty); } /// <summary> /// Implementace události Vynulováno volané po vynulování displeje. /// </summary> public event EventHandler Vynulovano; /// <summary> /// Vynulování displeje doubleclickem. /// Přepsání virtuální metody OnDoubleClick. /// </summary> protected override void OnDoubleClick(EventArgs e) { base.OnDoubleClick(e); Vynulovat(); } } Objektově orientované programování - Studijní opora 61 PrvniKalkulacka /// <summary> /// Třída kalkulaček PrvniKalkulacka. /// </summary> class PrvniKalkulacka : Kalkulacka { /// <summary> /// Konstruktor první kalkulačky /// nastaví vlastnosti, vloží displej a /// přidá základní tlačítka. /// </summary> public PrvniKalkulacka() { Size = new Size(Z`M, ZBM); Text = "První kalkulačka"; { Displej displej = new Displej(); displej.Parent = this; Displej = displej; } this[\, B] = new C(); this[c, Z] = new Cislice(\); this[`, Z] = new Cislice(a); this[b, Z] = new Cislice(Q); this[\, Z] = new Deleno(); this[c, l] = new Cislice(c); this[`, l] = new Cislice(`); this[b, l] = new Cislice(b); this[\, l] = new Krat(); this[c, c] = new Cislice(B); this[`, c] = new Cislice(Z); this[b, c] = new Cislice(l); this[\, c] = new Minus(); this[c, `] = new Cislice(M); this[\, `] = new Plus(); } } Tlacitko /// <summary> /// Tlačítko C pro vymazání (Clear) kalkulačky. /// </summary> class C : Tlacitko { /// <summary> /// Konstruktor tlačítka C. /// Bude červené s nápisem "C". /// </summary> public C() { Text = "C"; BackColor = Color.Red; } /// <summary> /// Při kliknutí vymaže displej. /// Přeprogramovaná virtuální metoda OnClick. /// </summary> protected override void OnClick(EventArgs e) { base.OnClick(e); Kalkulacka.Displej.Vynulovat(); } } Objektově orientované programování - Studijní opora 62 Cislice /// <summary> /// Číslice jsou tlačítka. /// </summary> class Cislice : Tlacitko { /// <summary> /// Konstruktor číslice. /// Tlačítka jsou bílá se zobrazenou číslicí. /// Při kliknutí je číslice přidána k číslu na displeji. /// </summary> /// <param name="cislice">Celočíslená hodnota číslice.</param> public Cislice(int hodnota):base() { Text = hodnota.ToString(); BackColor = Color.White; Click += delegate(object sender, EventArgs e) { Kalkulacka.Y *= BM; Kalkulacka.Displej.Hodnota = Kalkulacka.Y += hodnota; }; } } Operace /// <summary> /// Zobecněná třída operací jako jsou např. /// plus, mínus, krát a děleno. /// </summary> abstract class Operace : Tlacitko { /// <summary> /// Při kliknutí na tlačítko operace je proveden výpočet. /// </summary> protected override void OnClick(EventArgs e) { base.OnClick(e); Kalkulacka.Displej.Hodnota = Kalkulacka.X = Vypocitat(Kalkulacka.X, Kalkulacka.Y); Kalkulacka.Y = M; } /// <summary> /// Virtuální metoda Vypocitat vypočte výsledek operace /// ze zadaných hodnot x a y. /// </summary> /// <param name="x">Hodnota levého operandu, /// číslo před znaménkem operace.</param> /// <param name="y">Hodnota pravého operandu, /// číslo za znaménkem operace.</param> /// <returns>Výsledek operace.</returns> protected abstract double Vypocitat(double x, double y); } Objektově orientované programování - Studijní opora 63 Plus /// <summary> /// Operace plus pro sčítání. /// </summary> class Plus : Operace { /// <summary> /// Konstruktor operace plus nastaví na tlačítku nápis "+". /// </summary> public Plus() { Text = "+"; } /// <summary> /// Vypocitat je přepsaná virtuální metoda operace plus, která sečte čísla x a y. /// </summary> protected override double Vypocitat(double x, double y) { return x + y; } } Minus /// <summary> /// Operace mínus pro odčítání. /// </summary> class Minus : Operace { /// <summary> /// Konstruktor operace mínus nastaví na tlačítku nápis "−". /// </summary> public Minus() { Text = "−"; } /// <summary> /// Vypocitat je přepsaná virtální metoda operace minus, která odečte od čísla x číslo y. /// </summary> protected override double Vypocitat(double x, double y) { return x − y; } } Krat /// <summary> /// Operace krát pro násobení. /// </summary> class Krat : Operace { /// <summary> /// Konstruktor operace krát nastaví na tlačítku nápis "*". /// </summary> public Krat() { Text = "*"; } /// <summary> /// Vypocitat je přepsaná virtuální metoda operace krát, která vynásobí čísla x a y. /// </summary> protected override double Vypocitat(double x, double y) { return x * y; } } Objektově orientované programování - Studijní opora 64 Deleno /// <summary> /// Operace děleno pro dělení. /// </summary> class Deleno : Operace { /// <summary> /// Konstruktor operace děleno nastaví na tlačítku nápis "/". /// </summary> public Deleno() { Text = "/"; } /// <summary> /// Vypocitat je přepsaná virtuální metoda operace děleno, která vydělí číslo x číslem y. /// </summary> protected override double Vypocitat(double x, double y) { return x / y; } } F /// <summary> /// Delegát pro výpočet hodnoty funkce F v bodě x. /// </summary> /// <param name="x">x je argument z definičního oboru funkce.</param> /// <returns>F(x) je funkční hodnota přiřazená číslu x.</returns> delegate double F(double x); Funkce /// <summary> /// Tlačítko funkce /// </summary> class Funkce : Tlacitko { /// <summary> /// Konstruktor tlačítka funkce nastaví nápis, /// zvětší velikost a přidá ovladač události Click /// s výpočtem funkce. /// </summary> /// <param name="text">Nápis na tlačítku funkce.</param> /// <param name="f">Metoda pro výpočet hodnoty funkce.</param> public Funkce(string text, F f) : base() { Text = text; Width = ``; Click += delegate(object sender, EventArgs e) { Kalkulacka.Displej.Hodnota = Kalkulacka.Y = f(Kalkulacka.Y); }; } } Objektově orientované programování - Studijní opora 65 LepsiKalkulacka /// <summary> /// Vylepšení první kalkulačky. /// Přidáme nová tlačítka pro výpočet některých funkcí. /// </summary> class LepsiKalkulacka : PrvniKalkulacka { /// <summary> /// Konstruktor lepší kalkulačky změní záhlaví a /// přidá tlačítka pro odmocninu, trigonometrické /// funkce a logaritmus. /// </summary> public LepsiKalkulacka() { Text = "Lepší kalkulačka"; this[B, B] = new Funkce("sqrt", Math.Sqrt); this[B, Z] = new Funkce("sin", Math.Sin); this[B, l] = new Funkce("cos", Math.Cos); this[B, c] = new Funkce("tan", Math.Tan); this[B, `] = new Funkce("log", Math.LogBM); } } } Průvodce studiem. Uf… Jestli jste dočetli až sem, zasloužíte si velkou odměnu! Objektově orientované programování - Studijní opora 66 Úkol. Pokuste se zprovoznit jednoduchou kalkulačku na Vašem počítači. Úkol. Vyzkoušejte jak kalkulačka počítá. Bude-li se Vám zdát, že nějak divně, nevěšte hlavu, hned si to vysvětlíme. Postfixová notace Jednoduchost jednoduché kalkulačky spočívá v tom, že používá postfixovou notaci, která se lépe programuje. Bohužel se hůře ovládá. Nejdříve se zadává číslo a teprve potom operace. Chceme-li spočítat např. 0*/2−,, musíme stisknout tyto klávesy: Z + B l * b − Shrnutí kapitoly. Jednoduchá kalkulačka je příklad rozsáhlejší aplikace. Její zdrojový kód využijeme k výkladu v dalších kapitolách. Objektově orientované programování - Studijní opora 67 Kapitola a. Deklarace datových typů V této kapitole se dozvíte: Jak deklarovat datové typy. Jak důležité je rozhraní. Co je to dědičnost. Jak používat modifikátory Klíčová slova této kapitoly: Výčet, třída, struktura, rozhraní, dědičnost, modifikátor, zapouzdření. Čas potřebný k prostudování učiva kapitoly: 3 hodiny Deklarace výčtu type declaration → enum declaration → attributes A – / enum modifier A – N enum enum base A – / { enum member declaration ( , enum identifier enum member declaration )A – N , A – / } ; A–/ enum identifier → identifier enum member declaration → attributes A – / identifier ( = constant expression )A – / Výčet – enumeration [iˌnju:mǝˡreišn] jsou pojmenované číselné hodnoty. Počítači se lépe pracuje s čísly a lidem se jmény. Pojmenovat můžeme např. měsíce a roční období. enum Mesic{Leden = B, Unor, Brezen, Duben, Kveten, Cerven, Cervenec, Srpen, Zari, Rijen, Listopad, Prosinec} enum Obdobi{Jaro = B, Leto, Podzim, Zima} A potom místo … int obdobi(int mesic) { switch(mesic) { case l: case c: case `: return B; case b: case \: case a: return Z; case Q: case BM: case BB: return l; case BZ: case B: case Z: return c; default: throw new ArgumentException("Parametr mesic musí být od B do BZ."); } } Objektově orientované programování - Studijní opora 68 … můžeme psát srozumitelněji: Obdobi obdobi(Mesic mesic) { switch(mesic) { case Mesic.Brezen: case Mesic.Duben: case Mesic.Kveten: return Obdobi.Jaro; case Mesic.Cerven: case Mesic.Cervenec: case Mesic.Srpen: return Obdobi.Leto; case Mesic.Zari: case Mesic.Rijen: case Mesic.Listopad: return Obdobi.Podzim; case Mesic.Prosinec: case Mesic.Leden: case Mesic.Unor: return Obdobi.Zima; default: throw new ArgumentException("Parametr mesic není platný."); } } Deklarace delegáta type declaration → delegate declaration Protože delegáti – delegate [deligǝt] jsou odkazy na metody, ponecháme si vysvětlení deklarace delegátů až do kapitoly o metodách. Průvodce studiem. Třídíte? Klasifikujete? Zařazujete? Členíte? Používáte pojmy druh, kategorie, typ, čeleď, odrůda, sortiment? Máte rádi ve všem systém? Potom jsou pro Vás třídy to pravé ořechové. Mimochodem třídíte odpad? Deklarace třídy type declaration → class declaration → attributes A – / class modifier A – N partial A – / class class identifier type parameter list A – / class base A – / type parameter constraints clause A – N { class member declaration A – N } ; A–/ class identifier → identifier Třída – class [kla:s] je soubor objektů stejného typu, které mají stejné vlastnosti, metody a další členy. Příkladem je deklarace třídy Operace z jednoduché kalkulačky. abstract class Operace : Tlacitko { protected override void OnClick(EventArgs e) { base.OnClick(e); Kalkulacka.Displej.Hodnota = Kalkulacka.X = Vypocitat(Kalkulacka.X, Kalkulacka.Y); Kalkulacka.Y = M; } protected abstract double Vypocitat(double x, double y); } Objektově orientované programování - Studijní opora 69 Deklarace struktury type declaration → struct declaration → attributes A – / struct modifier A – N partial A – / struct struct identifier type parameter list A – / struct base A – / type parameter constraints clause A – N { struct member declaration A – N } ; A–/ struct identifier → identifier Struktury – structure [ˡstrakčǝr] se velmi podobají třídám, ale jsou mnohem jednodušší. Používají se jako hodnotové typy. Průvodce studiem. Také Vám většinou stačí vědět jak něco používat a nechcete se zatěžovat tím, z čeho všeho je to vyrobené? Ostatně při dnešní složitosti světa kolem nás na to mnohdy ani nezbývá čas. K řízení auta potřebujeme vědět jak používat volant a ne kolik kuliček je v ložisku klikového hřídele. A právě rozhraní, o kterém se teď něco dozvíte, umožňuje oddělit běžného uživatele od složitých vnitřností. Deklarace rozhraní type declaration → interface declaration → attributes A – / interface modifier A – N partial A – / interface interface identifier type parameter list A – / interface base A – / type parameter constraints clause A – N { interface member declaration A – N } ; A–/ interface identifier → identifier Rozhraní – interface [intǝfeis] je dohoda mezi autorem třídy s implementovaným rozhraním a autorem klientské části programu. Autor klientské části se zavazuje, že bude při práci s objektem používat pouze členy definované v rozhraní. Autor implementace se zavazuje, že naprogramuje všechny členy uvedené v rozhraní. Příkladem rozhraní je IDisplej z jednoduché kalkulačky. Displej je ke kalkulačce připojen přes rozhraní IDisplej. V budoucnu bude možné naprogramovat jiný typ displeje s rozhraním IDisplej, který půjde připojit ke kalkulačce bez nutnosti měnit kód kalkulačky. interface IDisplej { bool Zapnuto { get; set;} double Hodnota {set;} void Vynulovat(); event EventHandler Vynulovano; } Interface IDisplej má vlastnosti Zapnuto a Hodnota, metodu Vynulovat a událost Vynulovano. Malá rozhraní co do počtu členů omezují programátora klientské části. Velká rozhraní nutí autora třídy implemantovat příliš mnoho členů. Obvykle se používají co možná nejmenší rozhraní (inu v jednoduchosti je přece síla). Objektově orientované programování - Studijní opora 70 Průvodce studiem. Lenost − hybná to síla pokroku − budiž pochválena. Nebaví Vás dělat stejnou činnost znovu a znovu? Vezměte již hotové a jen to trochu upravte. Ekonomové nemluví o lenosti, ale řekli by, že je třeba zvýšit efektivitu výroby, a třeba matematici by řekli, že je třeba problém převést na předchozí případ. Objektově orientovaný programátor řekne, že použije bázi. Báze class base → : ( class type | interface type )( , struct base → : interface type ( , interface base → : enum base → : interface type )A – N interface type )A – N interface type ( , interface type )A – N integral type Báze – base [beis] neboli základ představuje obecnější třídu (nadřazený pojem) k deklarované třídě. Chceme-li někomu vysvětlit co je to letadlo, řekneme třeba, že letadlo je dopravní prostředek, který létá. Novou třídu objektů typu letadlo jsme definovali jako podtřídu objektů typu dopravní prostředek. A právě třída dopravních prostředků je bází (bázovou třídou) třídy letadel. V matematice je obvyklý tento zápis: Letadla ⊂ Dopravní prostředky V C# totéž zapíšeme takto: class Letadlo : DopravniProstredek Příklad. Najděte v kódu jednoduché kalkulačky užití báze. Řešení. class Tlacitko : Button class Kalkulacka : Form class Displej : Label, IDisplej class PrvniKalkulacka : Kalkulacka class C : Tlacitko class Cislice : Tlacitko class Operace : Tlacitko class Plus : Operace class Minus : Operace class Krat : Operace class Deleno : Operace class Funkce : Tlacitko class LepsiKalkulacka : PrvniKalkulacka Matemticky bychom mohli psát: Plus ⊂ Operace ⊂ Tlacitko ⊂ Button. Čili třída tlačítek Plus je podtřídou tlačítek operací. Operace patří do obecnější třídy Tlacitko a ta Objektově orientované programování - Studijní opora 71 zase do systémové třídy Button. Dědičnost V této souvislosti se hovoří také o dědičnosti – inheritability [inˌheritǝˡbilǝti], jako jednom ze tří pilířů objektově orientovaného programování. Vysvětlíme si to na třídě LepsiKalkulacka class LepsiKalkulacka : PrvniKalkulacka Matematicky to znamená LepsiKalkulacka ⊂ PrvniKalkulacka. Všechny lepší kalkulačky jsou tedy i první kalkulačky. Jinými slovy: každá lepší kalkulačka umí to co první kalkulačka. A ještě jinak: lepší kalkulačka „zdědila“ vlastnosti první kalkulačky. Při programování lepší kalkulačky nemusíme programovat celou kalkulačku od začátku, ale řekneme, že je to vlastně první kalkulačka a naprogramujeme jen to, co má umět lepší kalkulačka navíc. To je ohromná úspora času programátora a jeden z hlavních důvodů obrovského rozšíření objektově orientovaného programování v praxi. Modifikátory class modifier → new | public | protected | internal | private | abstract | sealed | static struct modifier → new | public | protected | internal | private interface modifier → new | public | protected | internal | private enum modifier → new | public | protected | internal | private delegate modifier → new | public | protected | internal | private Modifikátory používáme ke stanovení rozsahu platnosti jména a u tříd i k řízení dědičnosti. Modifikátor new Modifikátor new – new [nju:] – nový použijeme, tehdy, když jméno již existuje, ale my chceme pod stejným jménem deklarovat něco úplně jiného. Uvedením klíčového slova new do kódu informuje programátor překladač, že si je vědom důsledků, které tím může způsobit. Použít omylem stejné jméno dvakrát je častou chybou, protože to lze provést zcela neúmyslně. Napsat někam omylem „new“ se Vám asi jen tak nepovede. Průvodce studiem. Teď se prosím zastavte a pořádně se rozhlédněte. Nacházíte se v nejkrásnější části krajiny objektově orientovaného programování. Jste poblíž vrcholků hor, ze kterých od nepaměti pramení posvátné řeky. Takže se soustřeďte a tiše hledejte. Stojí to rozhodně za to. Objektově orientované programování - Studijní opora 72 Modifikátor public Modifikátor public – public [pablik] – veřejný zveřejňuje jméno. Jméno je tedy možné používat ve všech částech kódu. Modifikátor protected Modifikátor protected – protect [prǝˡtekt] – chránit chrání jméno před neoprávněným užitím. Jméno lze použít tam, kde bylo deklarováno. Dědicové bázové třídy (v řadě přímé) mají přístup ke jménům označených modifikátorem protected. Z ostatních tříd je jméno nedostupné. Modifikátor internal Má-li být jméno dostupné pouze v daném programu, použijeme modifikátor internal – internal [inˡtǝ:nl] – vnitřní. Při tom nezáleží na dědičné hiearchii tříd. Jde o poměrně spornou záležitost, protože to zbytečně komplikuje kód. Výjimečně se bez modifikátoru internal neobejdete. Ostatně používáte ještě příkaz go to? Správná odpověď zní: co je to příkaz go to? Takže, používáte modifikátor internal? Správná odpoveď zní … Modifikátor private Jméno označené modifikátorem private – private [praivit] – soukromý je soukromé pro danou třídu. Je tedy dostupné pouze tam, kde bylo deklarováno a nikde jinde. Možnost označit jméno modifikátorem private je velmi důležitá. Není-li užit žádný modifikátor, bývá často právě private defaultní hodnotou. Modifikátor private souvisí s jedním ze tří pilířů objektově orientovaného programování a to se zapouzdřením – encapsulation [inˌkæpsjuˡleišǝn]. Privátní jména jsou zapouzdřena uvnitř třídy a od jinud se na ně nikdo nedostane. Změníme-li deklaraci privátního jména, nebo význam toho co znamená, ovlivněný kód je omezen na danou třídu. Čili vše co je třeba upravit je pěkně pohromadě. Změníme-li deklaraci veřejného jména, může se stát, že velké množství kódu nebude fungovat. Ostatně často nemáme ani ponětí o tom, k čemu všemu se náš software používá. Co by se asi stalo při změně veřejných jmen ze systémových knihoven? Jak zařídit, aby všichni programátoři ve všech programech najednou psali místo Form třeba Window? Modifikátor abstract Modifikátorem abstract – abstract [æbstrækt] – abstraktní označujeme zobecněné abstraktní třídy. Příkladem budiž třída tlačítek operací z jednoduché kalkulačky. abstract class Operace : Tlacitko { protected override void OnClick(EventArgs e) { base.OnClick(e); Kalkulacka.Displej.Hodnota = Kalkulacka.X = Vypocitat(Kalkulacka.X, Kalkulacka.Y); Kalkulacka.Y = M; } protected abstract double Vypocitat(double x, double y); } Obecné tlačítko operace nelze vytvořit, na kalkulačce ho tedy neuvidíte. Modifikátor abstract zakazuje volání konstruktoru (čili vytvoření objektu) pomocí operátoru new. Následující kód je tedy chybný. this[`,b] = new Operace(); K čemu jsou tedy abstraktní třídy dobré? Především se používají jako bázové třídy. Třída Operace je bázovou třídou pro třídy Plus, Minus, Krat a Deleno. Třída Operace obsahuje obecný výpočet, který Objektově orientované programování - Studijní opora 73 by bylo jinak nutné programovat v každé třídě zvlášť. Máme-li více tříd, které obsahují podobný kód, můžeme vytvořit společnou abstraktní třídu implementující tento kód a tuto třídu použít jako bázi. Společný kód se mechanismem dědění dostane do všech tříd. Modifikátor sealed Třídu je možné „zapečetit“ modifikátorem sealed – seal [si:l] – pečeť. Takovou třídu nelze použít jako bázi − nemá tedy žádné dědice. Modifikátor sealed se používá výjimečně, zejména u rozsáhlých tříd, kde je autor někdy vůbec rád, že mu to nějak funguje a nechce si komplikovat situaci tím, že by k tomu ještě někdo další něco přidával. Úkol k zamyšlení. Je možné použít modifikátory abstract a sealed najednou? Modifikátor static Statické – static [stætik] třídy jsou prázdné v tom smyslu, že neexistují žádné objekty, které by byly jejich typu. Příkladem je systémová třída Math. Skutečně neexistují žádné matematiky, ale je možné používat statické metody (např. Math.Sin). V podstatě jde o to, jak dostat do objektově orientovaného prostředí procedury a funkce známé z předobjektových technologií (např. ze strukturovaného programování). Někdo by možná řekl, že jde o globální metody, vlastnosti a proměnné, které nezávisí na existenci nějakých objektů. Je sice možné si takto vystačit s jednou statickou třídou, vytvořená aplikace však bude spíše připomínat program, který si vystačí s jedním oknem, a to s příkazovou řádkou. Úkol. Zjistěte, které modifikátory se používají nejčastěji v jednoduché kalkulačce. Deklarace členů Nejdůležitější částí deklarace datového typu, je deklarace jeho členů. Typ může obsahovat konstanty – constant [konstǝnt], pole – field [fi:ld], metody – method [meӨǝd], vlastnosti – property [propǝti], události – event [iˡvent], indexery – index [indeks] – index (češtináři, co s tím?), operátory – operator [opǝreitǝ], konstruktory – constructor [kǝnˡstraktǝ] a destruktory – destructor [diˡstraktǝ]. Dokonce je možné do deklarace jednoho typu zahnízdit – nest [nest] – hnízdo deklaraci jiného typu. Členy třídy class member declaration → constant declaration | field declaration | method declaration | property declaration | event declaration | indexer declaration | operator declaration | constructor declaration | destructor declaration | static constructor declaration | type declaration Objektově orientované programování - Studijní opora 74 Členy struktury struct member declaration → constant declaration | field declaration | method declaration | property declaration | event declaration | indexer declaration | operator declaration | constructor declaration | static constructor declaration | type declaration Členy rozhraní interface member declaration → interface method declaration | interface property declaration | interface event declaration | interface indexer declaration Shrnutí kapitoly. Zdrojový kód v C# se prakticky skládá z deklarací datových typů. Sadu pojmenovaných hodnot deklarujeme jako výčet (enum). K odkazu na metodu používáme delegáta (delegate). Nejběžnějším datovým typem je třída (class) a její zjednodušená podoba – struktura (struct). V rozsáhlejších systémech používáme k oddělení jednotlivých částí rozhraní (interface). Hiearchii tříd udržujeme pomocí dědičnosti. Objektově orientované programování - Studijní opora 75 Kapitola Q. Deklarace členů V této kapitole se dozvíte: Jak používat pole k vnitřní implementaci. Co jsou to metody. Jak podstatný je rozdíl mezi objektovou metodou a neobjektovou funkcí či procedurou. Jaký význam mají vlastnosti, čím se liší od polí a jak je deklarovat. Jak deklarovat události − stěžejní technologii událostmi řízeného programování. Jak vytvořet nové objekty voláním konstruktoru a jak tyto konstruktory deklarovat. Jak správně používat virtuální či dokonce abstraktní metody. Klíčová slova této kapitoly: Konstanta, pole, metoda, delegát, vlastnost, událost, polymorfismus. Čas potřebný k prostudování učiva kapitoly: 0- hodin Deklarace konstanty constant declaration → attributes A – / constant modifier A – N const expression ( , identifier = type identifier = expression )A – N ; Konstanta – constant [konstǝnt] je pojmenovaná hodnota, která se nemění. Hodnota může být určena výrazem, který lze vyhodnotit během překladu. Nemůže tedy obsahovat proměnné. Typickým příkladem konstanty je Ludolfovo číslo π. Členem systémové třídy Math je konstanta Pi. Výpočet obvodu kruhu podle vzorce o = 0πr naprogramujeme takto: o = Z * Math.Pi * r; Deklarace konstanty se skládá z nepovinných atributů a modifikátorů, klíčového slova const, typu konstanty – type [taip], jména čili identifikátoru – identifier [aiˡdentifaiǝ], operátoru „=“, výrazu – expression [ikˡsprešǝn] a středníku. V rámci jedné deklarace je možné deklarovat více konstant stejného typu, jednotlivé konstanty se oddělují čárkou. Příklad. Deklarujeme-li kostantu maxPocetZnaku, … const int maxDelkaRadky = aM, maxPocetRadek = Z`, maxPocetZnaku = maxDelkaRadky * maxPocetRadek; je mnohem srozumitelnější psát … char Text[maxPocetZnaku]; než přemýšlet, proč je zde zrovna číslo 0AAA. char Text[ZMMM]; Objektově orientované programování - Studijní opora 76 Úkol. Najděte v kódu jednoduché kalkulačky deklaraci konstanty. Průvodce studiem. Jak si kdo ustele, tak si lehne. Tak praví známé přísloví. Každý algoritmus pracuje nad nějakými daty. Data objektů se ukládají do polí. Seznamte se nyní s tím, jak pole ustlat tak, aby se v něm Vašim algoritmům dobře leželo. A jestli je toho na Vás dnes už hodně, ustelte si taky a koukněte se na to až zítra. Odpočinek si zasloužíte. Vždyť už jste se toho tolik naučili! Deklarace pole field declaration → attributes A – / field modifier A – N type identifier ( = identifier ( = expression )A – / ( , expression )A – / )A – N ; Čím se liší deklarace pole – field [fi:ld] od deklarace konstanty? Pouze tím, že chybí klíčové slovo const. Hodnota pole se tedy může měnit během chodu programu. Pole představují vlastně jakési vnitřní proměnné tříd a struktur. Pozor na záměnu tohoto pole – field [fi:ld] s polem – array [ǝˡrei] více hodnot stejného typu, ke kterým se přistupuje pomocí indexů. Někteří autoři překládají „field“ jako „položka,“ ale to se zase může plést s jiným pojmem „item.“ Pole obvykle bývají soukromou záležitostí tříd a struktur (viz. modifikátor private.) V souladu principem zapouzdření jsou tedy pole z venku neviditelná. Je sice možné modifikátorem public pole zpřístupnit, ale mnohem lepší je deklarovat např. veřejnou vlastnost a pole nechat soukromé. Všimněte si, že rozhraní žádná pole nemají! Příklad. Třída kalkulačka v kódu jednoduché kalkulačky obsahuje pole X, … public double X; které je veřejné. Rozhodneme-li se z jakéhokoliv důvodu změnit typ pole z double např. na celočíselné int, budeme muset všechno přeprogramovat. Pomocí soukromého pole a veřejné vlastnosti problém elegantně vyřešíme. private int x; public double X { get { return Convert.ToDouble(x); } set { x = Convert.ToIntlZ(value); } } Nyní jsme vlastně zapouzdřili celočíselné pole x uvnitř třídy a na venek máme k dispozici vlastnost X typu double. V této souvislosti stojí za to se ještě zmínit o zvyklostech pojmenování. Jména soukromých členů začínáme malým písmenem a jména nesoukromých (veřejných, chráměných, … ) členů začínáme písmenem velkým. Potom snadno rozlišíme na první pohled, že „Text“ je veřejná vlastnost zatímco „text“ je soukromé pole. Objektově orientované programování - Studijní opora 77 Příklad. Aby kalkulačka uměla počítat se zlomky deklarujeme strukturu Zlomek. Zlomky jak známo mají čitatele a jmenovatele. struct Zlomek { int citatel; int jmenovatel; public int Citatel { get { return citatel; } set { citatel = value; } } public int Jmenovatel { get { return jmenovatel; } set { jmenovatel = value; } } } Díky správnému zapouzdření můžeme snadno doplnit zkrácení zlomku po každé změně čitatele nebo jmenovatele, čímž dosáhneme toho, zlomek bude stále v základním tvaru. struct Zlomek { int citatel; int jmenovatel; public int Citatel { get { return citatel; } set { citatel = value; zkratit(); } } public int Jmenovatel { get { return jmenovatel; } set { jmenovatel = value; zkratit(); } } void zkratit(){…} } Průvodce studiem. A jste nahoře. Konečně se Vám podařilo vylézt na hřeben a spatřit ohromnou krásu objektově orientované země. Je sice ještě trochu zahalena tajuplnou mlhou a dá Vám ještě mnoho úsilí než nahlédnete do všech jejích zákoutí, ale již nyní víte, že jste udělali dobře, když jste došli až sem. Cestou Vás vedly staré dobré průvodkyně Procedura a Funkce. Můžete se s nimi ještě vrátit zpět, nemáte-li dost odvahy. Vězte však, že Metoda je již připravena jít s Vámi dál. Rozlučte se tedy s Procedurou a Funkcí a nechte je se vrátit do neobjektové země. Bude jim tam dobře. Metody Metody – method [meӨǝd] používáme k zápisu (implementaci) algoritmů pro řešení různých úkolů. Metoda může obsahovat libovolné množství příkazů – statement [steitmǝnt]. Metoda je vždy členem nějaké třídy nebo struktury. V objektově orientovaném programování nemůže metoda existovat samostatně. To je podstatný rozdíl odlišující objektově orientované programování od starších technologií (např. strukturovaného programování.) Neobjektové technologie zapisují algoritmy do procedur a funkcí, které jsou nezávislé na datech. Základním neobjektovým pojmem je tedy procedura čili nějaký algoritmus, kterému jemu je třeba předat data. Na prvním místě je tedy činnost (co se bude dělat) Objektově orientované programování - Studijní opora 78 a data (s čím se to bude dělat) jsou až na druhém místě. Tento přístup je sice výhodný pro algoritmicky uvažující programátory, ale pro běžné uživatele je krajně nepřirozený. Mnohem přirozenější je za základní pojem vzít datový objekt (např. textový dokument, obrázek) a teprve potom se zabývat tím, co lze s takovým objektem dělat (např. uložit, vytisknout, převést do jiného formátu.) Objektově orientované programování tedy odpovídá tomu, jak uživatelé pracují s moderními systémy. Nejprve si uživatel prohlíží objekty, které jsou v systému k dispozici, pak si některé z nich vybere a nakonec s nimi provede nějakou akci. Možná jste se setkali se staršími systémy, se kterými se pracuje přesně obráceně. Nejprve uživatel vybere z nabídky co bude dělat (v horším případě napíše jméno příkazu nebo dokonce jen jeho číselný kód) a teprve potom s čím. Z vlastní zkušenosti mohu potvrdit, že je to velmi nepohodlné. Příklad. Ukažme si rozdíl v popisu stejné situace objektovou a neobjektovou technologií. Napřed neobjektově … Na laserové tiskárně vytiskněte do formátu jpeg převedenou na polovinu zmenšenou fotografii auta. … a potom objektově. Fotografii auta zmenšete na polovinu, převeďte do formátu jpeg a vytiskněte na laserové tiskárně. Záludná otázka zní: „Která verze je lepší?“ Odpověď není tak jednoduchá, jak by se mohlo zdát na první pohled. Lidé totiž mají velmi rozdílné zkušenosti a způsoby uvažování. Stejně to dopadne i se zdrojovým kódem programu popisujícím výše uvedenou situaci. V klasickém neobjektovém pojetí vypadá kód takto: Tisk(Laser, Prevod(Jpeg, Zmenseni(M.5, Fotografie(Auto))); Čteme: Budeme tisknout na laserové tiskárně výsledek převodu, kterým převedeme do formátu jpeg výsledek zmenšení na polovinu (A.5) fotografie auta. Objektový kód je naprosto odlišný: Auto.Fotografie.Zmensit(M.5).Prevest(Jpeg).Tisknout(Laser); Čteme: Auta fotografii zmenšíme na polovinu (A.5), převedeme do formátu jpeg a vytiskneme na laserové tiskárně. Jediným problémem je, že v češtině používáme obrácený slovosled než v angličtině. Místo „auta fotografie“ raději říkáme „fotografie auta.“ Totéž platí i pro „knihy název“, „faktury číslo“ apod. Anglické „book title“ a „invoice number“ je však naprosto v pořádku. Naopak nepřirozeně působí „title of book“ a „number of invoice.“ Deklarace metody method declaration → attributes A – / method modifier A – N return type ( interface type method identifier type parameter list A – / ( formal parameter list A – / ) type parameter constraints clause A – N ( ; | { Objektově orientované programování - Studijní opora . )A – / statement A – N } ) 79 Deklaraci metody napšíme tak, že nejprve uvedeme nepovinné atributy – attribute [ætribju:t] a modifikátory – modifier. Vždy musíme uvést návratový typ (return type) a jméno – identifier [aiˡdentifaiǝ] metody (method identifier). Před jménem můžeme uvést rozhraní oddělené tečkou. Rozhraní se používá tehdy, když máme třídu s několika rozhraními, které mají stejnou metodu, ale my chceme tuto metodu implementovat pro každé rozhraní jiným způsobem. Potom musíme uvést, kterého rozhraní se deklarace týká. Následuje nepovinný seznam typových parametů (viz. generické typy.) Další část deklarace metody píšeme do kulatých závorek. Závorky musíme napsat vždy, můžou však zůstat prázdné. Do závorek píšeme seznam formálních parametrů (formal parameter list.) Dále můžeme uvést omezení typových parametrů (viz generické typy.) Na závěr deklarace metody musíme napsat její tělo, skládající se z příkazů napsaných do složené závorky. Tělo metody může být i prázdné. V tom případě můžeme prádnou složenou závorku nahradit pohým středníkem. Identifikátor metody method identifier → identifier Identifikátor metody je jméno, které píšeme při volání metody. Je zvykem velikostí prvního písmene rozlišit viditelnost metody. Soukromé metody (private), které je možné volat pouze z třídy, ve které jsou deklarovány, píšeme s malým písmenem na začátku. Metody, které můžeme volat i zvenku (public, protected, …), píšeme s velkým písmenem na začátku. Seznam formálních parametrů formal parameter list → fixed parameter ( , formal parameter list )A – / | parameter array Seznam formálních parametrů představuje vlastně deklaraci proměnných, jejichž hodnoty (argumenty) zadáváme až při volání metody. Formální parametry jsou dostupné z těla metody. Používají se tedy k předání argumentů metodě. Seznam parametrů obsahuje pevné parametry (fixed parameter) oddělené čárkou. Jsou-li parametry stejného typu, je možné použít pole parametrů (parameter array). Obě možnosti můžeme zkombinovat. Nejprve uvedeme pevné parametry a nakonec pole parametrů. Pevný parametr fixed parameter → attributes A – / ( ref | out )A – / type parameter identifier Pevný parametr se skládá z typu (type) parametru a jména (identifikátoru) parametru (parameter identifier). Na začátek deklarace můžeme uvést atributy (attribute) parametru. Obvyklý způsob práce s parametrem je takový, že počítač vytvoří lokální proměnnou pro každý parametr. Hodnotu uloženou v této proměnné je možné v těle metody změnit přiřazením jiné hodnoty. Tyto změny se projeví pouze uvnitř metody. Říkáme, že parametr je volaný hodnotou. Chceme-li, aby se změny projevily i vně metody, musíme parametr volat odkazem. Do deklarace přidáme klíčové slovo ref, říkáme pak, že parametr je volaný odkazem. Používáme-li parametr volaný odkaz pouze pro zápis hodnot, označíme jej raději klíčovým slovem out. V tomto případě překladač nekontroluje, má-li argument předávaný metodě přiřazenu nějakou hodnotu. Objektově orientované programování - Studijní opora 80 Pole parametrů parameter array → attributes A – / params array type parameter identifier Pole parametrů představuje způsob, jak naprogramovat najednou metody, které se liší jen počtem argumentů. Do deklarace napíšeme klíčové slovo params. Příklad: Deklarujme metodu Max pro nalezení největšího čísla ze zadaných čísel. Nevíme-li však dopředu, kolik těch čísel bude, použijeme pole parametrů. int Max(params int[] cisla) { int max=int.MinValue; foreach(cislo in cisla)if(cislo>max)max=cislo; return max; } Při volání pak můžeme použít libovolný počet parametrů. int x=Max(B,Z,l), y=Max(c,`,b,\,a,Q,BM,BB,BZ,Bl,Bc,B`), z=Max(x,y); Identifikátor parametru parameter identifier → identifier Protože parametry jsou dostupné jen z těla metody, je zvykem psát jejich jména s malým písmenem na začátku. Návratový typ return type → type | void Metody můžeme používat jako funkce, které vrací nějaké hodnoty. Typ této hodnoty je určen návratovým typem. Může jím být libovolný typ (type). V případě, že metoda nic nevrací, použijeme místo typu klíčové slovo void. Metody typu void představují vlastně procedury. Jako procedury lze však volat všechny metody, případná návratová hodnota se jednoduše zahodí a k ničemu se nepoužije. Není-li metoda typu void, musí tělo metody obsahovat příkaz return. Příklad. Typickým příkladem metody je metoda Vypocitat operace plus z jednoduché kalkulačky. class Plus : Operace { … protected override double Vypocitat(double x, double y) { return x + y; } } Objektově orientované programování - Studijní opora 81 Průvodce studiem. Sliby se mají plnit. Takže si teď něco povíme o delegátech. Deklarace delegáta type declaration → delegate declaration → attributes A – / delegate modifier A – N delegate return type delegate identifier type parameter list A – / ( formal parameter list A – / ) type parameter constraints clauses A – / ; delegate identifier → identifier Delegát (delegate) je odkazový datový typ, který odkazuje na metodu. Existence delegátů je umožněna tím, že používáme počítače von Neumanovy architektury, které mají společnou paměť pro data i program. Deklarace delegáta se příliš neliší od deklarace metody. Navíc je zde klíčové slovo delegate. Chybí možnost zadávat rozhraní, protože pro datové typy to nemá smysl. Delegát je samostatný datový typ. To je podstatný rozdíl od metody, která je vždy členem jiného datového typu. Samozřejmostí je, že tělo delegáta neobsahuje žádné příkazy. Příklad. V jednoduché kalkulačce jsme použili delágata pro výpočet hodnoty funkce. Nejprve deklarujeme delegáta F jako metodu s parametrem x, která vrací vypočtenou funkční hodnotu. delegate double F(double x); Potom tohoto delegáta použijeme k deklaraci obecného funkčního tlačítka. class Funkce : Tlacitko { public Funkce(string text, F f) : base() { Text = text; Width = ``; Click += delegate(object sender, EventArgs e) { Kalkulacka.Displej.Hodnota = Kalkulacka.Y = f(Kalkulacka.Y); }; } } Konkrétní tlačítka nakonec vytváříme dosazením konkrétní funkce. new Funkce("sqrt", Math.Sqrt) new Funkce("sin", Math.Sin) Objektově orientované programování - Studijní opora 82 Deklarace metody rozhraní interface method declaration → attributes A – / new A – / return type type parameter list A – / ( formal parameter list A – / ) method identifier type parameter constraints clauses A – / Metoda může být i součástí rozhraní. Máme-li k dispozici objekt s příslušným rozhraním, můžeme volat metody tohoto rozhraní. Příklad. Systémové knihovny obsahují rozhraní IComparable porovnatelných objektů s jedinou metodou CompareTo. namespace System { interface IComparable { int CompareTo(object obj) } } Porovnatelný objekt A lze porovnat s jiným objektem B voláním metody CompareTo. IComparable A = … object B = … … … A.CompareTo(B) … … Průvodce studiem. Nebýt vizuálního vývojového prostředí, bylo by to už skoro všechno. Vracíme se tak nyní na téměř samém konci na téměř samý začátek. Tak, jak se v dobrém dramatu sluší. Vlastnostmi a událostmi jsme začínali, vlastnostmi a událostmi také skončíme. Dosud jsme však jen užívali vlastnosti a události předem připravené. Nyní si ukážeme, jak vytvářet svoje vlastní. Vlastnosti Metody přístupu k polím Protože pole (field) tříd mají být dle pravidel objektově orientovaného programování zapouzdřena, je přístup k nim možný pouze přes metody. To značným způsobem komplikuje situaci. Jak zpřístupnit soukromá pole pomocí metod? Obvykle dříve nebo později vytvoříme dvojici metod, jednu pro získání hodnoty pole (get) a druhou pro nastavení hodnoty pole (set). Objektově orientované programování - Studijní opora 83 Příklad. Mějme třídu XYZ se soukromými poli x, y, z. class XYZ { private double x; private double y; private double z; } Uvnitř třídy můžeme psát z = x + y; Z venku je to však nemožné. Musíme tedy připsat nějaké veřejné metody. class XYZ { private double x; private double y; private double z; public double GetX(){return x;} public void SetX(double value){x=value;} public double GetY(){return y;} public void SetY(double value){y=value;} public double GetZ(){return z;} public void SetZ(double value){z=value;} } Uložení součtu x + y do z je už zvenku možné. XYZ xyz = … … xyz.SetZ(xyz.GetX()+xyz.GetY()); … Vlastnosti Přístupové metody se často vyskytují ve dvojicích get a set. Neušetřili bychom si práci, kdybychom je deklarovali nějak najednou? Volání metod je nepřehledné. Nešlo by metody get a set volat jednodušším způsobem? Odpověď na obě zní ano s použitím vlastností. Nejprve si ukážeme jak se zjednodušší kód předešlého příkladu a potom si vše vysvětlíme. Příklad. Nejprve tedy nová deklarace třídy XYZ. class XYZ { private double x; private double y; private double z; public double X{get{return x;}set{x=value;} public double Y{get{return y;}set{y=value;} public double Z{get{return z;}set{z=value;} } } Objektově orientované programování - Studijní opora 84 A potom její použití. Všimněte si, že zápis výpočtu je podstatně čitelnější. XYZ xyz = … … xyz.Z = xyz.X + xyz.Y; … Deklarace vlastnosti property declaration → attributes A – / property modifier A – N type ( interface type { ( attributes A – / accessor modifier A – / get ( ; | { property identifier ))A – / ( attributes A – / accessor modifier A – / set ( ; | { . )A – / statement A – N } statement A – N } ))A – / } property identifier → identifier Deklarace vlastnosti je vlastně deklarací dvou metod. Návratový typ a parametry se neuvádí, protože jsou „jasné“ ze situace. Metoda pro získání hodnoty vlastnosti (get) má návratový typ stejný jako je typ vlastnosti a nemá žádné parametry. Naopak metoda pro nastavení hodnoty vlastnosti (set) nic nevrací (je typu void), ale má parameter value stejného typu jako má vlastnost. Někdy deklarujeme jen jednu z částí get a set. Nejčastěji pouze část get, potom je vlastnost „pouze pro čtení.“ Méně obvyklou vlastnost „pouze pro zápis“ získáme, když deklarujeme pouze část set. Deklarace vlastnosti nahrazuje deklaraci dvou metod. typ jméno typ jméno_Get void { get jméno_Set ( tělo get ) ( set tělo set } → tělo get typ value ) tělo set Vlastnost používáme stejně jako proměnnou. Podle toho, na které straně výrazu se vyskytuje, je volána příslušná metoda. Při použití na pravé straně je volána metoda get. výraz = jméno ; → výraz = jméno_Get ( ) ; Při použití na levé straně je volána metoda set. jméno = výraz ; → jméno_Set ( výraz ) ; Deklarace vlastnosti rozhraní interface property declaration → attributes A – / new A – / type A – / get ; )A – / ( attributes A – / set property identifier { ( attributes ; )A – / } Vlastnost lze deklarovat i u rozhraní. Obdobně jako u metody platí, že tělo musí být prázdné. Objektově orientované programování - Studijní opora 85 Příklad. Příkladem deklarace vlastnosti je vlastnost Zapnuto displeje z jednoduché kalkulačky. Vlastnost Zapnuto rozhraní IDisplej je implementována pomocí vlastnosti Enabled bázové třídy Label. class Displej : Label, IDisplej { public bool Zapnuto { get { return Enabled; } set { Enabled = value; } } } Události Položme si otázku: je možné volat metody přes hranici objektu? Situace zahrnuje dva případy. Prvním je chceme-li zvenku volat metodu, která je uvnitř objektu. Řešení je jednoduché a metodu prostě zavoláme. Co však budeme dělat v druhém případě, kdy chceme z vnitřku objektu volat nějakou metodu venku? Při deklaraci třídy však vůbec nemáme, ba ani mesmíme mít, ponětí o tom, co je vně kolem objektu. Řešením jsou události. Události lze zvnitřku objektu volat stejně, jako by to byly metody. Zvenku je možné na událost napojit konkrétní metody, které jsou volány při výskytu události. Autor objektu tedy neví, co budou připojené metody dělat, ale ví, jaké mají parametry, a to mu k jejich volání stačí. Událost je zjednodušeně řečeno vlastnost typu EventHandler, což je delegát, který má dva parametry. Prvním je objekt, který událost vyvolal. Druhým jsou argumenty události odvozené od třídy EventArgs. Zvláštností je, že na jednu událost je možné zavěsit více delegátů, a tím vlastně určit, co všechno se má provést při výskytu události. Delegáta vytvoříme buď odkazem na již existující metodu. new EventHandler(JmenoMetody) Nebo užijeme anonymní metodu. delegate(object sender, EventArgds e){ … } Deklarace události event declaration → attributes A – / event modifier A – N event delegate type identifier ; Deklarace události je jednoduchá. Od deklarace pole (field) se liší jen přidáním klíčového slova event. Samozřejmě typ musí být odvozen od systémového typu EventHandler. Příklad. Displej jednoduché kalkulačky má událost Vynulovano. public event EventHandler Vynulovano; Objektově orientované programování - Studijní opora 86 K vyvolání události Vynulovano dochází v metode Vynulovat. Událost Vynulovano vlastně informuje vnější svět o tom, že displej byl vynulován. public void Vynulovat() { Hodnota = M; Vynulovano(this, EventArgs.Empty); } Deklarace události rozhraní interface event declaration → attributtes A – / new A – / event delegate type identifier ; Událost může být deklarována i v rozhraní. Způsob deklarace se téměř nemění. Průvodce studiem. Už je to skoro všechno. Z důležitých věcí zbývá snad jen konstruktor a jedna taková maličkost. Následující část textu tedy nemusíte číst příliš pozorně. Je určen hlavně pro zájemce, kteří chtějí mít kompletní informace o jazyce C#. Na konstruktor a zmíněnou maličkost Vás včas upozorním. Deklarace indexeru indexer declaration → attributes A – / indexer modifiers A – / type ( interface type [ formal parameter list ] . )A – / this { ( attributes A – / accessor modifier A – / get ( ; | { A – N } ))A – / ( attributes A – / accessor modifier A – / set ( ; | { statement statement A – N } ))A – / } Můžeme-li pomocí vlastnosti zařídit, aby se objekt (či spíše ona vlastnost) dal používat jako proměnná, nešlo by nějak zařídit, aby objekt fungoval jako pole (array)? Řešením je použít indexer. Dalo by se říci, že je to vlastnost s parametry. Ale všimněte si, že místo jména je uvedeno jen klíčové slovo this. Indexer tedy nemá jméno a každý objekt může mít indexer jen jeden. S objektem můžeme pracovat jako s polem. Hodnoty indexů uvádíme do hranatých závorek. Na rozdíl od pole však nejsme omezeni na celočíselné (int) indexy. Indexem tak může být třeba řetězec (string). Příklad. Příklad užití indexeru najdeme opět v kódu jednoduché kalkulačky. class Kalkulacka : Form { public Tlacitko this[int sloupec, int radek] { set { value.Location = new Point(sloupec * rastr, radek * rastr); value.Parent = this; value.Kalkulacka = this; } } } Objektově orientované programování - Studijní opora 87 Indexer můžeme využít například takto. Kalkulacka kalkulacka = new Kalkulacka(); kalkulacka[\, B] = new C(); kalkulacka[c, Z] = new Cislice(\); kalkulacka[`, Z] = new Cislice(a); S kalkulačkou tedy díky indexeru můžeme pracovat jako s polem. Při užití indexeru z vnitřku objektu, použijeme klíčové slovo this. this[\, B] = new C(); this[c, Z] = new Cislice(\); this[`, Z] = new Cislice(a); Deklarace indexeru rozhraní interface indexer declaration → attributes A – / indexer modifiers A – / type ( interface type )A – / this [ formal parameter list ] { ( attributes A – / accessor modifier A – / get ( attributes A – / accessor modifier A – / set . ; )A – / ; )A – / } Pro těsnou souvislost indexeru s vlastností nikoho jistě nepřekvapí, že indexer lze deklarovat i pro rozhraní. Rozdíl je opět pouze ten, že těla metod get a set jsou prázdná. Část pro zájemce. Deklarace operátoru operator declaration → unary operator declaration | binary operator declaration | conversion operator declaration Je možné deklarovat i operátory. Jedná se o metody, které jsou volány k vyhodnocení výrazů. Příklad. Máme deklarovánu strukturu Zlomek s násobením. struct Zlomek { public double Citatel; public double Jmenovatel; public Zlomek Krat(Zlomek cinitel) { Zlomek soucin = new Zlomek(); soucin.Citatel = Citatel * cinitel.Citatel; soucin.Jmenovatel = Jmenovatel * cinitel.Jmenovatel; return soucin; } } Objektově orientované programování - Studijní opora 88 Součin 2/- a 8/2 naprogramujeme takto. Zlomek A = new Zlomek(); A.Citatel = l; A.Jmenovatel = `; Zlomek B = new Zlomek(); B.Citatel = a; B.Jmenovatel = l; Zlomek C = A.Krat(B); Nebylo by však hezčí místo poslední řádky psát … Zlomek C = A * B; A právě toho dosáhneme deklarací operátoru. struct Zlomek { public Zlomek operator *(Zlomek x, Zlome y) { return x.Krat(y); } } Deklarace unárního operátoru attributes A – / operator modifier A – N type ) ( ; | { operator overloadable unary operator ( type identifier statement A – N } ) Výsledek unární operace se počítá z jedné hodnoty. Deklarace je podobná deklaraci metody. Přetěžovatelné unární operátory overloadable unary operator → + | − | ! | ~ | ++ | −− | true | false Unárními operacemi, které lze deklarovat, jsou: +x, −x, !x, ~x, ++x, −−x, true x a false x. Deklarace binárního operátoru attributes A – / operator modifier A – N type , type identifier ) ( ; | { operator overloadable binary operator ( type identifier statement A – N } ) Výsledek unární operace se počítá z jedné hodnoty. Deklarace je podobná deklaraci metody. Přetěžovatelné binární operátory overloadable unary operator → + | − | * | / | % | & | | | ^ | << | >> | == | != | > | < Binárními operacemi, které lze deklarovat, jsou x+y, x−y, x*y, x/y, x%y, x&y, x|y, x^y, x<<y, x>>y, x==y, x!=y, x>y a x<y. Objektově orientované programování - Studijní opora 89 Konverze Konverze slouží k převodu dat jednoho typu na jiný. Konverze může být implicitní, to znamená, že ji není třeba uvádět, protože se provede vždy. Explicitní konverzi je třeba v kódu uvést, protože může nastat výjimka, kdy konverzi nepůjde dokončit. Příklad. Konverze z int na long je implicitní, protože všechna čísla typu int jsou zároveň čísly typu long. Opačná konverze z long na int musí být deklarována explicitně, protože ne všechna čísla typu long se „vejdou“ do typu int. int a=Ba; long b=a; // správně, implicitní konverze je možná int c=b; // špatně, implicitní konverze není možná int d=(int)b; //správně, explicitní konverze je možná Deklarace konverzního operátoru attributes A – / operator modifier A – N ( implicit | explicit ) operator ) ( ; | { type ( type identifier statement A – N } ) Deklarace konverzního operátoru je obdobou předcházejících deklarací, takže místo zbytečného vysvětlování si uvedeme jen příklad. Příklad. Naprogramujte implicitní převod (konverzi) zlomků na double. struct Zlomek { … public implicit operator double(Zlomek a) { return a.Citatel / a.Jmenovatel; } } Potom je možné psát: Zlomek a = new Zlomek(Ba, ZB); double b = a; Průvodce studiem. Máte někdy neodolatelnou touhu tvořit? Pořiďte si konstruktor! Použití konstruktoru je jediný způsob jak vytvořit nějaký objekt. Objektově orientované programování - Studijní opora 90 Deklarace konstruktoru constructor declaration → attributes A – / constructor modifiers A – / constructor identifier formal parameter list A – / ) constructor initializer A – / ( ; | { ( statement A – N } ) Konstruktor (constructor) je zvláštní metoda, která se používá k vytváření (konstrukci) objektů dané třídy. Protože návratový typ je shodný s type třídy, neuvádíme jej. Jméno konstruktoru je stejné jako jméno třídy a to včetně velikosti písmen. Takže pokud jméno třídy začíná velkým písmenem, začínají jména konstruktorů též velkým písmenem. Nezáleží na tom, jsou-li konstruktory soukromé nebo veřejné. Konstruktor je metoda, takže může mít i parametry, které se často používají k nastavení výchozích hodnot. Konstruktor voláme s klíčovým slovem new. Další zvláštností konstruktoru je, že se v něm nepoužívá příkaz return. Příklad. Přidáme do zlomku konstruktor. struct Zlomek { … public Zlomek(double citatel, double jmenovatel):base() { Citatel = citatel; Jmenovatel = jmenovatel; } } Kód pro násobení 2/- a 8/2 se pak výrazně zjednodušší. Zlomek A = new Zlomek(l, `), B = new Zlomek(a, l), C = A * B; Nebo dokonce až takto! Zlomek C = new Zlomek(l, `) * new Zlomek(a, l); Inicializace konstruktoru constructor initializer → : ( base | this ) ( argument ( , argument )A – / )A – / ) Protože nemáme žádné přímé prostředky, jak vytvořit nějaký objekt, nezbývá nám nic jiného, než využít konstruktor bázové třídy. Tomu můžeme předat nějaké argumenty, případně vybrat, který z konstruktorů bude volán. Bázový konstruktor voláme klíčovým slovem base. Konstrukci můžeme odvodit i od jiného konstruktoru téže třídy, pak použijeme klíčové slovo this. Není-li inicializace konstruktoru uvedena, je volán konstruktor bázové třídy se stejnými parametry jako má deklarovaný konstruktor. Pozor tedy na to, že při uvedení parametru do konstruktoru je obvykle nutné volat bázový kostruktor bez parametrů. public Zlomek(double citatel, double jmenovatel):base() Objektově orientované programování - Studijní opora 91 Deklarace statického konstruktoru static constructor declaration → attributtes A – / extern A – / static ; | { constructor identifier ( ) ( statement A – N } ) Zvláštním konstruktorem je konstruktor statický. Používá se k výchozímu nastavení celé třídy, zejména statických polí a vlastností. Nemá žádné parametry. Nelze jej nijak volat, kromě toho, že je jednou automaticky vyvolán, před vytvořením prvního objektu dané třídy. Deklarace destruktoru destructor declaration → attributtes A – / extern A – / ~ destructor identifier ( ) ( ; | { statement A – N } ) Protože systém používá GarbageCollector pro likvidaci nepotřebných objektů a tím automaticky uvolňuje již nepoužívanou paměť, nevoláme destruktor nikdy přímo. Může se však stát, že potřebujeme provést nějaké činnosti při likvidaci objektu. K tomu můžeme využít destruktor. Poznáme jej podle toho, že před jeho jménem je tilda (vlnka). Nemá žádné parametry. Bohužel není jisté, kdy dojde k volání destruktoru a zlí jazykové dodávají, jestli vůbec. Chceme-li např. po ukončení práce se souborem tento zavřít, je lepší implementovat metodu Dispose rozhraní IDisposable a použít např. příkaz using. Modifikátory Obdobně jako datové typy můžou mít i jejich členy různé modifikátory. constant modifier → new | public | protected | internal | private field modifier → new | public | protected | internal | private | static | readonly | volatile method modifier → new | public | protected | internal | private | static | virtual | sealed | override | abstract | extern property modifier → new | public | protected | internal | private | static | virtual | sealed | override | abstract | extern event modifier → new | public | protected | internal | private | static | virtual | sealed | override | abstract | extern indexer modifier → new | public | protected | internal | private | virtual | sealed Objektově orientované programování - Studijní opora 92 | override | abstract | extern operator modifier → public | static | extern constructor modifier → public | protected | internal | private | extern Modifikátor new Chceme-li použít jméno, které je v bázové třídě již použito, musíme přidat do deklarace modifikátor new. Pozor však na to, že když máme jedno jméno pro dvě naprosto odlišné věci, snadno dojde k záměně. Na těžko odhalitelnou chybu v programu tak máme „zaděláno“. Modifikátory public, protected, internal, private Modifikátory ovliňující viditelnost členů, mají stejný význam jako u datových typů. Úkol. Zopakujte si modifikátory public, protected, internal a private. Modifikátor static Statické členy deklarujeme s modifikátorem static. Statický člen je vázán na celou třídu objektů. Příkladem může být statická vlastnost společná pro všechna tlačítka. Není možné nastavit takovou vlastnost pro každé tlačítko zvlášť, jak je obvyklé. Může se to však hodit třeba v případě, kdy chceme mít společnou grafickou úpravu pro celou třídu dokumentů. Průvodce studiem. Dokonalosti se dosahuje maličkostmi, ale dokonalost sama není maličkost. Spolu s klasikem se nyní podívejme na jednu takovou maličkost. Vím, že už je toho na Vás hodně, ale prosím vydržte! Modifikátor virtual Člen označený modifikátorem virtual je virtuální. Je-li v bázové třídě nějaký virtuální člen, je možné jej znovu předeklarovat. Bázová třída má např. virtuální metodu, může jí zavolat, ale neví která konkrétní metoda bude provedena. Označí-li autor třídy metodu jako virtuální, říká tím, že jím naprogramovaná implementace metody je výchozí, ale autoři dalších tříd ji můžou změnit. Potomci takové třídy sice virtuální metodu zdědí, ale můžou si jí „přestavět“ podle svých potřeb. Obrovským možnostem, které virtuální metody umožňují, vděčí objektově orientované programování za jeden ze svých tří piliřů − polymorfismus. Polymorfismus čili přizpůsobení umožňuje psát obecné (abstraktní) třídy s obvyklou implementací a výjimky řešit zvlášť. Příklad. Deklarujeme třídu zvířat a implementujeme pohyb pomocí nohou (např. metody UdelatKrok a Otocit). Slona deklarujeme jako zvíře, které má chobot a silné nohy. Lva deklarujeme jako zvíře, které má hřívu a rychlé nohy. Velblouda deklarujeme jako zvíře, které má hrby a obyčejné nohy. Všichni se umí přesunout dopředu o jeden krok a otočit se. Objektově orientované programování - Studijní opora 93 Vše se zdá být v pořádku, ale pak přijde na řadu ryba. Rybu deklarujeme jako zvíře, které má ploutve a šupiny. Pohyb však nefunguje, protože rybě chybí nohy! Co s tím? Říci, že ryba není zvíře, nemůžeme. Nezbývá než implementovat pohyb pro každou třídu zvířat zvlášť. Jenže slony, lvy a velbloudy už máme hotové. Dokonce si ani nemůžeme být jisti, že někdo jiný mezitím nenaprogramoval další zvířata. Navíc kód pro pohyb pomocí nohou by byl stejný, vždyť to přece všechno tak pěkně fungovalo, než si někdo vymyslel, že tam chce mít tu zatracenou rybu. Polymorfismus nabízí velmi elegantní řešení. Metody pro pohyb zvířete deklarujeme jako virtuální. Takže milá rybo: když už jednou jseš zvíře, musíš se umět přesunout o kus dopředu metodou UdelatKrok. Nohama se to dělá tak a tak, ale jestli se ti to, rybo, nelíbí, tak si dělej krok jak chceš sama. A totéž s otáčením, musíš se umět otočit metodou Otocit. Doporučuji ti udělat nohama to a to, ale rozhodnutí je na tobě. Všechno je už v pořádku, zbývá jen doučit rybu UdelatKrok a Otocit s pomocí poloutví. Ty zvířecí rady co s nohama může ryba klidně zapomenout. Modifikátor sealed Zapečetěnou (sealed) virtuální metodu už nelze dále měnit. Příklad. Řekneme-li, že metoda Otocit je ve třídě Ryba zapečetěná, není už možné, aby se malé ryby točily třeba doleva a velké doprava. Modifikátor override Abychom omylem nepřepsali nějakou virtuální metodu, je třeba vždy při deklaraci nové implementace virtuální metody uvést modifikátor override. Modifikátor abstract Abstraktní metoda je virtuální metoda, která však nemá žádnou obecnou implementaci. Musí být tedy přepsána v konkrétních třídách. Příklad. Tlačítko Operace z jednoduché kalkulačky má virtuální metodu Vypocitat. Tlačítka jednotlivých operací (plus, minus, … ) tuto metodu přepisují implementací výpočtu (sčítání, odčítání, … ). Společný kód je však umístěn ve třídě Operace, která je bázovou třídou tlačítek operací. Modifikátor extern Deklarace vnější (externí) metody. Může jít například o přímé volání funkcí WinAPI z knihovny kernel20.dll apod. Část pro zájemce. Atributy attributes →( [ (( identifier | keyword ) : )A – / attribute ( , Objektově orientované programování - Studijní opora attribute )A – N , A – / ] 94 )/ – N attribute → attribute name ( ( attribute argument ( , attribute argument )A – N ) )A – / attribute name → type name attribute argument →( identifier = )A – / expression Pomocí atributů je možné nastavovat další vlastnosti, které nejsou přímou součástí jazyka. Řada atributů je deklarována v systémových knihovnách. Můžete si však deklarovat i atributy vlastní. Pomocí reflexe (System.Reflection) je možné číst atributy i programově. Příklad. Atribut Obsolete znamená zastaralý. Chceme např. používat novou metodu s kódem místo staré, ale starou musíme kvůli kompatibilitě implementovat taky. Jen ji označíme, že už se nemá používat. class OknoZ : Okno { [Obsolete("Používejte novou metodu NovaMetoda.")] public override void Metoda(){…} public virtual void NovaMetoda(int Kod){…} } Příklad. Globální atribut, kterým můžeme zadat číslo verze. [assembly:AssemblyVersion("B.0.0.0")] Část pro zájemce. Generické typy type parameter list → < attributes A – / identifier ( , type argument list → < type ( , attributes A – / identifier )A – N > type )A – N > type parameter constraints clause → ( where type parameter : type parameter constraint ( , type parameter constraint )A – N )/ – N type parameter constraint → class type | interface type | type parameter | class | struct | new ( ) Generické typy si vysvětlíme na příkladě. Objektově orientované programování - Studijní opora 95 Příklad. Mějme naprogramovaný zásobník objektů. class Stack { public void Push(object obj){…} public object Pop(){…} } Použijme nyní v kódu zásobník čísel a zásobník textů: Stack zasobnikCisel = new Stack(), zasobnikJmen = new Stack(); zasobnikCisel.Push(B); zasobnikCisel.Push(Z); zasobnikCisel.Push(l); zasobnikJmen.Push("Adam"); zasobnikJmen.Push("Božena"); zasobnikJmen.Push("Cyril"); Nyní můžeme ze zásobníků začít vyndavat. object cislo = zasobnikCisel.Pop(); object jmeno = zasobnikJmen.Pop(); Jenže cislo a jmeno jsou takhle pouhé objekty. Kdybychom chtěli použít správný typ, museli bychom provést externí konverzi, což není hezké. int cislo = (int)(zasobnikCisel.Pop()); string jmeno = (string)(zasobnikJmen.Pop()); Možná Vás napadne, vyřešit problém deklarací dvou typů zásobníku. class IntStack { public void Push(int i){…} public int Pop(){…} } class StringStack { public void Push(string s){…} public string Pop(){…} } Potom můžeme psát: IntStack zasobnikCisel = new IntStack(); StringStack zasobnikJmen = new StringStack(); zasobnikCisel.Push(B); zasobnikCisel.Push(Z); zasobnikCisel.Push(l); zasobnikJmen.Push("Adam"); zasobnikJmen.Push("Božena"); zasobnikJmen.Push("Cyril"); int cislo = zasobnikCisel.Pop(); string jmeno = zasobnikJmen.Pop(); Řešení je to polovičaté, protože musíme implementovat každý zásobník zvlášť. Co když budeme potřebovat ještě zásobníky oken, tlačítek, barev a kdoví čeho dalšího? Naší záchranou je deklarace generického zásobníku objektů obecného typu T, který bude určen až později. Objektově orientované programování - Studijní opora 96 class Stack<T> { public void Push(T i){…} public T Pop(){…} } Nyní můžeme používat zásobníky takto: Stack<int> zasobnikCisel = new Stack<int>(); Stack<string> zasobnikJmen = new Stack<string>(); zasobnikCisel.Push(B); zasobnikCisel.Push(Z); zasobnikCisel.Push(l); zasobnikJmen.Push("Adam"); zasobnikJmen.Push("Božena"); zasobnikJmen.Push("Cyril"); int cislo = zasobnikCisel.Pop(); string jmeno = zasobnikJmen.Pop(); Průvodce studiem. Toť vše. Zbývá už jen pár otázeček a nějaký ten úkol. Otázky. Znáte tři pilíře objektově orientovaného programování? Které členy mohou být součástí rozhraní? Proč je nutné v konkrétní třídě přepisovat abstraktní metody? Úkol. Rozšiřte kalkulačku o další funkce z třídy Math. Úkol. Naprogramujte do kalkulačky další funkce jako je např. faktoriál n! = n(n−/)(n−0)…2.2.1. Úkol. Pokuste se upravit kalkulačku tak, používala běžnou notaci. Čili pro výpočet 2+0−/ použít tlačítka l + Z − B = místo postfixového zápisu na jednoduché kalkulačce l + Z + B − Úkol. Rozšiřte kalkulačku o výpočty se zlomky. Objektově orientované programování - Studijní opora 97 Úkol. Přidejte na kalkulačku přepínání režimu stupně − radiány a patřičným způsobem upravte výpočet goniometrických funkcí (sin, cos, tan). Úkol k zamyšlení. Doplňte do kalkulačky závorky. Korespondenční úkol. Odevzdejte ke kontrole zdrojový kód Vaší kalkulačky. Nemusíte nutně splnit všechny výše uvedené úkoly, ale zkuste to. Můžete samozřejmě přidělat i nějaká vlastní vylepšení. V tom případě odevzdejte i popis toho, co všechno už Vaše kalkulačka umí. Shrnutí kapitoly. Datové typy mají členy. Stálé hodnoty deklarujeme jako konstanty (const), proměnné jako pole (field). Přístup nastavujeme pomocí modifikátorů (např. public, private). Pole jsou obvykle privátní ve shodě s principem zapouzdření. Přístup k nim je možný pomocí metod. K předání dat do metody používáme parametry. Návratová hodnota umožňuje předání dat z metody. Díky technologii polymorfismu můžeme měnit implementaci viruálních metod. Volání metod pro čtení a zápis hodnoty zjednodušíme použitím vlastnosti (property). K volání metod vně objektu použijeme události (event). Dále můžeme deklarovat indexery (indexer), operátory (operator), konstruktory (constructor) a destruktory (destructor). Objektově orientované programování - Studijní opora 98 Závěr Po prostudování této opory vytváříte své první windowsové aplikace. Překládáte je ze zdrojového kódu, který si píšete sami v některém z textových editorů nebo jej vytváříte pomocí vizuálního vývojového prostředí. Nastavujete vlastnosti programu a oken. Tyto vlastnosti umíte změnit po nějaké události. Rozumíte základní struktuře zdrojového kódu, víte jak deklarovat datové typy. Vyznáte se v používání jmenných prostorů. Znáte základní vlastnosti formulářů čili oken. Umíte nastavit text, barvu, kurzor, ikony a mnohé další. Máte přehled o základních událostech a umíte napsat kód, který na ně reaguje např. změnou nějaké vlastnosti. Zaměřili jsme se zejména na události vyvolané uživatelem. K ovládání dovedete použít zejména myš a klávesnici. Základními událostmi, které ovládáte, jsou klikání a posun myší a stisk kláves na klávesnici. Na formuláře umísťujete ovládací prvky. Používáte různá tlačítka, popisky, textová a zaškrtávací pole. Znáte jejich základní vlastnosti a události. V 6. kapitole jste se seznámili s rozsáhlejší aplikací – jednoduchou kalkulačkou. Její zdrojový kód vám posloužil ke studiu dalších kapitol. A v závěru studia jste tuto kalkulačku jistě vylepšili o další funkce. Znáte datové typy výčet, delegát, třída, struktura a rozhraní. Při návrhu aplikací používáte dědičnost tříd. Deklarujete členy typů (konstanty, pole, metody, delegáty, vlastnosti, události, indexery, operátory, konstruktory a destruktory). U metod ovládáte předávání dat pomocí parametrů a návratové hodnoty. Seznámili jste se s technologií zapouzdření a polymorfismu. Celou oporu včetně rozsáhlých příloh můžete nyní používat jako referenční příručku při programování vlastních aplikací. Průvodce studiem. Může Vám to připadat neuvěřitelné, ale opravdu jste to zvládli. Doufám že čas, který jste strávili nad touto publikací, nebude pro Vás nikdy časem ztraceným. Ať už budete aplikace vyvíjet nebo je jen užívat, přeji Vám, aby obsahovaly co nejméně chyb, pokud možno žádné. O totéž jsem se snažil při psaní tohoto textu. Pokud Vám přece jen nějaká chyba způsobí problémy, věřte, že mne to velmi mrzí a předem se omlouvám. A protože studium vlastně nikdy nekončí, třeba zase někdy na shledanou. Objektově orientované programování - Studijní opora 99 Příloha A: Lexikální gramatika Lexikální gramatika je soubor pravidel lexikální analýzy. Lexikální analýza zdrojového kódu převádí posloupnost znaků na posloupnost tokenů. Vstup input → input section part A – N input section part → input element A – N new line | pp directive new line → cr | lf | cr lf input element → whitespace | comment | token input element → whitespace →( Zs | ht | vt | ff )/ – N Soubor se zdrojovým kódem obsahuje právě jeden vstup, dle výše uvedeného pravidla. Vstup (input) může obsahovat oddělovače řádek (new line), direktivy preprocesoru (pp directive), bílá místa (whitespace), komentáře (comment) a tokeny (token). Komentáře input element → comment → single line comment | delimited comment input element → comment → single line comment → / input element → comment → delimited comment → / / ( character − cr − lf )A – N * ( character − * | * / – N ( character − / ))A – N * / – N / Objektově orientované programování - Studijní opora 100 Příklad. Komentáře jsou vyznačeny žlutě, direktivy preprocesoru zeleně. Vše ostatní jsou tokeny. namespace blek.cz.Programovani.PrvniProgram { partial class FormB { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support − do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // FormB // this.AutoScaleDimensions = new System.Drawing.SizeF(bF, BlF); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.Lime; this.ClientSize = new System.Drawing.Size(ZQZ, bb); this.Name = "FormB"; this.Text = "První okno"; this.Click += new System.EventHandler(this.FormB_Click); this.ResumeLayout(false); } #endregion } } Objektově orientované programování - Studijní opora 101 Tokeny input element → token → keyword | identifier | literal | operator | punctuator Klíčová slova input element → token → keyword → abstract | as | base | bool | break | byte | case | catch | char | checked | class | const | continue | decimal | default | delegate | do | double | else | enum | event | explicit | extern | false | finally | fixed | float | for | foreach | goto | if | implicit | in | int | interface | internal | is | lock | long | namespace | new | null | object | operator | out | override | params | private | protected | public | readonly | ref | return | sbyte | sealed | short | sizeof | stackalloc | static | string | struct | switch | this | throw | true | try | typeof | uint | ulong | unchecked | unsafe | ushort | using | virtual | void | volatile | while input element → token → keyword → abstract → a input element → token → keyword → as → a b s t r a c t s a tak dále až do input element → token → keyword → while → w Objektově orientované programování - Studijní opora h i l e 102 Příklad. Klíčová slova jsou vyznačena žlutě. namespace blek.cz.Programovani.PrvniProgram { partial class FormB { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support − do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // FormB // this.AutoScaleDimensions = new System.Drawing.SizeF(bF, BlF); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.Lime; this.ClientSize = new System.Drawing.Size(ZQZ, bb); this.Name = "FormB"; this.Text = "První okno"; this.Click += new System.EventHandler(this.FormB_Click); this.ResumeLayout(false); } #endregion } } Objektově orientované programování - Studijní opora 103 Identifikátory identifier or keyword →( letter | _ )( letter | Pc | Nd )A – N input element → token → identifier → identifier or keyword − keyword | @ identifier or keyword Příklad. Identifikátory jsou vyznačeny žlutě. namespace blek.cz.Programovani.PrvniProgram { partial class FormB { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support − do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // FormB // this.AutoScaleDimensions = new System.Drawing.SizeF(bF, BlF); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.Lime; this.ClientSize = new System.Drawing.Size(ZQZ, bb); this.Name = "FormB"; this.Text = "První okno"; this.Click += new System.EventHandler(this.FormB_Click); this.ResumeLayout(false); } #endregion } } Objektově orientované programování - Studijní opora 104 Hodnoty input element → token → literal → null literal | boolean literal | integer literal | real literal | character literal | string literal Příklad. Hodnoty jsou vyznačeny žlutě. namespace blek.cz.Programovani.PrvniProgram { partial class FormB { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support − do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // FormB // this.AutoScaleDimensions = new System.Drawing.SizeF(bF, BlF); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.Lime; this.ClientSize = new System.Drawing.Size(ZQZ, bb); this.Name = "FormB"; this.Text = "První okno"; this.Click += new System.EventHandler(this.FormB_Click); this.ResumeLayout(false); } #endregion } } Prázdná hodnota input element → token → literal → null literal → null Objektově orientované programování - Studijní opora 105 Logické hodnoty input element → token → literal → boolean literal → true | false Číslené hodnoty input element → token → literal → integer literal → ( decimal digit / – N | M /–N)( u | l | u l | l x hex digit u )A – / decimal digit → M | B | Z | l | c | ` | b | \ | a | Q hex digit → M | B | Z | l | c | ` | b | \ | a | Q | a | b | c | d | e | f input element → token → literal → real literal → ( decimal digit A – N . )A – / decimal digit / – N ( e − A – / decimal digit / – N )A – / ( f | d | m )A – / Textové hodnoty input element → token → literal → character literal → ' character → character − ' − \ − cr − lf | \ character ' escape sequence escape sequence → ' | " | \ | M | a | b | f | n | r | t | v | x hex digit / – 3 input element → token → literal → string literal → regular string literal | verbatim string literal regular string literal → " regular string character A – N " regular string character → character − " − \ − cr − lf | \ verbatim string literal → @ " (( character − " )| " escape sequence " )A – N " Operátory a interpunkční znaménka input element → token → operator or punctuator → { | } | [ | ] | ( | ) | . | , | : | ; | + | − | * | / | % | & | | | ^ | ! | ~ | = | < | > | ? | ++ | −− | && | || | == | −> | != | <= | >= | += | −= | *= | /= | %= | &= | |= | ^= | << | >> | <<= | >>= | :: Objektově orientované programování - Studijní opora 106 input element → token → operator or punctuator → { → { input element → token → operator or punctuator → } → } a tak dále až do input element → token → operator or punctuator → :: → : : Příklad. Operátory a interpunkční znaménka jsou vyznačena žlutě. namespace blek.cz.Programovani.PrvniProgram { partial class FormB { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose (bool disposing) { if (disposing && (components != null)) { components .Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support − do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // FormB // this.AutoScaleDimensions = new System.Drawing.SizeF(bF, BlF); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.Lime; this.ClientSize = new System.Drawing.Size(ZQZ, bb); this.Name = "FormB"; this.Text = "První okno"; this.Click += new System.EventHandler(this.FormB_Click); this.ResumeLayout(false); } #endregion } } Objektově orientované programování - Studijní opora 107 Příloha B: Unicode Znaky character → letter | number | symbol | punctuation | separator | other Znaky – character [ˡkærǝktǝr] dělíme na písmena – letter [ˡletǝr], čísla – number [ˡnambǝr], symboly – symbol [ˡsimbl], interpunkční znaménka – punctuation [paŋkčuˡeišn], oddělovače – separator [ˡsepǝreitǝr] a jiné znaky – other [ˡaðǝr]. Písmena character → letter → Lu | Ll Písmena – letter [ˡletǝr] dělíme na velká (třída Lu) a malá (třída Ll). Velká písmena character → letter → Lu → A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Třída Lu obsahuje velká písmena – uppercase [ˡapǝrkeis] latinské abecedy. character → letter → Lu → A → U+MMcB character → letter → Lu → B → U+MMcZ a tak dále až do character → letter → Lu → Z → U+MM`A Malá písmena character → letter → Ll → a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z Objektově orientované programování - Studijní opora 108 Třída Ll (Letter lowercase) obsahuje malá písmena latinské abecedy. character → letter → Ll → a → U+MMbB character → letter → Ll → b → U+MMbZ a tak dále až do character → letter → Ll → z → U+MM\A Čísla character → number → Nd Čísla (number) obsahují číslice (třída Nd). character → number → decimal digit → Nd → h | i | j | k | l | m | n | o | p | q Třída Nd (Number decimal digit) obsahuje arabské desítkové číslice. character → number → Nd → M → U+MMlM character → number → Nd → B → U+MMlB a tak dále až do character → number → Nd → Q → U+MMlQ Symboly character → symbol → Sc | Sm | Sk Symboly (symbol) dělíme na měnové symboly (třída Sc), matematické symboly (třída Sm) a diakritické symboly (třída Sk). Měnové symboly character → symbol → Sc → $ Třída Sc (Symbol currency) obsahuje měnové symboly. character → symbol → Sc → $ → U+MMZc „$“ je znak amerického dolaru (dollar sign). Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − ů. Objektově orientované programování - Studijní opora 109 Matematické symboly character → symbol → Sm → + | < | = | > | | | ~ Třída Sm (Symbol math) obsahuje matematické symboly. character → symbol → Sm → + → U+MMZB „+“ je znaménko sčítání (plus sign). Znaménka odčítání „−“, násobení „*“ a dělení „/“ jsou zařazena do jiných tříd, protože mají i jiné významy. Pro zápis na české klávesnice je vhodné používat numerickou část klávesnice. character → symbol → Sm → < → U+MMlC „<“ je znaménko menší než (less−than sign). Používá se i jako levá lomená závorka. Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − <. character → symbol → Sm → = → U+MMlD „=“ je znaménko rovná se (equals sign). character → symbol → Sm → > → U+MMlE „>“ je znaménko větší než (greater−than sign). Používá se i jako pravá lomená závorka. Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − >. character → symbol → Sm → | → U+MM\C „|“ je svislá čára (vertical line). Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − W. character → symbol → Sm → ~ → U+MM\E „~“ je tilda (tilde) nebo jednoduše vlnka, vlnovka. Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − / (na abecední části klávesnice). Diakritické symboly character → symbol → Sk → ^ | ` Třída Sk (Symbol modifier − kdo ví proč „k“?) obsahuje diakritiku. character → symbol → Sk → ^ → U+MM`E „^“ je vokáň (circumflex accent). Pro zápis na české klávesnici stiskneme nejdříve kombinaci kláves pravý Alt − 2 (na abecední části klávesnice) a potom stiskneme samostatně mezerník. Je to vlastně mezera s vokáněm. Chceme-li napsat např. o s vokáněm, stiskneme Alt − 2 a potom „o“. Dostaneme „ô“! Objektově orientované programování - Studijní opora 110 character → symbol → Sk → ` → U+MMbM „`“ je přízvuk (grave accent). Pro zápis na české klávesnici stiskneme nejdříve kombinaci kláves pravý Alt − 6 (na abecední části klávesnice) a potom stiskneme samostatně mezerník. Je to vlastně mezera s přízvukem. Chceme-li napsat např. e s přízvukem, stiskneme Alt − 6 a potom „e“. Dostaneme „è“! Průvodce studiem. A jdeme na CAFÈ. Interpunkční znaménka character → punctuation → Ps | Pe | Pd | Pc | Po Interpunkční znaménka se dělí na otvírací znaménka (třída Ps), uzavírací znaménka (třída Pe), pomlčky (třída Pd), spojovníky (třída Pc) a ostatní interpunkční znaménka (třída Po). Otvírací znaménka character → punctuation → Ps → ( | [ | { Třída Ps (Punctuation open − start) obsahuje otvírací znaménka čili levé závorky. character → punctuation → Ps → ( → U+MMZa „(“ je levá kulatá závorka (left parenthesis). character → punctuation → Ps → [ → U+MM`B „[“ je levá hranatá závorka (left square bracket). Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − F. character → punctuation → Ps → { → U+MM\B „{“ je levá složená závorka (left curly bracket). Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − B. Uzavírací znaménka character → punctuation → Pe → ) | ] | } Třída Pe (Punctuation close − end) obsahuje uzavírací znaménka čili pravé závorky. character → punctuation → Pe → ) → U+MMZQ „)“ je pravá kulatá závorka (right parenthesis). Objektově orientované programování - Studijní opora 111 character → punctuation → Pe → ] → U+MM`D „]“ je pravá hranatá závorka (right square bracket). Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − G. character → punctuation → Pe → } → U+MM\D „}“ je pravá složená závorka (right curly bracket). Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − N. Pomlčky character → punctuation → Pd → − Třída Pd (Punctuation dash) obsahuje pomlčky. character → punctuation → Pd → − → U+MMZD „−“ je pomlčka (dash). Používá se i jako spojovník (hyphen) a matematické znaménko mínus (minus sign). Spojovníky character → punctuation → Pc → _ Třída Pc (Punctuation connector) obsahuje spojovníky. character → punctuation → Pc → _ → U+MM`F „_“ je podtržítko (underline). Ostatní interpunkční znaménka character → punctuation → Po → ! | " | # | % | & | ' | * | , | . | / | : | ; | ? | @ | \ Třída Po (Punctuation other) obsahuje ostatní interpunkční znaménka. character → punctuation → Po → ! → U+MMZB „!“ je vykřičník (exclamation mark). character → punctuation → Po → " → U+MMZZ „"“ je anglická dvojitá uvozovka (quotation mark). V angličtině se používají horní uvozovky na začátku i na konci přímé řeči. character → punctuation → Po → # → U+MMZl Objektově orientované programování - Studijní opora 112 „#“ je znak čísla (number sign). Např. #/ znamená číslo jedna. character → punctuation → Po → % → U+MMZ` „%“ je procento (percent sign). Používá se pro zkrácení zápisu „///AA“. character → punctuation → Po → & → U+MMZb „&“ je ampersand (ampersand). Používá se pro zkrácení zápisu „Et“. Ampersand se vyskytuje v mnoha grafických podobách, např. „& “. Latiské slovo et znamená česky a, anglicky and. Česky „&“ čteme „emprsand“ nebo „end“. Nehrozí-li záměna s písmenem „A“, můžeme číst „a“. Při latiské výslovnosti „et“ hrozí záměna s anglickým „at“ používaným pro „@“. Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − C. Příklad. Novák & syn Nápis „Novák & syn“ běžně čteme „Novák a syn“, ale hrozí záměna s nápisem „Novák a syn“. Varianta „Novák emprsand syn“ je sice jasná, ale špatně se vyslovuje. Nejlepší je „Novák end syn“, neboť záměna s nápisem „Novák and syn“ většinou nehrozí. Mluvené „Novák et syn“ zapíšeme spíše jako „Novák@syn“. character → punctuation → Po → ' → U+MMZ\ „'“ je apostrof (apostrophe). Používá se i jako jednoduchá uvozovka. Na české klávesnici bývá poblíž tlačítka Enter, obvykle se píše se shiftem. character → punctuation → Po → * → U+MMZA „*“ je hvězdička (asterisk). Používá se i jako matematické znaménko pro násobení. character → punctuation → Po → , → U+MMZC „ ,“ je čárka (comma). character → punctuation → Po → . → U+MMZE „ .“ je tečka (period). character → punctuation → Po → / → U+MMZF „/“ je lomítko (slash). Používá se i jako matematické znaménko pro dělení. character → punctuation → Po → : → U+MMlA „:“ je dvojtečka (colon). character → punctuation → Po → ; → U+MMlB „ ;“ je středník (semicolon). Na české klávesnici bývá pod tlačítkem Esc. Objektově orientované programování - Studijní opora 113 character → punctuation → Po → ? → U+MMlF „?“ je otazník (question mark). character → punctuation → Po → @ → U+MMcM „@“ je komerční a (commercial at). V češtině se hojně používá i slangový výraz „zavináč“. Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − V. character → punctuation → Po → \ → U+MM`C „\“ je zpětné lomítko (backslash). Pro zápis na české klávesnici používáme kombinaci kláves pravý Alt − Q. Oddělovače character → separator → Zs Oddělovače (separator) obsahují mezery (třída Zs). character → separator → Zs → sp Třída Zs (Zero space) obsahuje mezery. character → separator → Zs → sp → U+MMZM „ “ je mezera (space). Ostatní znaky character → other → Cc Ostatní znaky (other character) obsahují řídící znaky (třída Cc). character → other → Cc → nul | soh | stx | etx | eot | enq | ack | bel | bs | ht | lf | vt | ff | cr | so | si | dle | dci | dcj | dck | dcl | nak | syn | etb | can | em | sub | esc | fs | gs | rs | us | del Třída Cc (Control) obsahuje řídící znaky. Protože jich je hodně (asi 2A), vybereme jen ty nejdůležitější. character → other → Cc → nul → U+MMMM Prázdný znak (null) character → other → Cc → bel → U+MMM\ Zvonek (bell) Objektově orientované programování - Studijní opora 114 character → other → Cc → bs → U+MMMa Vymazání znaku (back space) character → other → Cc → ht → U+MMMQ Vodorovný tabelátor (horizontal tab). character → other → Cc → lf → U+MMMA Odřádkování (line feed). Na klávesnici se obvykle řádkuje klávesou Enter. Její význam je však závislý na použitém softwaru. Někdy je vkládán znak lf, někdy cr. Nejčastěji se používají oba v pořadí cr lf. V textových editorech je řádkování obvykle automatické a klávesa Enter se používá k ukončení odstavce. character → other → Cc → vt → U+MMMB Svislý tabelátor (vertical tab). character → other → Cc → ff → U+MMMC Odstránkování (form feed) character → other → Cc → cr → U+MMMD Návrat vozíku (carriage return). Zastaralý název pochází z doby telegrafů. character → other → Cc → esc → U+MMBB Únik (escape). character → other → Cc → del → U+MM\F Smazat (delete). Objektově orientované programování - Studijní opora 115 Příloha C: Datové typy Typy type → value type | reference type | type parameter Datový typ – type [taip] je soubor hodnot a metod práce s těmito hodnotami. Podle toho, kde jsou hodnoty uloženy, dělíme typy na hodnotové – value type [ˡvælju: taip] a odkazové – reference type [ˡrefǝrǝns taip]. Zatímco hodnotové typy pracují s hodnotou přímo, odkazové typy pracují s odkazem do paměti (adresou), kde je hodnota uložena. Při zobecňování je možné použít typový parametr – type parameter [taip pǝˡræmitǝr]. Kód zapíšeme obecně s parametrem, za který dosadíme konkrétní typ až při použití. Např. máme-li naprogramovaný obecný seznam prvků, můžeme dosazením typu získat seznam čísel, seznam jmen nebo seznam barev. Výhodou je, že naprogramujeme všechny typy seznamů najednou a nemusíme programovat každý typ zvlášť. Hodnotové typy type → value type → struct type | enum type Hodnotový typ – value type [ˡvælju: taip] je typ, který pracuje s hodnotami přímo. Zpracování dat je tedy rychlé. Je vhodný pro zpracování jednoduchých dat jako jsou např. čísla, body, barvy. Nehodí se pro rozsáhlejší data jako jsou např. seznamy, okna, obrázky. Hodnotové typy dělíme na struktury – structure [ˡstrakčǝr] a výčty – enumeration [iˌnju:mǝˡreišn]. Nejčastějšími hodnotami struktur jsou n−tice hodnot jednodušších typů. Např. bod na obrazovce lze definovat jako dvojici souřadnic [x,y]. Výčty jsou obvykle malé soubory čísel s pojmenovanými hodnotami. Např. pro určení dne v týdnu použijeme sadu čísel {A, /, 0, 2, 3, -, ,}, ale ve zdrojovém kódu pracujeme s názvy {po, ut, st, ct, pa, so, ne}. Struktury type → value type → struct type → simple type | type name Mezi struktury – structure [ˡstrakčǝr] zahrnujeme většinu předdefinovaných jednoduchých typů – simple type [ˡsimpl taip]. Další struktury nalezneme v systémových knihovnách, v knihovnách od dodavatelů sowtware nebo si je můžeme sami naprogramovat. K využití takové struktury potřebujeme znát její jméno – name [neim], které je někde deklarované – declaration [deklǝˡreišn]. type declaration → struct declaration Jednoduché typy type → value type → struct type → simple type → bool | numeric type System.Boolean (bool) using bool=System.Boolean; Logický datový typ. Objektově orientované programování - Studijní opora 116 Číselné typy type → value type → struct type → simple type → numeric type → decimal | integral type | floating point type System.Decimal (decimal) using decimal=System.Decimal; Celá čísla Hodnoty odpovídají prvkům množina celých čísel ℤ. type → value type → struct type → simple type → numeric type → integral type → sbyte | byte | short | ushort | int | uint | long | ulong | char using sbyte=System.SByte; using byte=System.Byte; using short=System.IntBb; using ushort=System.UIntBb; using int=System.IntlZ; using uint=System.UIntlZ; using long=System.Intbc; using ulong=System.UIntbc; using char=System.Char; System.SByte (sbyte) Osmibitové (/ byte) celé číslo se znaménkem v rozsahu od −/08 do /06. System.Byte (byte) Osmibitové (/ byte) celé číslo bez znaménka v rozsahu od A do 0--. System.IntBb (short) Šestnáctibitové (0 byte) celé číslo se znaménkem. System.UIntBb (ushort) Šestnáctibitové (0 byte) celé číslo bez znaménka. System.IntlZ (int) Dvaatřicetibitové (3 byte) celé číslo se znaménkem. System.UIntlZ (uint) Dvaatřicetibitové (3 byte) celé číslo bez znaménka. Objektově orientované programování - Studijní opora 117 System.Intbc (long) Šedesátičtyřbitové (8 byte) celé číslo se znaménkem. System.UIntbc (ulong) Šedesátičtyřbitové (8 byte) celé číslo bez znaménkem. System.Char (char) Šestnáctibitové číslo ve významu znaku ze sady Unicode. Reálná čísla Hodnoty odpovídají prvkům množiny reálných čísel ℝ. type → value type → struct type → simple type → numeric type → floating point type → float | double using float=System.Single; using double=System.Double; System.Single (float) Reálné číslo s jednoduchou přesností. System.Double (double) Reálné číslo s dvojitou přesnosstí. Výčty type → value type → enum type → type name type declaration → enum declaration Odkazové typy type → reference type → class type | interface type | delegate type | array type Odkazové (referenční) typy narozdíl od hodnotových neobsahují hodnoty přímo, ale jen adresy do paměti, kde se hodnoty nacházejí. Mezi odkazové typy patří třídy (class), rozhraní (interface), delegáti (delegate) a pole (array). Objektově orientované programování - Studijní opora 118 Třídy type → reference type → class type → object | string | type name Základním druhem odkazových typů jsou třídy. Nové třídy můžeme deklarovat deklarací třídy: type declaration → class declaration Dvě třídy (object a string) jsou již v systému předdefinované. using object=System.Object; using string=System.String; System.Object (object) Základní třída objektů. Všechny ostatní třídy jsou ať už přímo nebo nepřímo odvozeny od této třídy. System.String (string) Řetězec (string) znaků se používá k ukládání textů. Rozhraní type → reference type → interface type → type name Rozhraní (interface) slouží k popisu veřejných členů daného datového typu. Rozhraní je vlastně dohodou mezi výrobce typu, že všechny požadované členy naprogramuje (implementuje) a uživatelem rozhraní, že bude ve svých programech používat jen tyto členy. Popis nového rozhraní lze deklarovat: type declaration → interface declaration Delegáti Delegát je odkaz na metodu. Deklaruje se takto: type → reference type → delegate type → type name type declaration → delegate declaration Objektově orientované programování - Studijní opora 119 Pole Pole (array) představují jednu ze základních datových struktur. Pole se skládá z prvků stejného datového typu. Přístup k jednotlivým prvkům je možný prostřednictvím číselných indexů. type → reference type → array type → ( type − array type )( [ , A – N ] )/ – N Typový parametr type → type parameter → identifier Místo podobných typů SeznamCisel s metodou Pridat(int cislo) a SeznamRetezcu s metodou Pridat(string retezec) deklarujeme typ s parametrem Seznam<Typ> s metodou Pridat(T prvek). Místo SeznamCisel použijeme Seznam<int> a místo SeznamRetezcu použijeme Seznam<string>. Objektově orientované programování - Studijní opora 120 Příloha D: Příkazy Příkaz statement → labeled statement | declaration statement | embedded statement Příkazy jsou stavebním kamenem metod. Dělíme je na příkazy s návěštím (label), deklarační příkazy a vložené příkazy. Příkaz s návěštím statement → labeled statement → identifier : statement Příkaz s návěštím obsahuje jméno návěští oddělené od příkazu dvojtečkou. Deklarační příkaz statement → declaration statement → const A – / local variable declaration ; Deklarační příkaz se skládá z deklarace lokální proměnné a středníku. Je-li na začátku uvedeno klíčové slovo const, je hodnota proměnné neměnná (konstantní). Deklarace lokální proměnné local variable declaration → type identifier ( = expression )A – / ( , identifier ( = expression )A – / )A – N Deklarace lokální proměnné se skládá z typu a jména identifier. Proměnné může být přiřazena výchozí hodnota operátorem = a výrazem (expression). Při deklaraci více promměnných stejného typu oddělujeme jednotlivé promměnné čárkou. Vložený příkaz statement → embedded statement → empty statement | block | expression statement selection statement | iteration statement | jump statement | try statement | checked statement | unchecked statement | lock statement | using statement | yield statement Vložené příkazy dělíme na prázdné (empty), blok (block), výrazové příkazy (expression statement), podmínkové (selection) příkazy, příkazy cyklu (iteration), skokové (jump) příkazy a na příkazz try, checked, unchecked, lock, using a yield. Prázdný příkaz statement → embedded statement → empty statement → ; Prázdný příkaz nedělá nic. Zapisuje se samostatným středníkem. Objektově orientované programování - Studijní opora 121 Blok statement → embedded statement → block → { statement A – N } Blok příkazů vytvoří z několika příkazů jeden složený. Blok se skládá ze složené závorky uvnitř které jsou zapsány příkazy bloku. Výrazový příkaz statement → embedded statement expression statement → statement expression ; Z některých výrazů lze vytvořit příkaz připsáním středníku. Tyto výrazy (statement expression) naleznete v příloze Výrazy. expression → statement expression Podmínkové příkazy statement → embedded statement → selection statement → if statement | switch statement Podmínkové příkazy jsou if a switch. Příkaz if statement → embedded statement → selection statement → statement if → if embedded statement ( else ( expression ) embedded statement )A – / Je-li splněna podmínka uvedená v kulaté závorce za klíčovým slovem if, provede se příkaz uvedený za závorkou. Obsahuje-li příkaz klíčové slovo else, je při nesplnění podmínky vykonán příkaz uvedený za else. Příkaz switch statement → embedded statement → selection statement → statement switch → switch expression : ) { (( case expression ( : )/ – N statement A – N jump statement )A – N ( default statement A – N jump statement )A – / } Na základě hodnoty výrazu uvedeného v kulaté závorce za klíčovým slovem switch, pokračuje zpracování příkazem uvedeným za odpovídající klauzulí case. Objektově orientované programování - Studijní opora 122 Iterační příkazy statement → embedded statement → iteration statement → while statement | do statement | for statement | foreach statement Iteračními příkazy jsou while, do, for, foreach. Příkaz while statement → embedded statement → iteration statement → while statement → while ) ( expression embedded statement Základní iterační příkaz se svou syntaxí podobá příkazu if. Příkaz za závorkou je však prováděn opakovaně tak dlouho, dokud podmínka v závorce platí. Příkaz do statement → embedded statement → iteration statement → do statement → do while ( expression ) embedded statement ; Obdoba příkazu while s tím rozdílem, že podmínka se vyhodnocuje až po provedení příkazu. Příkaz for statement → embedded statement → iteration statement → for statement → for A–/ ; for condition A – / ; for iterator A – / ) ( for initializer embedded statement for initializer → local variable declaration | statement expression ( , statement expression )A – / for condition → expression statement expression )A – / for iterator → statement expression ( , Sice poněkud komplikovaný, ale mocný příkaz. Nejlépe jej pochopíme z jeho definice pomocí příkazu while: for ( initializer initializer ; while ; condition ( ; condition iterator ) Objektově orientované programování - Studijní opora { ) statement → statement iterator ; } 123 Příkaz foreach statement → embedded statement → iteration statement → foreach statement → foreach identifier in expression ) ( type embedded statement Příkazem foreach lze zpracovat všechny prvky objektů s rozhraním IEnumerable. U polí se například nemusíme starat o jejich rozsah. Skokové příkazy statement → embedded statement → jump statement → break statement | continue statement | goto statement | return statement | throw statement Skokové příkazy jsou break, continue, goto, return a throw. Příkaz break statement → embedded statement → jump statement → break statement → break ; Příkazem break je možné předčasně ukončit iterační příkaz. Často se používá v příkaze switch k ukončení jednotlivých možností. Příkaz continue statement → embedded statement → jump statement → continue statement → continue ; Příkaz continue ukončí zpracování aktuálního kroku iteračního příkazu a pokračuje krokem dalším. Příkaz goto statement → embedded statement → jump statement → goto statement → goto goto case expression ; | goto default identifier ; | ; Příkazem goto přeskočíme na provádění označeného příkazu. Příkaz return statement → embedded statement → jump statement → return statement → return expression A – / Příkazem return ukončíme provádění příkazů metody. Typ výrazu musí odpovídat návratovému typu metody. Objektově orientované programování - Studijní opora 124 Příkaz throw statement → embedded statement → jump statement → throw statement → throw expression A – / Příkazem throw dojde k vyhození výjimky (exception). Příkaz try statement → embedded statement → try statement → try { statement A – N } catch clause A – N finally clause A – / Příkaz try používáme tehdy, když očekáváme vyhození výjimky. Příkazy uvedené v klauzuli try se postupně provádějí, dokud nejsou provedeny všechny nebo dokud některý z nich nevyhodil výjimku. V takovém případě nejsou další příkazy provedeny a zpracování se předá klauzuli catch. Klauzule catch catch clause → catch ( ( type identifier A – / ) )A – / { statement A – N } Klauzule catch obsahuje kód, který se vykoná při zachycení výjimky. K zychycení je nutné, aby typ vyhozené výjimky odpovídal typu, který je uveden v klauzuli catch. Klauzilí catch může být v jednom příkaze try více. Klauzule finally finally clause → finally { statement A – N } Klauzule finally obsahuje příkazy, které se nakonec provedou vždy, nazávisle na tom, zda byla či nebyla vyhozena nějaká výjimka. Příkaz checked statement → embedded statement → checked statement → checked { statement A – N } Při zpracování příkazů je zapnuta kontrola přetečení celočíselných operací. Příkaz unchecked statement → embedded statement → unchecked statement → unchecked { statement A – N } Při zpracování příkazů je vypnuta kontrola přetečení celočíselných operací. Objektově orientované programování - Studijní opora 125 Příkaz lock statement → embedded statement → lock statement → lock ( expression ) embedded statement Objekt uvedený v závorce je po dobu provádění příkazu uzamknut, takže není přístupný z jiných vláken. Příkaz using statement → embedded statement → using statement → using expression ) ) ( ( local variable declaration | embedded statement Po provedení příkazu je objekt uvedený v závorce uvolněn voláním jeho metody Dispose. Příkaz yield statement → embedded statement → yield statement → yield break return expression ; | yield ; Příkaz yield se používá při pokročilejší implementaci rozhraní IEnumerable. Objektově orientované programování - Studijní opora 126 Příloha E: Výrazy Booleovské výrazy boolean expression → expression Výrazy typu bool. Konstantní výrazy constant expression → expression Výrazy jejichž hodnotu lze vypočítat během překladu. Příkazové výrazy statement expression → invocation | object creation | assignment | post increment | post decrement | pre increment | pre decrement Výrazy z nichž je možné přidáním středníku vytvořit příkaz. Výrazy expression → assignment | conditional expression Výrazy dělíme na přiřazovací a podmíněné. Přiřazovací výraz assignment → unary expression ( = | += | −= | *= | /= | %= | &= | |= | ^= | <<= | >>= ) expression Hodnota výrazu na pravé straně je uložena do objektu na levé straně. V případě složeného operátoru je nejprve provedena příslušná operace a teprve její výsledek je uložen. Podmíněný výraz conditional expression → conditional or expression ( ? expression : expression )A – / Podmíněný výraz je podmínka následovaná otazníkem a dvěma výrazy oddělenými dvojtečkou. Je-li podmínka před otazníkem pravdivá, je výsledkem hodnota výrazu mezi otazníkem a dvojtečkou. Není-li podmínka pravdivá, je výsledkem výraz za dvojtečkou. Objektově orientované programování - Studijní opora 127 Logické „nebo“ (or) conditional or expression → conditional and expression ( || conditional and expression )A – N Logická operace nebo. Je-li levý výraz pravdivý, pravý se již nevyhodnocuje. Logické „a“ (and) conditional and expression → inclusive or expression ( && inclusive or expression )A – N Logická operace a. Je-li levý výraz nepravdivý, pravý se již nevyhodnocuje. Binární „nebo“ (or) inclusive or expression → exclusive or expression ( | exclusive or expression )A – N Binární operace nebo. Binární vylučovací „nebo“ (xor) exclusive or expression → and expression ( ^ and expression )A – N Binární operace vylučovací nebo. Binární „a“ (and) and expression → equality expression ( & equality expression )A – N Binární operace a. Rovnost a nerovnost equality expression → relational expression (( == | != ) relational expression )A – N Porovnání výrazů na rovnost (==) resp. nerovnost (!=). Relační výrazy relational expression → shift expression (( < | > | <= | >= ) shift expression |( is | as ) type )A – / Porovnání výrazů (<, >, <=, >=). Test je-li hodnota výrazu daného typu (is). Převedení hodnoty na daný typ (as). Nelze-li hodnotu převést, je výsledkem null. Objektově orientované programování - Studijní opora 128 Posuvné výrazy shift expression → additive expression (( << | >> ) additive expression )A – N Binární posuv levého operandu o počet bitů daný druhým operandem doleva (<<) nebo doprava (>>). Aditivní výrazy additive expression → multiplicative expression (( + | − ) multiplicative expression )A – N Aditvní operace sčítání (+) a odčítání (−). Multiplikativní výrazy multiplicative expression → unary expression (( * | / | % ) unary expression )A – N Multiplikativní operace násobení (*), dělení (/) a zbytek po dělení (%). Unární výrazy unary expression → ( + | − | ! | ~ | ++ | −− | ( type ) )A – N primary expression Unární operace plus (+), mínus (−), negace (!), doplněk (~), inkrementace (přičtení /) před vyhodnocením a dekrementace (odečtení /) před vyhodnocením. Primární výrazy primary expression → literal | simple name | parenthesized expression | member access | invocation | element access | this access | base access | post increment | post decrement | object creation | delegate creation | typeof expression | checked expression | unchecked expression | default value expression | annonymous method expression Jednoduché jméno simple name → identifier type argument list A – / Jméno proměnné obsahující hodnotu výrazu. Uzávorkovaný výraz parenthesized expression → ( expression ) Jakýkoliv výraz uzavřený do závorek je primárním výrazem. Závorkováním můžeme měnit pořadí prováděných operací. Objektově orientované programování - Studijní opora 129 Přístup ke členům member access → member access prefix . identifier type argument list A – / member access prefix → primary expression | bool | byte | char | decimal | double | float | int | long | object | sbyte | short | string | uint | ulong | ushort | identifier :: identifier type arument list A – / Přístup ke členům objektu prostřednictvím operátoru tečka. Volání invocation → primary expression ( argument ( , argument )A – N A – / ) Volání metody uvedením argumentů do kulaté závorky. Přístup k prvku element access → primary expression [ expression ( , expression )A – N ] Přístup k prvkům pole zadáním indexů do hranatých závorek. Přístup this this access → this Přístup k objektu právě deklarované třídy. Přístup base base access → base . identifier type argument list A – / | base [ expression ( , expression )A – N ] Přístup k bázové třídě. Objektově orientované programování - Studijní opora 130 Postfixová inkrementace post increment expression → primary expression ++ Po vyhodnocení výrazu je jeho hodnota zvýšena o /. Postfixová dekrementace post decrement expression → primary expression −− Po vyhodnocení výrazu je jeho hodnota snížena o /. Vytvoření objektu object creation expression → new type ( ( argument ( , argument )A – N )A – / ) Vytvoření objektu daného typu voláním konstruktoru se zadanými argumenty. Vytvoření pole array creation expression → array creation from non array type | array creation from array type array creation from non array type )A – N ] ( [ new ( type − array type ) [ expression ( , expression , A – N ] )A – N array initializer A – / array creation from array type new array type array initializer array initializer → { (( expression | array initializer )( , ( expression | array initializer ))A – N )A – / } Vytvoření pole. Výraz typeof typeof expression → typeof ( ( type | void ) ) Převod typu na objekt typu Type. Objektově orientované programování - Studijní opora 131 Výraz checked chcked expression → checked ( expression ) Zapnutí kontroly přetečení aritmetických operací. Výraz unchecked unchcked expression → unchecked ( expression ) Vypnutí kontroly přetečení aritmetických operací. Výchozí hodnota default value expression → default ( primary expresion ) Výchozí hodnota výrazu. Anonymní metody anonymous method expression → delegate annonymous method parameter )A – N )A – / ) ( ( annonymous method parameter ( , { statement A – N } annonymous method parameter → ( ref | out )A – / type identifier Vytvoření delegáta pomocí anonymní metody. Objektově orientované programování - Studijní opora 132 Anglicko-český slovníček abstract array attribute base class compilation unit constant constructor declaration delegate destructor directive encapsulation enumeration event expression field character identifier index inheritability interface internal letter method name nest new number operator other private property protect public punctuation reference type seal separator simple type statement static structure symbol type type parameter uppercase value type [æbstrækt] [ǝˡrei] [ætribju:t] [beis] [kla:s] [kǝmpileišn junit] [konstǝnt] [kǝnˡstraktǝ] [deklǝˡreišn] [deligǝt] [diˡstraktǝ] [diˡrektiv] [inˌkæpsjuˡleišǝn] [iˌnju:mǝˡreišn] [iˡvent] [ikˡsprešǝn] [fi:ld] [ˡkærǝktǝr] [aiˡdentifaiǝ] [indeks] [inˌheritǝˡbilǝti] [intǝfeis] [inˡtǝ:nl] [ˡletǝr] [meӨǝd] [neim] [nest] [nju:] [ˡnambǝr] [opǝreitǝ] [ˡaðǝr] [praivit] [propǝti] [prǝˡtekt] [pablik] [paŋkčuˡeišn] [ˡrefǝrǝns taip] [si:l] [ˡsepǝreitǝr] [ˡsimpl taip] [steitmǝnt] [stætik] [ˡstrakčǝr] [ˡsimbl] [taip] [taip pǝˡræmitǝr] [ˡapǝrkeis] [ˡvælju: taip] Objektově orientované programování - Studijní opora abstraktní pole atribut základ třída celek překladu konstanta konstruktor deklarace zástupce destruktor direktiva zapouzdření výčet událost výraz pole znak identifikátor index dědičnost rozhraní vnitřní písmeno metoda jméno hnízdo nový číslo operátor jiný soukromý vlastnost chránit veřejný interpunkce odkazový typ pečeť oddělovač jednoduchý typ příkaz statický struktura symbol typ typový parametr velké písmeno hodnotový typ 133 Česko-anglický slovníček abstraktní atribut celek překladu číslo dědičnost deklarace destruktor direktiva hnízdo hodnotový typ chránit identifikátor index interpunkce jednoduchý typ jiný jméno konstanta konstruktor metoda nový oddělovač odkazový typ operátor pečeť písmeno pole pole příkaz rozhraní soukromý statický struktura symbol třída typ typový parametr událost velké písmeno veřejný vlastnost vnitřní výčet výraz základ zapouzdření zástupce znak abstract attribute compilation unit number inheritability declaration destructor directive nest value type protect identifier index punctuation simple type other name constant constructor method new separator reference type operator seal letter field array statement interface private static structure symbol class type type parameter event uppercase public property internal enumeration expression base encapsulation delegate character Objektově orientované programování - Studijní opora [æbstrækt] [ætribju:t] [kǝmpileišn junit] [ˡnambǝr] [inˌheritǝˡbilǝti] [deklǝˡreišn] [diˡstraktǝ] [diˡrektiv] [nest] [ˡvælju: taip] [prǝˡtekt] [aiˡdentifaiǝ] [indeks] [paŋkčuˡeišn] [ˡsimpl taip] [ˡaðǝr] [neim] [konstǝnt] [kǝnˡstraktǝ] [meӨǝd] [nju:] [ˡsepǝreitǝr] [ˡrefǝrǝns taip] [opǝreitǝ] [si:l] [ˡletǝr] [fi:ld] [ǝˡrei] [steitmǝnt] [intǝfeis] [praivit] [stætik] [ˡstrakčǝr] [ˡsimbl] [kla:s] [taip] [taip pǝˡræmitǝr] [iˡvent] [ˡapǝrkeis] [pablik] [propǝti] [inˡtǝ:nl] [iˌnju:mǝˡreišn] [ikˡsprešǝn] [beis] [inˌkæpsjuˡleišǝn] [deligǝt] [ˡkærǝktǝr] 134 Doporučená a použitá literatura Anders Hejlsberg, Scott Wiltamuth, Peter Golde: C# Language Specification Microsoft Developer Network Library John Sharp: Visual C# .NET krok za krokem, Computer Press Josef Pirkl: Řešené příklady v C# aneb C# skutečně prakticky, Kopp Robert Sedgewick: Algoritmy v C, SoftPress Josef Fronek: Anglicko−český slovník, LEDA Karel Hais, Břetislav Hodek: Velký anglicko−český slovník, LEDA, 0AA2 Ochranné známky Slova jako Microsoft, Windows, Visual Studio a pod. mohou být registrovanými obchodními značkami ® nebo obchodními značkami ™ svých vlastníků. Objektově orientované programování - Studijní opora 135
Podobné dokumenty
sr_pg_314
V tomto kódu se definuje metoda Main – vstupní bod každého programu v jazyce C#. Její první příkaz
je ten, který program vykoná po spuštění.
Metoda Application.Run
Programování jBotBrainu II v Javě a práce s moduly
Java je v poslední době mezi programátory velice oblíbená. Jedná se o interpretovaný jazyk – to
znamená, že kompilací programu nevzniká binární kód specifický pro danou platformu, ale jakýsi
mezikó...
Dialogy
Vlastnosti:
o string FileName (Get, Set) – cesta + jméno souboru („Název souboru:“)
o string Filter (Get, Set) – filtr pro výběr souborů („Soubory typu:“)
Příklad: "Text files (*.txt)|*.txt|All f...
Distribuované programování na platformě Microsoft .NET
Remoting slouží k tomu, abyste váš program spouštěli na více počítačích. Program rozdělíte
do „komponent“ a ty pak můžete fyzicky umístit na různé počítače. Remoting nabízí opravdu
mnoho možností, ...
Významné zdroje http:// java.sun.com Historie
− JIT kompilátory – v době zavádění přeloží bajtový kód do strojového
kódu platformy (v návrhu bajtového kódu s tím bylo počítáno, takže je
to efektivní) dle Sun se pak rychlost vyrovná C++
− Hot-s...
ASP.NET pre začiatočníkov
informácie o MSDN vrátane inštalácie, administrátorských a klientských aplikácií sú v piatej kapitole o vývoji
databázových aplikácií
Kód aplikácie na strane servera
Zatiaľ sme sa nedostali k vlast...
3. Reologie
smykové deformace. Díky jednoduchosti metody měření nelze úplně věrohodně srovnávat tuto
hodnotu s hodnotou viskozity získanou z měření na skutečném vysokotlakém kapilárním reometru.
Obě hodnoty se...
Skripta - Marek Běhálek
1. Nástroje pro vývoj softwaru – v této části budou probrány
různé nástroje, které se používají při vývoji softwarových
produktů. V kurzu budou představeny nástroje pro sestavení,
správu či uchováv...