Úvod Třídy Rozhraní Pole Konec
Programování v C# Hodnotové datové typy, řídící struktury
Petr Vaněček
1 / 39
Úvod Třídy Rozhraní Pole Konec
Obsah přednášky
I
Referenční datové typy I I I
datové položky metody přístupové metody – accessory, indexery
I
Rozhraní
I
Pole
2 / 39
Úvod Třídy Rozhraní Pole Konec
Třídy
I
Třídy je datový typ I I
I
elementární prvek OOP zaveden na úrovni CIL
Zapouzdření I I
Sdružují v sobě funcionalitu a data Ke členům se přistupuje pomocí operátoru .
I
Dědičnost
I
Polymorfismus
3 / 39
Úvod Třídy Rozhraní Pole Konec
Deklarace třídy I
Deklarace v C#
class < identifikátor > [: < rodič , rozhraní >] { < datové položky , metody , vlastnosti , události , vnoř } I
Příklad class MotorovéVozidlo : Vozidlo { Motor motor ; void Nastartuj () { ... } }
4 / 39
Úvod Třídy Rozhraní Pole Konec
Instance
I I
Pro identifikátory se používá PascalCasing Pro použití jednoho konkrétního objektu třídy nutno vytvořit instanci třídy I I I
operátor new vyvolání kosntruktoru alokace paměti pro data
< Třída > < identifikátor >; < identifikátor > = new < Třída >( < parametry kosntruktoru >)
5 / 39
Úvod Třídy Rozhraní Pole Konec
Dědičnost
I
Umožňuje I I
I
Není možná vícenásobná dědičnost I
I
umístit obecná data a metody do společného předka rozšířit předka přidáním nových metod a položek nebo modifikací metod částečně je tento problém řešen interfaci
Specializovaná třída dědí všechny metody a položky rodičovských tříd I
metody tříd jsou v paměti pouze jednou!
6 / 39
Úvod Třídy Rozhraní Pole Konec
Datové položky
I
Reprezentují data
I
Podobné jako proměnné Možno určit způsob přístupu pomocí modifikátorů
I
I
private
I
protected
I
I
pouze pro danou třídu pro třídu a její potomky
I
internal
I
public
I
I I
pro assembly obsahující třídu přístupný všem pouze vyjímečně – většinou se řeší pomocí vlastností a metod
7 / 39
Úvod Třídy Rozhraní Pole Konec
Datové položky
I
Možno určit způsob chování pomocí modifikátorů I
static
I
readonly
I
I I
položka třídy (nikoliv instance) lze zapisovat pouze v inicializaci nebo v konstruktoru
const I
lze zapisovat pouze v inicializaci
8 / 39
Úvod Třídy Rozhraní Pole Konec
Metody I
Reprezentují funkcionalitu
I
Mohou být s parametry Musí vracet hodnotu
I
I
I
lze obejít typem void
Syntax:
[ modifikátory ] < návratový typ > < identifikátor > ( < parametry > { < tělo > return < hodnota >; } I I I
I
za return se příkazy nikdy neprovedou return nemusí být pouze jeden (větvení programu) u návratového typu void se return nemusí uvádět
Přístupové modifikátory stejné jako u datových položek 9 / 39
Úvod Třídy Rozhraní Pole Konec
Statické a instanční metody I
Statické < Třída >. < Metoda >(...); I I
I
volají se nad třídou nemají přístup k nestatickým členům
Instanční < instance >. < Metoda >(...); I I
volají se nad instancí možno použít indetifikátor this I I I
označuje instanci nad níž je zavolaná metoda členy přístupné i bez this musí se uvádět pokud by mohlo dojítk záměně např. s parametrem
10 / 39
Úvod Třídy Rozhraní Pole Konec
Formální parametry
I
V hlavičce metody I
I
seznam oddělený čárkami
Modifikátory I I I I
žádný – předání hodnotou ref – předání odkazem out – obdoba ref params – variabilní počet parametrů
11 / 39
Úvod Třídy Rozhraní Pole Konec
Formální parametry I I
Bez modifikátoru Parametr se předává hodnotou I
I
I
vytvoří se paměťové místo, které se inicializuje hodnotou parametru – změny se nedostanou mimo funkci v případě referenčního typu se vyrobí kopie reference – změny se projeví i mimo funkci
Např.
void Normalni ( int param ) { param = 5; } ... int i = 1; Normalni ( i ); Console . WriteLine ( i ); // 1
void Normalni ( MyInt param ) { param . i = 5; } ... MyInt j = new MyInt (1); Normalni ( j ); Console . WriteLine ( j . i ); // 5
12 / 39
Úvod Třídy Rozhraní Pole Konec
Formální parametry – ref
I
Parametr se předává odkazem I I I
I
nevytváří se lokální paměťové místo změny se projeví i mimo metodu v místě volání musí mít parametr hodnotu
Např.
void Ref ( ref int param ) { param = 5; } ... int i = 1; Ref ( ref i ); Console . WriteLine ( i ); // 5
void Ref ( ref MyInt param ) { param . i = 5; } ... MyInt j = new MyInt (1); Ref ( ref j ); Console . WriteLine ( j . i ); // 5
13 / 39
Úvod Třídy Rozhraní Pole Konec
Formální parametry – out I
Parametr se předává odkazem I I I I
I
nevytváří se lokální paměťové místo změny se projeví i mimo metodu v místě volání nemusí mít parametr hodnotu před opuštěním metody se musí přiřadit hodnota
Např.
void Ref ( out int param ) { param = 5; } ... int i ; Ref ( out i ); Console . WriteLine ( i ); // 5
void Ref ( out MyInt param ) { param . i = 5; } ... MyInt j = new MyInt (1); Ref ( out j ); Console . WriteLine ( j . i ); // 5
14 / 39
Úvod Třídy Rozhraní Pole Konec
Formální parametry – params
I
Parametry se předávají hodnotou I I I
I
umožnuje variabilní počet parametrů stejného typu musí být jednorozměrné pole pouze u posledního parametru
Např.
void Params ( params int [] param ) { foreach ( int p in param ) Console . Write ( p ); // 123 } ... Params (1 ,2 ,3);
15 / 39
Úvod Třídy Rozhraní Pole Konec
Virtuální metody
I
Virtuální metody (označené virtual) mohou být v odděděné třídě překryty I I
I
I
Při překrytí metod lze zabránít dalšímu překrývání I
I
překrytí se označuje slovem override při volání překryté metody se volá metoda současného typu instance (i když se přetypuje na předka) při překrytí nelze měnit přístupová práva modifkátor sealed
Lze možno zrušit vztah s předkem pomocí modifikátoru new
16 / 39
Úvod Třídy Rozhraní Pole Konec
Virtuální metody – příklad class Rodic { public virtual void PisVirtual () { Console . WriteLine ( " PisVirtual - rodic " ); } public void Pis () { Console . WriteLine ( " Pis - rodic " ); } } class Potomek : Rodic { public override void PisVirtual () { Console . WriteLine ( " PisVirtual - potomek " ); } public void Pis () { Console . WriteLine ( " Pis - potomek " ); } } ... Rodic m = new Potomek (); m . Pis (); // Pis - rodic m . PisVirtual (); // PisVirtual - potomek 17 / 39
Úvod Třídy Rozhraní Pole Konec
Metody předka
I
Pro volání metod předka nutno použít identifikátor base I
I I
obdoba Javoského super
Používá se hodně v konstruktorech V rodičovské třídě musí metoda být I I
nesmí být private nesmí být abstrakt
public void Tiskni () { base . Tiskni (); ... }
18 / 39
Úvod Třídy Rozhraní Pole Konec
Abstraktní metody I I I I
Metody, u kterých je znám prototyp (hlavička), ale ne funkčnost Tělo musí doplnit některá z odděděných tříd Abstraktní metoda je zároveň virtuální Třída obsahující abstraktní metody I I
I I
musí být označena jako abstraktní nemůže být isntanciována
Třída může být abstraktní aniž by měla abstraktní metody Abstraktní se označuje modifikátorem abstract abstract class Abstraktni { public abstract void Metoda (); } class Konkretni : Abstraktni { public override void Metoda () { ... } } 19 / 39
Úvod Třídy Rozhraní Pole Konec
Konstruktor I I I
Používá se k inicializaci instance Volá se automaticky při vytvoření instance V C# se zapisuje jako metoda I I
I I
bez návratového typu jméno shodné se jménem třídy
Lze volat konstruktor předka Lze použít this pro přístup k vytvářené instanci public Potomek ( int i , int j ) : base (i ,5 ,8) { this . j = j ; ... }
I
Možnost vytvořit statický konstruktor I I I
modifikátor static bezparametrický volá se při prvním přístupu na třídu 20 / 39
Úvod Třídy Rozhraní Pole Konec
(Bez)parametrické konstruktory I
I
Bezparametrický veřejný kosntruktor je automaticky doplněn kompilátorem Při volání konstruktoru potomka se automaticky volá bezparametrický konstruktor předka I I
I
pokud není pomocí : base(...) určen jiný konstruktor platí i u parametrického konstruktoru
Před voláním kódu konstruktor možno volat jiný kosntruktor stejné třídy public Trida ( int i , float f ) : this ( f ) { ... }
21 / 39
Úvod Třídy Rozhraní Pole Konec
Destruktor
I I
Slouží k uvolnění zdrojů alokovaných instancí V C# se zapisuje jako metoda I I
I
bez návratového typu jméno shodné se jménem třídy, uvozeno znakem ∼
Není zaručeno kdy destrukce proběhne (GC) I I
používá se výjimečně pokud je to opravdu nutné, implementuje se rozhraní IDisposable
22 / 39
Úvod Třídy Rozhraní Pole Konec
System.Object
I
Všechny datové typy jsou potomkem I
I
i pokud se neuvede žádný předek
Poskytuje statické metody I
bool Equals(object,object) I I
I
určuje datovou rovnost vhodné upravit si pro konkrétní typy
bool ReferenceEquals(object,object) I I
určuje rovnost referencí (zda se jedná o stejnou instanci) není virtuální
23 / 39
Úvod Třídy Rozhraní Pole Konec
System.Object
I
Poskytuje instanční metody I
string ToString() I
vrací řetězec reprezentující třídu
I
Type GetType()
I
object MemberwiseClone()
I
I I I I I
vrací typ objektu vytváří mělkou kopii objektu vytvoří instanci stejného typu překopíruje hodnotové typy u referečních typů nastaví referenci na původní objekt
...
24 / 39
Úvod Třídy Rozhraní Pole Konec
Vlastnosti I
Properties
I
Bezpečnější přístup k datovým položkám třídy
I
Obdoba Javovských get...() a set...() Pro přístup se používají přístupové metody
I
I I
accessory - get a set jméno většinou odpovídá datové položce, které náleží I
PascalCasing
I
Property se chová jako datová položka
I
Syntax:
< modifikátor > < typ > < identifikátor > { [ get {
} ] [ set { } ] } 25 / 39
Úvod Třídy Rozhraní Pole Konec
Accessory I I
Nemusí být definovány oba get I I I I
I
set I I I I
I
musí vracet hodnotu daného typu používá se return čtení z property se přeloží jako volání getteru není-li definován: write-only property (používá se výjimečně) zpracuje vstupní hodnotu reprezentována identifikátorem value zápis do property se přeloží jako volání setteru není-li definován: read-only property
V NET 2.0 mohou mít accessory nastavené různé přístupové modifikátory
26 / 39
Úvod Třídy Rozhraní Pole Konec
Accessory – příklad class Stamgast () { private int denniPridel ; public int DenniPridel { get { return denniPridel ; } set { if ( value <5) denniPridel = 5; else denniPridel = value ; } } } ... Stamgast pepa = new Stamgast (); pepa . DenniPridel = 1; Console . WriteLine ( " Pepa pije {0} piv denne " , pepa . DenniPridel );
27 / 39
Úvod Třídy Rozhraní Pole Konec
Indexery I I I I
Podobné jako vlastnosti Umožňují přistupovat k datovým položkám pomocí indexu Mohou být i vícerozměrné Příklad: class Bod () { int x ; int y ; public int this [ int index ] { get { switch ( index ) { case 0 : return x ; case 1 : return y ; default : return 0; } } } } 28 / 39
Úvod Třídy Rozhraní Pole Konec
Rozhraní
I
Umožňuje sjednocení komunikace heterogenních tříd
I
Částčně řeší problém vícenásobné dědičnosti Omezení rozhraní
I
I I I
I
nemůže obsahovat datové položky nemůže obsahovat těla metod a vlastností metody a vlastnosti nesmí mít nastavené přístupové modifikátory
Třída/strutkura může rozhraní implementovat I
musí dodat těla všem metodám v rozhraní
29 / 39
Úvod Třídy Rozhraní Pole Konec
Rozhraní I
Rozhraní se mohou ”oddědit” od jiných rozhraní I
I
metody jsou automaticky virtuální
Syntax: < modifikátor > interface < identifikátor > [: < předek >] { < tělo > }
I
Implementace rozhraní – syntakticky stejné jako dědění class < identifikátor >: < interface >[ , < interface >] { ... }
I
V těle třídy/struktury musí být implementovány všechny položky I
I
možno použít abstraktní
Třídu možno přetypovat na typ rozhraní I
možno použít is a as 30 / 39
Úvod Třídy Rozhraní Pole Konec
Explicitní implementace rozhraní I
Implementace konkrátních členů může být provedena explicitně I I
I
budou přítupní pouze z daného rozhraní (třída se musí přetypovat) nesmí mít žádné modifikátory
Příklad (ne příliš šťastné): interface Bod { void Kresli () } interface Platno { void Kresli () } class Kresleni : Bod , Platno { void Bod . Kresli () {...} void Platno . Kresli () {...} } (( Bod ) kresleni ). Kresli ();
31 / 39
Úvod Třídy Rozhraní Pole Konec
Pole
I I
Homogenní struktura statického rozsahu Třída – System.Array I
I
nutno vytvořit instanci
Syntax: [] < indetifikátor > = new [ < velikost >] [] < indetifikátor > = new [] { < prvek >[ , < prvek >]};
I
Indexace od nuly
I
Přístup pomocí indexeru []
32 / 39
Úvod Třídy Rozhraní Pole Konec
Vícerozměrná pole
I
Možno definovat libovolný počet rozměrů
I
Např: int [ ,] matice = new int [4 ,4];
I
Celé pole se vytváří najednou
I
Všechny řádky stejně dlouhé
33 / 39
Úvod Třídy Rozhraní Pole Konec
Zubatá pole
I
Pole polí
I
Např. int [][] matice = new int [4][]; matice [0] = new int [4];
I
Nelze konstruovat najednou I
I
Postupuje se od levého indexeru k pravému
Každá řádka může být jinak dlouhá
34 / 39
Úvod Třídy Rozhraní Pole Konec
Metody polí
I
Statické metody I I
volají se přes třídu Array Sort I
řazení pole
I
BinarySearch
I
Resize
I
I I
hledání metodou půlení intervalu změna velikosti pole
...
35 / 39
Úvod Třídy Rozhraní Pole Konec
Metody polí
I
Instanční metody I
property Length
I
property Rank
I
I I
velikost pole počet dimenzí
GetLength(int dim) I
rozměr v dimenzi dim
36 / 39
Úvod Třídy Rozhraní Pole Konec
Řazení polí
I
Není nutno psát vlastní řazení
I
Statická metoda Sort Řazené objekty musí implementovat IComparable
I
I
poskytují metodu CompareTo(object) I I I
záporné číslo – instance menší než parametr kladné číslo – instance větší než parametr nula – rovnost
37 / 39
Úvod Třídy Rozhraní Pole Konec
Řazení polí – Array.Sort
I
Možno předat třídu implementující IComparer I
I
Řazení části pole I
I
parametr index a rozsah
Řazení dvou polí I
I
poskytuje metodu int Compare(object, object)
pole klíčů a pole hodnot
...
38 / 39
Úvod Třídy Rozhraní Pole Konec
Konec
39 / 39