Jazyk C# (seminář 3) Pavel Procházka KMI October 8, 2014
Motivace Největší využití v programování okenních aplikací a GUI knihoven. Data reprezentujeme pomocí objektů (tříd), máme tedy ucelený pohled na to, jak se objekt chová a co obsahuje Atributem OOP je zapouzdření členské proměnné třídy nejsou dostupné přímo, ale zásadně přes metody, které by navíc měly zajišťovat kontrolu správnosti vstupu dosahujeme tím robustnosti programu (odolnosti vůči chybám). Polymorfismus mnohotvarost stejně nazvané metody mohou být jinak naimplementované. Krava->mluvit(); // buuuu Kun->mluvit(); //ihahaaaa Dědičnost ve smyslu IS A. Nějaký objekt je současně i jiný objekt. Například kůň je savec všimněte si třídy kůň a savec. Problém vícenásobné dědičnosti. Uživatel Uklízečka, Student, Učitel Co když chceme vytvořit objekt Akademik dědící od učitele i studenta?
Zapouzdření v C# Objektově orientované programování (OOP) Ochrana členských proměnných a metod pomocí specifikátorů přístupů public veřejný kdekoli v kódu může číst, zapisovat nebo volat private přístup je možný pouze z metody dané třídy nebo struktury rotected chráněno přístup možný pouze v metodě dané třídy nebo v potomcích třídy internal málo používané přistup možný pouze ze stejného assembly bytekódu Obvykle bychom měli používat private nebo protected a přistupovat k nim pomocí metod, které nastavují, čtou proměnnou. class Savec private int weight; void SetWeight( int w ) if( weight <= 0 ) return; weight = w; int GetWeight() return weight;
Zapouzdření pohodlněji Naštestí v C# existují settery, gettery umožňují k proměnným přistupovat přímo, a přesto nejsme ochuzeni o kontrolu vstupu klíčová slova get, set class Savec /* skutecna vnitrni promenna */ private int weight = 1; public int Weight /* nastavovana hodnota je v promenne value */ set if( value <= 0 ) return; weight = value; get return weight; Savec s = new Savec(); /* zavola se setter s value = 10 */ s.weight = 10; /* prenastavi na 10 */ /* ve skutecnosti se zavola getter a vrati 10 */ Console.WriteLine( "w: 0", s.weight );
Dědičnost Dědíme VŽDY ve smyslu object IS A other object ne ve smyslu object have other object. Syntaxe class MORE_PARTICULAR_CLASS : MORE_GENERAL_CLASS class Savec public int hmotnost = 10; public int Hmotnost() return hmotnost; class Kun : Savec public void Mluv() Console.WriteLine("ihahaaa"); class Koza : Savec pubic void Mluv() Console.WriteLine("me-eee"); Koza k = new Koza(); k.mluv(); Console.WriteLine( "0", k.hmotnost() );
Statické třídy Není potřeba instance třídy provede se automaticky a má stejné jméno jako třída Klíčové slovo static Už to známe například System.Console je taková statická třída static class SampleClass public static string SampleString = "Sample String"; Console.WriteLine(SampleClass.SampleString);
Virtuální metody Objektově orientované programování (OOP) Klíčové slovo virtual Metoda může být vyměněna při dědení za jinou metodu pomocí klíčového slova override class Savec public int hmotnost = 10; public int Hmotnost() return hmotnost; public virtual void Mluv() Console.WriteLine("----"); class Kun : Savec public override void Mluv() Console.WriteLine("ihahaaa"); public class Koza : Savec pubic override void Mluv() Console.WriteLine("me-eee"); Koza k = new Koza(); k.mluv(); Console.WriteLine( "0", k.hmotnost() );
Abstraktní třídy Objektově orientované programování (OOP) Taková třída není určena k instanciaci instance takového typu nedává moc smysl například Savec abstract class Savec abstract public void Mluv(); class Kun : Savec public override void Mluv() Console.WriteLine( "ihahaaa" ); /* nelze */ Savec s = new Savec(); /* lze */ Kun k = new Kun(); k.mluv(); // -> ihahaaa
Vnořené třídy Objektově orientované programování (OOP) class Container public class Nested Container.Nested nestedinstance = new Container.Nested()
Překrývání Lze překrývat členské proměnné, metody i vnořené třídy. public class BaseC public static int x = 55; public static int y = 22; public class DerivedC : BaseC // Hide field x. new public static int x = 100; static void Main() // Display the new value of x: Console.WriteLine(x); // Display the hidden value of x: Console.WriteLine(BaseC.x); // Display the unhidden member y: Console.WriteLine(y);
Rozhraní interface Objektově orientované programování (OOP) Klíčové slovo interface Je to jako abstraktní třída, která neobsahuje žádnou implementovanou metodu Neobsahuje modifikátory přístupu Nesmí obsahovat členské proměnné ani konstanty Třída, která dědí (implementuje) rozhraní musí implementovat všechny metody Využití například při psaní driverů interface IFileSystem byte [] Read( string path ); bool Write( string path, string mode, byte [] data ); class FSNull : IFileSystem public int state = 0; public byte [] Read( string path ) return null; public bool Write( string path, string mode, byte [] data )
A teď vy Napište třídu Rectangle Napište abstraktní třídu Shape2D s virtuálními metodami Area vracející obsah objektu jako double, BoundingBox vracející Rectangle obdélník obalující tvar, bool InsideP( int x, int y ) vracející true pokud bod na souřadnicích [x,y] leží uvnitř objektu, false jinak. abstraktní třída Shape2D obsahuje proměnné symbolizující polohu tvaru int x,y, které Udělejte třídu Rect, Triangle, Circle, které dědí od Shape2D a implementují Area, BoundingBox, InsideP Do třídy Rect si doimplementujte metodu bool IntersectsP( Rect r ) vracející true, pokud se obdélníky překrývají Zkuste si doimplementovat interface IFileSystem pomocí třídy ArrayFS, která bude zapisovat, číst data z pole v paměti.