&to)
9 {
10 os << to.x << endl;
11 return os;
12 }
13 };
Ć" Może działać, ale nie jest to właściwa definicja.
Programowanie Obiektowe 132
Ć" Działa, gdy mamy jedną specjalizację klasy:
1 TempOp
2 cout << i;
Ć" Przestaje, gdy mamy więcej specjalizacji:
1 TempOp
2 TempOp
3 cout << to;
4 cout << i;
Kompilator zgłasza niejednoznaczność.
Programowanie Obiektowe 133
STL Standard Template Library
Ć" Teraz już jest częścią standardu języka.
Ć" Implementacja SGI http://www.sgi.com/tech/stl/
wykorzystywana m.in. w Borland C++.
Ć" Implementuje szablony wielu bardzo przydatnych struktur danych i
algorytmów:
î% Kontenery: vector, deque, list, set, multiset, map, multimap, oraz
dodatkowo w implementacji SGI:
hash_set, hash_multiset, hash_map, hash_multimap.
î% Iteratory
î% Algorytmy: reverse, find, for_each, sort . . .
Programowanie Obiektowe 134
vector
Ć" Przykład:
1 vector
2 v.reserve(100);
3 for (unsigned i=0; i<100; i++)
4 v[i] = i"i;
5 v.push_back(117);
6 for (unsigned i=0; i
Ć" Parametry:
T typ elementów wektora
Alloc alokator pamięci
Programowanie Obiektowe 135
Ć" Wybrane składowe:
reference typ: referencja na T
pointer typ: wskaznik na T
iterator typ do iterowania elementów
vector() tworzy pusty wektor
vector(size_type n) tworzy wektor n-wymiarowy
vector(size_type n, const T& t) tworzy wektor z n kopii obiektu t
iterator begin() zwraca iterator wskazujÄ…cy na poczÄ…tek
iterator end() zwraca iterator wskazujÄ…cy na koniec
reference front() zwraca pierwszy element
reference back() zwraca ostatni element
size_type size() const zwraca rozmiar wektora
size_type capacity() const ile zarezerwowanej pamięci (elementów)
reference operator[](size_type n) zwraca n ty element
void reserve(size_t n) zapewnia n elementów wektora
void resize(n, t = T()) dodaje bądz usuwa by było n elementów
void push_back(const T&) wstawia element na koniec
void pop_back() usuwa ostatni element
iterator erase(iterator pos) usuwa wskazany element
Programowanie Obiektowe 136
Iteratory
Ć" Uogólnienie wskazników.
Ć" Główny cel sprawne poruszanie się po strukturach danych.
Ć" Przykład: wskazniki istotnie szybciej pozwalają przebiec przez wszystkie
elementy tablicy niż iterowanie zmiennej całkowitej i dostęp do danych
przez operator[]:
1 const int n = 100000;
2 int tab[n];
3 // nieoptymalnie
4 for (int i=0; i
6 // optymalnie
7 for (int i = n, "p=tab+n; p--; )
8 "p = --i;
Programowanie Obiektowe 137
Ć" Podejście naiwne:
1 template
2 class Vector
3 {
4 protected:
5 T"data;
6 int size;
7 public:
8 Vector(int s) {data=new T[size=s]; }
9 ~Vector() {delete[] data;}
10 T &operator[] (int i) {return data[i];}
11 int Size() {return size;}
12 };
13 ...
14 Vector
15 ...
16 for (int i=0; i
Programowanie Obiektowe 138
Ć" Podejście z niepoprawnym iteratorem (wolniej niż naiwnie):
1 template
2 class Vector {
3 // ...
4 class Iterator {
5 T"ptr;
6 public:
7 Iterator(T"p) {ptr = p;}
8 T &operator"() {return"ptr;}
9 void operator ++() {ptr++;}
10 int operator <(const Iterator &i) {return ptr
12 Iterator begin() {return Iterator(data);}
13 Iterator end() {return Iterator(data+size);}
14 };
15 ...
16 Vector
17 for (int i=0; it
Programowanie Obiektowe 139
Ć" Podejście z poprawnym iteratorem:
1 template
2 class Vector
3 {
4 protected:
5 T"data;
6 int size;
7 public:
8 Vector(int s) {data=new T[size=s]; }
9 ~Vector() {delete[] data;}
10
11 typedef T"Iterator;
12 Iterator begin() {return data;}
13 Iterator end() {return data+size;}
14 };
15 ...
16 Vector
17 for (int i=0; it
Programowanie Obiektowe 140
deque
Ć" Przykład:
1 deque
2 Q.push_back(3);
3 Q.push_front(1);
4 Q.insert(Q.begin() + 1, 2);
5 Q[2] = 0;
6 copy(Q.begin(), Q.end(), ostream_iterator
7 // Na wyjściu dostaniemy: 1 2 0
Ć" Parametry:
T typ elementów
Alloc alokator pamięci
Programowanie Obiektowe 141
Ć" Niemal to samo co vector, ale dodaje i usuwa pierwszy element w stałym
czasie.
Ć" Nie posiada metod capacity() i reserve().
Ć" Dodatkowe składowe:
void push_front(const T&) wstawia element na poczÄ…tek
void pop_front() usuwa pierwszy element
Programowanie Obiektowe 142
list
Ć" Lista dwukierunkowa
Ć" Przykład:
1 list
2 L.push_back(0);
3 L.push_front(1);
4 L.insert(++L.begin(), 2);
5 copy(L.begin(), L.end(), ostream_iterator
6 // Na wyjściu dostajemy: 1 2 0
Ć" Parametry:
T typ elementów listy
Alloc alokator pamięci
Programowanie Obiektowe 143
Ć" Wybrane składowe:
reference typ: referencja na T
pointer typ: wskaznik na T
iterator typ do iterowania elementów
list() tworzy pustÄ… listÄ™
list(size_type n) tworzy listę n elementów T()
list(size_type n, const T& t) tworzy wektor z n kopii obiektu t
iterator begin() zwraca iterator wskazujÄ…cy na poczÄ…tek
iterator end() zwraca iterator wskazujÄ…cy na koniec
reference front() zwraca pierwszy element
reference back() zwraca ostatni element
size_type size() const zwraca rozmiar wektora
reference operator[](size_type n) zwraca n ty element
void reverse() odwraca kolejność elementów
void push_back(const T&) wstawia element na koniec
void remove(const T& value) usuwa elementy równe value
void merge(list& L) Å‚Ä…czy uporzÄ…dkowane listy
void sort() sortuje (stabilnie, złożoność nlogn)
Programowanie Obiektowe 144
slist
Ć" Lista jednokierunkowa
Ć" Przykład:
1 slist
2 L.push_front(0);
3 L.push_front(1);
4 L.insert_after(L.begin(), 2);
5 copy(L.begin(), L.end(), // Na wyjściu 1 2 0
6 ostream_iterator
7 cout << endl;
8
9 slist
10 back = L.insert_after(back, 3);
11 back = L.insert_after(back, 4);
12 back = L.insert_after(back, 5);
13 copy(L.begin(), L.end(), // Na wyjściu: 1 2 0 3 4 5
14 ostream_iterator
15 cout << endl;
Programowanie Obiektowe 145
Ć" Mniej zajętej pamięci niż w list
Ć" Większa złożoność pewnych operacji np insert() i erase()
Ć" Lista metod niemal identyczna z list
Programowanie Obiektowe 146
set
Ć" Implementacja zbioru reprezentowanego w sposób uporządkowany dla
sprawniejszej obsługi, wstawianie jednego (uporządkowanego) zbioru do
drugiego jest bardzo szybkie itp.
Ć" Prosty kontener asocjacyjny klucze i wartości (tutaj tożsame)
Ć" Parametry:
Key typ elementów zbioru (kluczy i wartości)
Compare funkcja porównująca zdefiniowana jako klasa
Alloc alokator pamięci
Ć" Przykład:
1 struct ltstr
2 {
3 bool operator()(const char"s1, const char"s2) const
4 {
5 return strcmp(s1, s2) < 0;
6 }
7 };
8
Programowanie Obiektowe 147
9 int main()
10 {
11 const int N = 6;
12 const char"a[N] = {"isomer", "ephemeral", "prosaic",
13 "nugatory", "artichoke", "serif"};
14 const char"b[N] = {"flat", "this", "artichoke",
15 "frigate", "prosaic", "isomer"};
16
17 set
18 set
19 set
20
21 cout << "Set A: ";
22 copy(A.begin(), A.end(), ostream_iterator
23 cout << endl;
24 cout << "Set B: ";
25 copy(B.begin(), B.end(), ostream_iterator
26 cout << endl;
27
Programowanie Obiektowe 148
28 cout << "Union: ";
29 set_union(A.begin(), A.end(), B.begin(), B.end(),
30 ostream_iterator
31 ltstr());
32 cout << endl;
33
34 cout << "Intersection: ";
35 set_intersection(A.begin(), A.end(), B.begin(), B.end(),
36 ostream_iterator
37 ltstr());
38 cout << endl;
39
40 set_difference(A.begin(), A.end(), B.begin(), B.end(),
41 inserter(C, C.begin()),
42 ltstr());
43 cout << "Set C (difference of A and B): ";
44 copy(C.begin(), C.end(), ostream_iterator
45 cout << endl;
46 }
Programowanie Obiektowe 149
multiset
Ć" Podobnie jak w set, ale z możliwymi powtórzeniami elementów
Ć" Przykład:
1 int main()
2 {
3 const int N = 10;
4 int a[N] = {4, 1, 1, 1, 1, 1, 0, 5, 1, 0};
5 int b[N] = {4, 4, 2, 4, 2, 4, 0, 1, 5, 5};
6
7 multiset
8 multiset
9 multiset
10
11 cout << "Set A: ";
12 copy(A.begin(), A.end(), ostream_iterator
13 cout << endl;
14 cout << "Set B: ";
15 copy(B.begin(), B.end(), ostream_iterator
Programowanie Obiektowe 150
16 cout << endl;
17
18 cout << "Union: ";
19 set_union(A.begin(), A.end(), B.begin(), B.end(),
20 ostream_iterator
21 cout << endl;
22
23 cout << "Intersection: ";
24 set_intersection(A.begin(), A.end(), B.begin(), B.end(),
25 ostream_iterator
26 cout << endl;
27
28 set_difference(A.begin(), A.end(), B.begin(), B.end(),
29 inserter(C, C.begin()));
30 cout << "Set C (difference of A and B): ";
31 copy(C.begin(), C.end(), ostream_iterator
32 cout << endl;
33 }
Programowanie Obiektowe 151
map
Ć" Posortowany kontener asocjacyjny przypisujący obiektom typu Key
(kluczom) obiekty typu Data (wartości).
Ć" Kontener par pair
Ć" Klucze muszą być unikalne.
Ć" Parametry:
Key typ kluczy
Data typ wartości
Compare funkcja porównująca klucze
Alloc alokator pamięci
Ć" Przykład:
1 struct ltstr
2 {
3 bool operator()(const char"s1, const char"s2) const
4 {
5 return strcmp(s1, s2) < 0;
6 }
7 };
Programowanie Obiektowe 152
8
9 int main()
10 {
11 map
12
13 months["january"] = 31;
14 months["february"] = 28;
15 months["march"] = 31;
16 months["april"] = 30;
17 months["may"] = 31;
18 months["june"] = 30;
19 months["july"] = 31;
20 months["august"] = 31;
21 months["september"] = 30;
22 months["october"] = 31;
23 months["november"] = 30;
24 months["december"] = 31;
25
26 cout << "june -> " << months["june"] << endl;
Programowanie Obiektowe 153
27 map
28 map
29 map
30 ++next;
31 --prev;
32 cout << "Previous (in alphabetical order) is "
33 << ("prev).first << endl;
34 cout << "Next (in alphabetical order) is "
35 << ("next).first << endl;
36 }
Programowanie Obiektowe 154
multimap
Ć" Podobnie jak w map, ale z możliwymi powtórzeniami kluczy
Ć" Przykład:
1 struct ltstr
2 {
3 bool operator()(const char"s1, const char"s2) const
4 {
5 return strcmp(s1, s2) < 0;
6 }
7 };
8
9 int main()
10 {
11 multimap
12
13 m.insert(pair
14 m.insert(pair
15 m.insert(pair
Programowanie Obiektowe 155
16 m.insert(pair
17 m.insert(pair
18 m.insert(pair
19
20 cout << "Number of elements with key a: " << m.count("a") << endl;
21 cout << "Number of elements with key b: " << m.count("b") << endl;
22 cout << "Number of elements with key c: " << m.count("c") << endl;
23
24 cout << "Elements in m: " << endl;
25 for (multimap
26 it != m.end();
27 ++it)
28 cout << " [" << ("it).first << ", " << ("it).second << "]" << endl;
29 }
Programowanie Obiektowe 156
Platforma .NET
Ć" .NET Framework = Common Language Runtime (CLR) + Framework
Class Library (FCL)
Ć" Środowisko a kompilatory
Ć" MSIL - MicroSoft Intermediate Language (Common Intermediate
Language - CIL)
î% wspólny kod wyjÅ›ciowy dla różnych jezyków programowania (Visual
Basic, C#, Managed C++, JScript. . . )
î% każdy program można Å‚atwo zdekompilować
î% programy utrudniajÄ…ce dekompilacjÄ™ - obfuscators
Ć" JIT (Just in Time) compiler
î% tworzy kod maszynowy dla danego procesora (jak w Javie)
î% optymalizacja na dany komputer bardzo poważna zaleta
Programowanie Obiektowe 157
Platforma .NET c.d.
Ć" Zarządzanie bibliotekami dynamicznymi
î% Zestaw (assembly) jako uogólnienie DLL
î% Zezwolenie na wiele wersji tego samego zestawu
Ć" bogactwo biblioteki standardowej .NET (FCL) przestrzenie nazw
nabierają jeszcze większego znaczenia
Ć" projekt MONO http://www.mono-project.com/ - .NET na Unix ach
Programowanie Obiektowe 158
Język C# podstawy
Ć" Brak plików nagłówkowych, bardzo szybka kompilacja
Ć" Wszystko wewnątrz klas
Ć" Identyfikatory to ciągi znaków Unicode (mogą zawierać polskie znaki)
Ć" Operator . zamiast ::
Ć" Pierwszy program
1 class Example
2 {
3 public static void Main () {
4 System.Console.WriteLine ("Hello world!");
5 }
6 }
Ć" Dostęp definiowany przy każdej składowej
Ć" Średniki po deklaracjach klas niepotrzebne
Programowanie Obiektowe 159
Przestrzenie nazw
Ć" Deklaracje dokładania do przestrzeni i korzystanie z przestrzeni
1 namespace Poczatki {
2 using System;
3 class Example {
4 public static void Main () {
5 Console.WriteLine ("Hello world!");
6 }
7 }
8 }
Ć" Można zagnieżdżać przestrzenie nazw tworząc hierarchię
Ć" Przykłady z hierarchii FCL
1 System.IO
2 System.Collections.Generic
3 System.Runtime.Serialization.Formatters.Binary
4 System.Security.Cryptography
Programowanie Obiektowe 160
Typy wartościowe i referencyjne
Ć" Stos i sterta (stack and heap)
î% stos obsÅ‚uga wywoÅ‚aÅ„ funkcji i zmiennych lokalnych
î% sterta miejsce na dynamicznie alokowane zmienne
î% czyszczenie stosu zwiÄ…zane z powrotami z funkcji
î% czyszczenie sterty przejmuje system zbierania odpadków (garbage
collection)
Ć" Typy wartościowe (typy proste, struct, enum)
1 class Test {
2 static void Main () {
3 int x = 3;
4 int y = x; // assign x to y, y is now a copy of x
5 x++; // increment x to 4
6 System.Console.WriteLine (y); // prints 3
7 }
8 }
Programowanie Obiektowe 161
Ć" Typy referencyjne (klasy, kolekcje, delegacje, interfejsy)
î% wartość i adres jej przechowywania w jednym
î% analogicznie do przekazywania parametrów przez referencjÄ™ w C++
î% syntaktycznie jak wartoÅ›ci, semantycznie jak wskazniki
1 using System;
2 using System.Text;
3 class Test {
4 static void Main () {
5 StringBuilder x = new StringBuilder ("hello");
6 StringBuilder y = x;
7 x.Append (" there");
8 Console.WriteLine (y); // prints "hello there"
9 }
10 }
Programowanie Obiektowe 162
Ć" typy wartościowe i referencyjne - przykład porównujący
1 class PointR { // typ referencyjny
2 public int x, y;
3 }
4 struct PointV { // typ wartościowy
5 public int x, y;
6 }
7 class Test {
8 static void Main() {
9 PointR a; // 4 bajty na stosie
10 PointV b; // 8 bajtów na stosie
11 a = new PointR(); // alokacja 8 bajtów na stercie
12 b = new PointV(); // zawołanie konstruktora
13 a.x = 7;
14 b.x = 7;
15 }
16 }
Programowanie Obiektowe 163
Ć" opakowywanie wartości w obiekty referencyjne i rozpakowywanie (boxing,
unboxing)
1 class Test {
2 static void Main () {
3 int x = 9;
4 object o = x; // box the int
5 int y = (int)o; // unbox the int
6 }
7 }
Programowanie Obiektowe 164
Predefiniowane typy wartościowe
Ć" typy całkowite
alias typ rozmiar znak
sbyte System.SByte 1 tak
short System.Int16 2 tak
int System.Int32 4 tak
long System.Int64 8 tak
byte System.Byte 1 nie
ushort System.UInt16 2 nie
uint System.UInt32 4 nie
ulong System.UInt64 8 nie
1 int ii = 5;
2 uint ui = 5U;
3 long ll = 5L;
4 ulong ul = 5UL;
Programowanie Obiektowe 165
Ć" typy rzeczywiste
alias typ rozmiar
float System.Single 4
double System.Double 8
decimal System.Decimal 16
1 float f = 3.14f;
2 double d = 3.14;
3 decimal m = 123456789.123456789m;
typ decimal:
î% 28-29 cyfr znaczÄ…cych, ale maÅ‚y zakres
î% szczególnie przydatny w finansach
Ć" char i bool
alias typ rozmiar
char System.Char 2
bool System.Boolean 1/2
Programowanie Obiektowe 166
Predefiniowane typy referencyjne
alias typ rozmiar
object System.Object 0/8
string System.String min. 20
Ć" object klasa bazowa dla wszystkich typów, dla referencyjnych 8 bajtów
Ć" string niezmienna sekwencja znaków Unicode
Ć" string zwykła klasa o specjalnym traktowaniu
1 string a1 = "\\\\server\\fileshare\\helloworld.cs";
2 string a2 = @"\\server\fileshare\helloworld.cs";
3 Console.WriteLine(a1==a2); // Prints "True"
4 string b1 = "First Line\r\nSecond Line";
5 string b2 = @"First Line
6 Second Line";
7 Console.WriteLine(b1==b2); // Prints "True"
Programowanie Obiektowe 167
Garbage collection
Ć" new - alokacja jak w C++
Ć" nie zwalniamy pamięci wprost (na wzór delete z C++)
Ć" garbage collection system system zarządzania pamięcią
î% zarzÄ…dza wszelkimi referencjami do obiektów
î% odzyskuje pamięć po niepotrzebnych obiektach
î% Uwaga! ważne zerowanie dÅ‚ugo żyjÄ…cych referencji, bo inaczej
wycieki pamięci
î% Uwaga! obiekty mogÄ… zmieniać swoje poÅ‚ożenie (adres) bez wiedzy
programisty
1 public void Test()
2 {
3 Macierz m = new Macierz();
4 m = null; // dla zmiennych lokalnych niepotrzebne
5 }
Programowanie Obiektowe 168
Garbage collection
1 // W klasie Macierz
2 public Macierz(Manager mgr)
3 {
4 mgr.Rejestruj(this); // mgr wrzuca this do kolekcji
5 ...
6 }
7 public void Test(Manager mgr)
8 {
9 Macierz m = new Macierz(mgr);
10 ...
11 // m nie będzie zwolniona, bo "trzyma" ją mgr
12 }
Programowanie Obiektowe 169
Typ wyliczeniowy
Ć" Standardowo wartości 0, 1, 2, . . .
1 enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
Ć" Wartości 1, 2, . . .
1 enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};
Ć" Wartości jawnie zadane i typ long:
1 enum Range : long {Max = 2147483648L, Min = 255L};
Ć" Brak konwersji niejawnych - trzeba jawnie
1 int i = (int)Days.Sun;
2 long l = (long)Range.Max;
Ć" Dostępne operatory: == != < > <= >= + - ^ & | ~ = += -= ++ --
sizeof
Programowanie Obiektowe 170
Tablice
Ć" System.Array zwykła klasa o specjalnym traktowaniu
Ć" syntaktyka podobna do C++, ale z pewnymi różnicami
Ć" tablice prostokątne i postrzępione (jagged)
1 int[] tab, tab2 = new int[15];
2 int[,] tab2d = new int[5,5];
3 double[][] macierz = new double[5][];
4 for (int i=0; i<5; i++)
5 macierz[i] = new int[10+i];
6 tab2[5] = tab2d[0,3] = 7;
7 macierz[0][3] = 7;
8 int[,] zainicjowana = {{1,2},{3,4}};
Ć" kontrola zakresów, wyjątek IndexOutOfRangeException, dzięki
optymalizacji nie musi dużo kosztować
Programowanie Obiektowe 171
Wybrane metody i własności klasy Array
Length długość tablicy
Rank liczba wymiarów
IsReadOnly czy tylko do odczytu
GetLength() długość w danym wymiarze
GetLowerBound() dolne ograniczenie danego wymiaru
GetUpperBound() górne ograniczenie danego wymiaru
Sort() sortowanie tablic jednowymiarowych
Reverse() odwracanie kolejności tablic jednowymiarowych
IndexOf() indeks pierwszego wystąpienia wartości
LastIndexOf() indeks ostatniego wystąpienia wartości
Copy() kopiowanie fragmentu
Clear() ustawianie wartości 0 lub null
Programowanie Obiektowe 172
Zmienne
Ć" ściśle określony typ (operacje, które można wykonywać)
Ć" każda zmienna musi być zainicjowana przed użyciem
Ć" wartości domyślne dla pól obiektów złożonych
î% numeryczne i wyliczeniowe 0
î% char \0
î% bool false
î% referencyjne null
Programowanie Obiektowe 173
Przekazywanie argumentów do metod
Ć" domyślnie przez wartość (działania na kopii)
Ć" w przypadku typów referencyjnych kopia referencji
Ć" ref przekazanie przez referencję
1 public void zamień(ref int a, ref int b)
2 {
3 int c = a;
4 a = b;
5 b = c;
6 }
Programowanie Obiektowe 174
Ć" out parametr traktowany jak wyjście funkcji, kompilator pilnuje by
zmiennej coś przypisać w funkcji
1 public void ustaw(out int a, out int b)
2 {
3 a = 5;
4 b = 7; // skomentuj jedną z linii by dostać błąd
5 }
Programowanie Obiektowe 175
Ć" ref i out konieczne również przy wywołaniach
Ć" zmienna przekazana z modyfikatorem out może nie być zainicjowana
1 public void test()
2 {
3 int x, y;
4 ustaw(out x, out y);
5 zamień(ref x, ref y);
6 }
Ć" nie ma mechanizmu domyślnych wartości parametrów metod, trzeba
jawnie przeciążać metody, by uzyskać ten sam efekt
1 public int Kalkuluj(int a, int b) { return ... }
2 public int Kalkuluj(int a) { return Kalkuluj(a, 0); }
Programowanie Obiektowe 176
Modyfikatory dostępu
Ć" public pełna widoczność
Ć" private dostęp tylko dla metod tej samej klasy
Ć" protected dostęp dla metod tej samej klasy i klas potomnych
Ć" internal dostęp w ramach zestawu (assembly)
Ć" protected internal suma logiczna warunków dostępu dla
protected i internal
Ć" domyślnie:
î% dla niezagnieżdżonych klas internal
î% dla skÅ‚adowych klas private
Ć" dziedziczenie zawsze publiczne!
Programowanie Obiektowe 177
Pola klas
Ć" pola mogą być inicjowane w linii deklaracji (przypisanie nastąpi przed
konstruktorem)
1 public class test
2 {
3 internal string kto = "Ala";
4 public string KtoTo() { return kto; }
5 }
Ć" pola statyczne są alokowane i inicjowane dopiero wtedy, gdy są potrzebne
Ć" pola tylko do odczytu
1 readonly int rozmiar = 100;
2 static readonly maxRozmiar = 1000;
î% wyznaczane w trakcie dziaÅ‚ania, nie kompilacji
î% muszÄ… być zainicjowane w linii deklaracji bÄ…dz w konstruktorze
Programowanie Obiektowe 178
Ć" pola stałe
1 public const double PI = 3.14159265358979323846;
î% wyznaczane w trakcie kompilacji
î% statyczne z zaÅ‚ożenia
î% dozwolone typy: sbyte, byte, short, ushort, int, uint, long,
ulong, float, double, decimal, bool, char, string, enum
î% muszÄ… być zainicjowane w linii deklaracji bÄ…dz w konstruktorze
Programowanie Obiektowe 179
Własności (properties)
Ć" implementowane inline
1 public class ProstokÄ…t
2 {
3 int lewa, góra, długość, szerokość;
4 public int Prawa {
5 get { return lewa + dlugość; }
6 set ( lewa = value - dlugość; }
7 }
8 }
Ć" w praktyce para metod get_Prawa() i set_Prawa(int value)
Programowanie Obiektowe 180
Operatory indeksujÄ…ce (indexers)
Ć" definiowane podobnie do własności
1 public class Tab5Double {
2 double[] tab = new double[5];
3 double suma;
4 public double this[int i] {
5 get { return tab[i]; }
6 set { suma += value-tab[i]; tab[i] = value; }
7 }
8 public double Srednia {
9 get { return suma / 5; }
10 }
11 }
Ć" można zdefiniować wiele operatorów o różnych listach argumentów
Programowanie Obiektowe 181
Konstruktory klas
Ć" jak w C++ tj. metody o nazwie klasy
1 public class TabDouble {
2 double[] tab;
3 TabDouble(int n) { tab = new double[n]; }
4 TabDouble() : this(n) {};
5 }
Ć" pola inicjowane w linii deklaracji przychodzą do konstruktora już
zainicjowane (w kolejności występowania w klasie)
Ć" mogą być opatrzone dowolnym modyfikatorem dostępu
Programowanie Obiektowe 182
Konstruktor statyczny
Ć" może być tylko jeden w klasie
Ć" wołany przed stworzeniem pierwszego obiektu i przed dostępem do
jakiegokolwiek pola statycznego klasy
1 public class TabDouble {
2 static TabManager tabmgr;
3 static TabDouble() { tabmgr = new TabManager(); }
4 }
Ć" pola statyczne inicjalizowane przed konstruktorem statycznym
Ć" kolejność wołania konstruktorów statycznych jest nieustalona, również
dziedziczenie nie ma tu znaczenia
Programowanie Obiektowe 183
Destruktor
Ć" Jak w C++ metoda o nazwie klasy poprzedzonej tyldą
Ć" Zadania całkiem inne niż w C++ ze względu na garbage collection
Ć" Bardzo rzadko potrzebne
Ć" Czas wykonania destruktora jest nieokreślony
Ć" Kompilowany do funkcji wirtualnej Finalize()
1 protected override void Finalize() {
2 ...
3 base.Finalize();
4 }
Programowanie Obiektowe 184
Dziedziczenie
Ć" Klasa bez jawnego dziedziczenia dziedziczy po object
Ć" Wielokrotne dziedziczenie jest niedozwolone
Ć" Prosty przykład:
1 public class Kwadrat : ProstokÄ…t {
2 public Kwadrat(int lewa, int góra, int bok)
3 : base(lewa, góra, bok, bok)
4 {
5 }
6 public OkrÄ…g OkrÄ…gWpisany();
7 }
Programowanie Obiektowe 185
Ć" Konwersje niejawne dozwolone tylko w stronę bazowej
1 Kwadrat k = new Kwadrat(0, 0, 5);
2 ProstokÄ…t p = k; // OK
3 Kwadrat w = (Kwadrat)p; // jawna konwersja konieczna
Ć" Nieudana jawna konwersja oznacza wyjątek InvalidCastException
Ć" Operator as (w wyniku null, gdy się nie uda)
1 Kwadrat w = p as Kwadrat;
Ć" Operator is (pytanie o dziedziczenie lub implementację interfejsu)
1 if (p is Kwadrat)
2 ((Kwadrat)p).OkragWpisany().Rysuj();
Programowanie Obiektowe 186
Polimorfizm
Ć" Polimorfizm to możliwość realizacji tego samego wywołania w kontekście
wielu typów.
Ć" Dziedziczenie klas i implementowanie interfejsów
Ć" Metody wirtualne
1 public class Figura {
2 public virtual void Rysuj() {throw new NotDefined();}
3 }
4 public class ProstokÄ…t : Figura {
5 public override void Rysuj() {...}
6 }
7 public class Kwadrat : ProstokÄ…t {
8 public override void Rysuj() {...}
9 }
Programowanie Obiektowe 187
Klasy abstrakcyjne
Ć" Klasy abstrakcyjne mogą zawierać metody abstrakcyjne
Ć" Metody abstrakcyjne to metody wirtualne bez implementacji:
1 public abstract class Figura {
2 public abstract void Rysuj();
3 }
Ć" W C++
1 class Figura {
2 public:
3 virtual void Rysuj() = 0;
4 }
Programowanie Obiektowe 188
Ć" Ukrywanie metod wirtualnych przerywanie wirtualności
1 public class Figura {
2 public virtual void Rysuj() {throw new NotDefined();}
3 }
4 public class ProstokÄ…t : Figura {
5 public override void Rysuj() {...}
6 }
7 public class Kwadrat : ProstokÄ…t {
8 public new void Rysuj() {...}
9 }
Wówczas:
1 Kwadrat k = new Kwadrat(0, 0, 5);
2 k.Rysuj(); // woła Kwadrat.Rysuj()
3 ((Figura)k).Rysuj(); // woła Prostokąt.Rysuj()
Programowanie Obiektowe 189
Ć" Modyfikator sealed klasy i metody zalakowane
î% Nie można dziedziczyć po zalakowanej klasie
1 public sealed class ProstokÄ…t : Figura {
2 ...
3 }
4 public class Kwadrat : ProstokÄ…t { // BÅ‚Ä…d!
5 ...
6 }
î% Pozwala kompilatorowi zmienić wywoÅ‚ania wirtualne na niewirtualne
î% Zwykle dla klas zawierajÄ…cych tylko statyczne metody (np. Math)
î% Można zalakować pojedyÅ„cze metody
1 public class ProstokÄ…t : Figura {
2 public sealed override Rysuj() {...}
3 }
Programowanie Obiektowe 190
SÅ‚owo kluczowe base
Ć" Daje dostęp do metod klasy bazowej
Ć" Podobne w użyciu jak słowo kluczowe this:
1 public class ProstokÄ…t : Figura {
2 public Prostokąt(int x, int y, int dług, int szer) {...}
3 public override void Rysuj() {...}
4 }
5 public class Kwadrat : ProstokÄ…t {
6 public Kwadrat(int x, int y, int bok)
7 : base(x, y, bok, bok) {...}
8 public Kwadrat(int bok)
9 : this(0, 0, bok) {...}
10 public override void Rysuj() {
11 base.Rysuj(); ...
12 }
13 }
Programowanie Obiektowe 191
Interfejsy
Ć" Interfejsy to specyfikacje możliwości klas (główne narzędzie polimorfizmu
w C#)
Ć" Klasy i struktury mogą implementować interfejsy tzn. implementować
wszystko co wyspecyfikowane w ramach interfejsu
Ć" Konstrukcje podobne do klas z kilkoma bardzo istotnymi różnicami:
î% Interfejsy nie zawierajÄ… implementacji żadnych metod (sÄ… trochÄ™ jak
klasy abstrakcyjne zawierające wyłącznie deklaracje abstrakcyjnych
metod)
î% Klasy i struktury mogÄ… implementować wiele interfejsów
î% Struktury mogÄ… implementować interfejsy, ale nie mogÄ… dziedziczyć klas
Ć" Interfejsy mogą zawierać deklaracje:
î% metod,
î% wÅ‚asnoÅ›ci,
î% operatorów indeksujÄ…cych,
î% zdarzeÅ„.
Programowanie Obiektowe 192
Ć" Definicja interfejsu
1 public interface ICloneable {
2 object Clone();
3 }
Ć" Interfejs może rozszerzać inne interfejsy:
1 public interface ITablica {
2 object this[int i] { get; set; }
3 }
4 public interface ISortowalnaTablica : ITablica {
5 void Sortuj();
6 }
Programowanie Obiektowe 193
Ć" Implementacja interfejsu
1 public class TablicaInt : ISortowalnaTablica {
2 public object this[int i] { get { return 0;} set {} }
3 public void Sortuj() { }
4 }
Ć" Implementacja interfejsu w sposób jawny (np. żeby uniknąć konfliktu, gdy
dwa interfejsy zawierają taką samą składową)
1 public class TablicaCalkowitych : ISortowalnaTablica {
2 object ITablica.this[int i] { get {return 1;} set {} }
3 void ISortowalnaTablica.Sortuj() { }
4 }
Ć" Dziedziczenie i implementacja najpierw klasa, potem interfejsy
1 public class Kwadrat : ProstokÄ…t, ICloneable {
2 ...
3 }
Programowanie Obiektowe 194
Reimplementacja interfejsu
Ć" Jeśli klasa bazowa implementuje składową interfejsu jako wirtualną, to
klasy potomne mogą je dociążać:
1 public class Bazowa : ICloneable {
2 public virtual object Clone() {return new Bazowa();}
3 }
4 public class Potomna : Bazowa {
5 public override object Clone() {return new Potomna();}
6 }
Ć" Uwaga na virtual/override!
Ć" Jeśli w powyższym Clone zabraknie virtual/override, to:
1 Potomna coÅ› = new Potomna();
2 (coś as ICloneable).Clone(); // woła Bazowa.Clone()
Programowanie Obiektowe 195
Ć" Można też reimplementować interfejs:
1 public class Bazowa : ICloneable {
2 public object Clone() {return new Bazowa();}
3 }
4 public class Potomna : Bazowa, ICloneable {
5 public object Clone() {return new Potomna();}
6 }
Wówczas:
1 Potomna coÅ› = new Potomna();
2 (coś as ICloneable).Clone(); // woła Potomna.Clone()
Programowanie Obiektowe 196
Delegaty
Ć" Sygnatury metod typy do przechowywania i wołania metod
(pojedyńczych bądz list metod) o określonej liście parametrów
1 delegate Figura Transformacja(Figura f);
2 class KolekcjaFigur {
3 Figura[] figury;
4 KolekcjaFigur Transformuj(Transformacja t)
5 {
6 KolekcjaFigur kf = new KolekcjaFigur(liczbaFigur);
7 foreach (Figura f in Figury)
8 kf.Dodaj(t(f));
9 return kf;
10 }
11 }
Programowanie Obiektowe 197
Ć" Argumenty mogą być specyfikowane z modyfikatorem params
1 delegate int Kombinacja(params int[] arg);
2 class Operacje
3 {
4 static public int Suma(params int[] argumenty) {
5 int wynik = 0;
6 foreach (int i in argumenty)
7 wynik += i;
8 return wynik;
9 }
10 static public void Main() {
11 Kombinacja k = new Kombinacja(Suma);
12 System.Console.WriteLine("Wynik = {0}", k(1, 2, 3, 4));
13 }
14 }
Programowanie Obiektowe 198
Ć" Operatory += i -= do obsługi delegatów przechowujących listy metod
1 delegate int Kombinacja(params int[] arg);
2 class Operacje
3 {
4 static public int Suma(params int[] argumenty) { ... }
5 static public int Iloczyn(params int[] argumenty) { ... }
6 static public void Main() {
7 Kombinacja k = new Kombinacja(Suma);
8 k += Iloczyn;
9 //k -= Suma;
10 System.Console.WriteLine("Wynik = {0}", k(1, 2, 3, 4));
11 }
12 }
î% Kolejność woÅ‚ania taka jak kolejność dodawania.
î% Delegat zwraca wynik ostatniej metody z listy.
Programowanie Obiektowe 199
Zdarzenia
Ć" Interfejsy graficzne sterowane zdarzeniami.
Ć" Delegaty doskonały środek do realizacji obsługi zdarzeń.
Ć" Konwencja: pierwszy argument to zródło, drugi to parametry zdarzenia
(dziedziczy po System.EventArgs):
1 delegate void MoveEventHandler(object source,
2 MoveEventArgs e);
Ć" Przykład parametrów zdarzenia:
1 public class MoveEventArgs : EventArgs {
2 public int newPosition;
3 public bool cancel;
4 public MoveEventArgs(int newPosition) {
5 this.newPosition = newPosition;
6 }
7 }
Programowanie Obiektowe 200
Ć" Przykład uruchomienia zdarzenia:
1 class Slider {
2 int position;
3 public event MoveEventHandler Move;
4 public int Position {
5 get { return position; }
6 set {
7 if (Move != null) { // if invocation list not empty
8 MoveEventArgs args = new MoveEventArgs(value);
9 Move(this, args); // fire event
10 if (args.cancel) return;
11 }
12 position = value;
13 }
14 }
15 }
Programowanie Obiektowe 201
Zestawy (ang. assembly)
Ć" Nowe podejście do bibliotek alokowanych dynamicznie.
Ć" Różne wersje tej samej biblioteki mogą równolegle funkcjonować w
systemie.
Ć" Zestaw może stanowić pojedynczy moduł (plik .dll lub .exe), albo kilka
modułów (słabe wsparcie).
Ć" Nie mylić z przestrzeniami nazw (ang. namespaces), choć często ta sama
nazwa jest użyta i dla zestawu i przestrzeni nazw.
Ć" Silne nazwy (strong names) unikalne, generowane przy użyciu klucza
prywatnego
Ć" Global Assembly Cache magazyn zestawów
Programowanie Obiektowe 202
Application domains
Ć" Proces = uruchomiona aplikacja.
Ć" System chroni procesy przed innymi procesami.
Ć" Domeny pozwalają na podobną ochronę w ramach jednego procesu.
Ć" Proces startuje z jedną domyślną domeną, dodatkowe można tworzyć
samemu w miarÄ™ potrzeby.
Ć" Wymiana danych pomiędzy domenami na tych samych zasadach co
między procesami.
Ć" Wiele wątków może biec w ramach jednej domeny.
Ć" Jeden wątek może pracować w ramach różnych domen (ale nie
jednocześnie).
Programowanie Obiektowe 203
Ć" Głowne składowe klasy AppDomain:
î% CurrentDomain statyczna wÅ‚asność, zwraca bieżącÄ… domenÄ™ dla
bieżącego wątku
î% CreateDomain() tworzy nowÄ… domenÄ™
î% GetCurrentThreadID() identyfikator bieżącego wÄ…tku
î% Load() Å‚aduje zestaw do domeny
î% Unload() usuwa zadanÄ… domenÄ™
î% CreateInstance() tworzy obiekt w domenie
Programowanie Obiektowe 204
Ć" Przykład:
1 AppDomain ad2 =
2 AppDomain.CreateDomain("Shape Domain");
3 ObjectHandle oh = ad2.CreateInstance(
4 "ProgCSharp", // the assembly name
5 "ProgCSharp.Shape", // the type name with namespace
6 false, // ignore case
7 System.Reflection.BindingFlags.CreateInstance, // flag
8 null, // binder
9 new object[] {3, 5}, // args
10 null, // culture
11 null, // activation attributes
12 null ); // security attributes
Programowanie Obiektowe 205
Atrybuty
Ć" Służą do opisywania elementów składniowych: zestaw, klasa, konstruktor,
delegat, typ wyliczeniowy, zdarzenie, pole, interfejs, metoda, moduł,
parametr, własność, wartość zwracana, struktura
Ć" Meta-dane o klasach, polach itd.
Ć" Przykłady:
1 [assembly: AssemblyKeyFile("c:\\myStrongName.key")]
2 [NoIDispatch]
3 public interface IEksperymentCOM {...}
4 [Serializable]
5 class MySerializableClass { ...}
Ć" Wstawia się je bezpośrednio przed deklaracją, której dotyczą, z wyjątkiem
tych dotyczących zestawów i modułów.
Ć" Atrybuty wewnętrzne wsparcie Common Language Runtime,
zintegrowane z .NET
Programowanie Obiektowe 206
Ć" Atrybuty użytkownika klasy dziedziczące po System.Attribute
1 public class MachineAttribute : Attribute
2 {
3 public string name;
4 public Type configType;
5 public MachineAttribute(string name, Type configType)
6 {
7 this.name = name;
8 this.configType = configType;
9 }
10 }
11
12 [Machine("Decision tree", typeof(DTConfig))]
13 public class DT : DTClassifier, IMachine
14 { ... }
Programowanie Obiektowe 207
Ć" Konwencja wspierana przez kompilator: nazwy klas kończą się na
Attribute
Ć" Koniecznie przynajmniej jeden konstruktor.
Ć" Parametry pozycyjne (argumenty konstruktora)
Ć" Parametry nazwane (własności)
1 [Machine("Decision tree", typeof(DTConfig),
2 Description="A standard greedy search decision tree")]
Ć" Atrybut atrybutów (meta-atrybut)
1 [AttributeUsage(AttributeTargets.Class,
2 AllowMultiple = false)]
3 public class MachineAttribute : Attribute
4 { ... }
Ć" Wiele atrybutów można wymienić w jednym nawiasie kwadratowym:
1 [Serializable, Machine(...)]
Programowanie Obiektowe 208
Mechanizm refleksji (reflection)
Ć" Dostęp do meta-danych.
Ć" Duże możliwości penetrowania hierarchii klas, wnętrz klas itd.
Ć" Klasa Type meta-dane o typach i ich wnętrznościach
Ć" Pobieranie informacji o typie
1 Type t = zmienna.GetType(); // metoda System.Object
2 Type t = Type.GetType("System.Int32");
3 Type t2 = Type.GetType("MyNamespace.MyType", MyAssembly);
4 Type t3 = typeof(System.Int32);
Programowanie Obiektowe 209
Ć" Przykład penetracji typów:
1 using System;
2 using System.Reflection;
3 class Test {
4 static void Main( ) {
5 DumpTypeInfo((new Object()).GetType( ));
6 DumpTypeInfo(typeof(int));
7 DumpTypeInfo(Type.GetType("System.String"));
8 }
9 static void DumpTypeInfo(Type t) {
10 Console.WriteLine("Type: {0}", t);
11 // Retrieve the list of members in the type
12 MemberInfo[ ] miarr = t.GetMembers( );
13 // Print out details on each of them
14 foreach (MemberInfo mi in miarr)
15 Console.WriteLine(" {0}={1}", mi.MemberType, mi);
16 }
17 }
Programowanie Obiektowe 210
Ć" Inne możliwości mechanizmów refleksji:
î% late binding Å‚adowanie bibliotek, tworzenie obiektów i woÅ‚anie metod na
etapie działania programu a nie kompilacji Uwaga! znacznie wolniej!
î% Modyfikacja pól prywatnych.
î% Tworzenie typów na etapie dziaÅ‚ania programu
(System.Reflection.Emit), klasy:
î% AssemblyBuilder dynamiczne tworzenie zestawów,
î% ModuleBuilder dynamiczne tworzenie modułów,
î% TypeBuilder dynamiczne tworzenie typów,
î% ILGenerator dynamiczne tworzenie kodu MSIL.
Programowanie Obiektowe 211
Serializacja
Ć" Konwersja złożonych hierarchicznych struktur danych do strumieni danych
Ć" Deserializacja operacja odwrotna
Ć" Przestrzenie nazw System.Runtime.Serialization.*,
System.Xml.Serialization.*.
Ć" Podział zadań: strumienie, obiekty formatujące, obiekty serializowane.
Ć" Jawna serializacja:
1 public void SerializeGraph(string file, object root) {
2 Stream stm = new FileStream(file, FileMode.Create);
3 IFormatter fmt = new BinaryFormatter( );
4 fmt.Serialize(stm, root);
5 stm.Flush( );
6 stm.Close( );
7 }
Programowanie Obiektowe 212
Ć" Jawna deserializacja:
1 public object DeserializeGraph(string file) {
2 Stream stm = new FileStream(file, FileMode.Open);
3 IFormatter fmt = new SoapFormatter( );
4 object o = fmt.Deserialize(stm);
5 stm.Close( );
6 return o;
7 }
Programowanie Obiektowe 213
Ć" Niejawna serializacja
î% gdy serializujemy obiekt zawierajÄ…cy jako pola inne serializowalne obiekty,
1 [Serializable]
2 public sealed class Person {
3 public string Name;
4 public int Age;
5 }
6
7 [Serializable]
8 public sealed class Team {
9 public string Name;
10 public Person[ ] Players;
11 }
î% gdy przekazujemy argumenty metodzie woÅ‚anej w innej domenie aplikacji,
1 public Team MergeTeams(Team teamOne, Team teamTwo) {...}
î% w innych przypadkach zdalnego uruchamiania.
Programowanie Obiektowe 214
Ć" Atrybut Serializable
î% Ustawia odpowiedni bit w meta-danych o typie.
î% Nie jest dziedziczony klasy potomne muszÄ… redeklarować atrybut.
î% Wszystkie skÅ‚adowe muszÄ… być też serializowalne.
Ć" Atrybut NonSerialized wyłącza pola z serializacji.
1 [Serializable]
2 public sealed class Person {
3 public string Name;
4 public DateTime DateOfBirth;
5 [NonSerialized] public int Age; // Can be calculated
6 // Rest of class...
7 }
Programowanie Obiektowe 215
Ć" Interfejs IDeserializationCallback pozwala ustawić po
deserializacji pola wyłączone z serializacji
1 [Serializable]
2 public sealed class Person : IDeserializationCallback {
3 public string Name;
4 public DateTime DateOfBirth;
5 [NonSerialized] public int Age; // Can be calculated
6 public void OnDeserialization(object o) {
7 TimeSpan ts = DateTime.Now - DateOfBirth;
8 Age = ts.Days/365; // Rough age in years
9 }
10 // Rest of class...
11 }
Programowanie Obiektowe 216
Ć" Interfejs ISerializable
î% Pozwala na wiÄ™cej kontroli nad szczegółami serializacji.
î% Potrzeba implementacji konstruktora deserializacyjnego:
1 [Serializable]
2 public sealed class Team : ISerializable {
3 public string Name;
4 public Person[ ] Players;
5 public void GetObjectData(SerializationInfo si,
6 StreamingContext sc) {
7 si.AddValue("IChangedTheFieldName", Name);
8 si.AddValue("Players", Players);
9 }
10 private Team(SerializationInfo si, StreamingContext sc) {
11 Name = si.GetString("IChangedTheFieldName");
12 Players = (Person[ ])si.GetValue("Players",
13 typeof(Person[ ]));
14 }
15 }
Programowanie Obiektowe 217
Strumienie
Ć" Abstrakcyjna klasa Stream i jej pochodne niskopoziomowy zapis i
odczyt
î% CanRead, CanWrite, CanSeek
î% Read(), Write() binarny odczyt i zapis
î% metody Seek(), SetLength() i wÅ‚asnoÅ›ci Position, Length
î% BeginRead(), EndRead(), BeginWrite(), EndWrite()
operacje asynchroniczne
î% Flush(), Close()
Programowanie Obiektowe 218
Ć" Klasy potomne:
î% Microsoft.JScript.COMCharStream
î% Microsoft.WindowsMobile.DirectX.GraphicsStream
î% System.IO.BufferedStream
î% System.IO.Compression.DeflateStream
î% System.IO.Compression.GZipStream
î% System.IO.FileStream
î% System.IO.MemoryStream
î% System.IO.UnmanagedMemoryStream
î% System.Net.Security.AuthenticatedStream
î% System.Net.Sockets.NetworkStream
î% System.Security.Cryptography.CryptoStream
Programowanie Obiektowe 219
Ć" Klasy usprawniające pisanie i czytanie
î% BinaryReader, BinaryWriter,
î% StreamReader, StreamWriter, Encoding,
î% StringReader, StringWriter,
î% TextReader, TextWriter abstrakcyjne klasy bazowe dla StreamXXX i
StringXXX.
Programowanie Obiektowe 220
Ć" Podstawowe klasy obsługi wejścia/wyjścia
î% Directory metody statyczne
î% DirectoryInfo metody w kontekÅ›cie obiektu
î% DriveInfo metody obsÅ‚ugi napÄ™du
î% File metody statyczne
î% FileInfo metody w kontekÅ›cie obiektu
î% FileSystemInfo klasa abstrakcyjna, bazowa dla FileInfo i DirectoryInfo
î% Path obsÅ‚uga Å›cieżek (wieloplatformowa)
î% SerialPort obsÅ‚uga portów szeregowych
î% File, FileInfo, DriveInfo, Path, Directory, DirectoryInfo
sealed
Programowanie Obiektowe 221
Ć" Podstawowy przykład użycia strumieni:
1 using System.IO;
2 class StreamFun {
3 static void Main() {
4 Stream s = new FileStream("foo.txt", FileMode.Create);
5 s.WriteByte(67);
6 s.WriteByte(35);
7 s.Close();
8 }
9 }
Programowanie Obiektowe 222
Ć" Buforowanie odczytu i zapisu:
1 void Run( )
2 {
3 Stream inStream = File.OpenRead("plik");
4 Stream outStream = File.OpenWrite("plik.kopia");
5 BufferedStream bufIn = new BufferedStream(inStream);
6 BufferedStream bufOut = new BufferedStream(outStream);
7
8 byte[] buffer = new Byte[1024];
9 int bytesRead;
10 while ( (bytesRead = bufIn.Read(buffer, 0, 1024)) > 0 )
11 bufOut.Write(buffer, 0, bytesRead);
12
13 bufOut.Flush( );
14 bufIn.Close( );
15 bufOut.Close( );
16 }
Programowanie Obiektowe 223
Ć" Bardziej zaawansowany przykład użycia strumieni:
1 using System;
2 using System.IO;
3 using System.Security.Cryptography;
4 class EncoderFun {
5 static void Main() {
6 Stream stm = new FileStream("foo.txt",
7 FileMode.Open, FileAccess.Read);
8 ICryptoTransform ict = new ToBase64Transform();
9 CryptoStream cs = new CryptoStream(stm,
10 ict, CryptoStreamMode.Read);
11 TextReader tr = new StreamReader(cs);
12 string s = tr.ReadToEnd();
13 Console.WriteLine(s);
14 }
15 }
Programowanie Obiektowe 224
Ć" Binarny zapis i odczyt:
1 public class Student {
2 public string Name;
3 public int Age;
4 public double GPA; }
5 void SaveToStream(Stream stm, Student s) {
6 BinaryWriter bw = new BinaryWriter(stm);
7 bw.Write(s.Name);
8 bw.Write(s.Age);
9 bw.Write(s.GPA);
10 bw.Flush(); // Ensure the BinaryWriter buffer is empty
11 }
12 void ReadFromStream(Stream stm, Student s) {
13 BinaryReader br = new BinaryReader(stm);
14 s.Name = br.ReadString();
15 s.Age = br.ReadInt32();
16 s.GPA = br.ReadDouble();
17 }
Programowanie Obiektowe 225
Ć" Strumienie tekstowe:
1 void SaveToStream(Stream stm, Student s) {
2 TextWriter tw = new StreamWriter(stm);
3 tw.WriteLine(s.Name);
4 tw.WriteLine(s.Age);
5 tw.WriteLine(s.GPA);
6 tw.Flush(); // Ensure the TextWriter buffer is empty
7 }
8 void ReadFromStream(Stream stm, Student s) {
9 TextReader tr = new StreamReader(stm);
10 s.Name = tr.ReadLine();
11 s.Age = Int32.Parse(tr.ReadLine());
12 s.GPA = Double.Parse(tr.ReadLine());
13 }
Programowanie Obiektowe 226
Ć" Aańcuchy znaków jako strumienie:
1 using System;
2 using System.IO;
3 using System.Text;
4 class Test {
5 static void Main() {
6 StringBuilder sb = new StringBuilder();
7 StringWriter sw = new StringWriter(sb);
8 WriteHello(sw);
9 Console.WriteLine(sb);
10 }
11 static void WriteHello(TextWriter tw) {
12 tw.Write("Hello, String I/O!");
13 }
14 }
Programowanie Obiektowe 227
Ć" Asynchroniczne wejście/wyjście:
1 usingSystem;
2 usingSystem.IO;
3 usingSystem.Text;
4 classAsyncReadFun{
5 classAsyncReadState{
6 publicStreamstm;// Underlying stream
7 publicbyte[]buf=newbyte[256];// Read buffer
8 publicStringBuildersb=newStringBuilder();// Result buffer
9 publicAsyncCallbackacb=newAsyncCallback(ReadCallback);
10 }
11 staticvoidAReadCallback(IAsyncResultiar) {
12 AsyncReadStatears= (AsyncReadState)iar.AsyncState;
13 intbytes=ars.stm.EndRead(iar);// Get count of bytes read
14 if(bytes> 0) {// Copy read bytes and restart read
15 ars.sb.Append(Encoding.ASCII.GetString(ars.buf, 0,bytes));
16 Console.WriteLine("Read chunk of {0} bytes",bytes);
17 ars.stm.BeginRead(ars.buf, 0,ars.buf.Length,ars.acb,ars);
18 }
Programowanie Obiektowe 228
19 }
20 staticvoidMain(string[]args) {
21 // Open the stream & start reading
22 Streams=File.OpenRead(args[0]);
23 AsyncReadStatears=newAsyncReadState();
24 ars.stm=s;// Save the stream reference
25 IAsyncResultiar=s.BeginRead(ars.buf, 0,ars.buf.Length,
26 ars.acb,ars);
27 // Download a file while we re reading the stream
28 System.Net.WebClientwc=newSystem.Net.WebClient();
29 wc.DownloadFile("http://www.oreilly.com","index.html");
30 Console.WriteLine("Finished downloading index.html.");
31 // Wait until the async read is done
32 iar.AsyncWaitHandle.WaitOne();
33 Console.WriteLine(ars.sb);
34 }
35 }
Programowanie Obiektowe 229
Typy ogólne generics
Ć" Idea mniej-więcej ta sama co szablonów w C++: typy sparametryzowane
typami.
Ć" Różnice:
î% Parametrami mogÄ… być tylko typy.
î% ZaÅ‚ożenia co do typu parametryzujÄ…cego muszÄ… być ujawnione w
deklaracji klasy ogólnej.
î% Typy kompilowane do kodu poÅ›redniego, typy szczegółowe powstajÄ…
dopiero w wyniku działania komplatora JIT
Ć" Przykład korzystania:
1 Stack
2 for (int i=0; i<10; i++)
3 stack.Push(i);
4 for (int i=0; i<10; i++)
5 Console.WriteLine(stack.Pop());
Programowanie Obiektowe 230
Ć" Kolekcje
î% ICollection
f& Count,
f& CopyTo().
î% IEnumerable
f& GetEnumerator().
î% IEnumerator
f& Current,
f& MoveNext(), Reset().
î% foreach uÅ‚atwia używanie enumeratorów.
î% wersja 2.0 iteratory, yield return oraz yield break
1 public IEnumerator GetEnumerator() {
2 for (int i = count - 1; i >= 0; --i) {
3 yield return items[i];
4 }
5 }
î% PrzestrzeÅ„ nazw System.Collections.Generic.
Programowanie Obiektowe 231
Ć" Ogólne klasy
î% Comparer klasa bazowa dla imlplementacji IComparer.
î% Dictionary sÅ‚ownik (kolekcja par klucz wartość).
î% Dictionary.KeyCollection Kolekcja kluczy sÅ‚ownika.
î% Dictionary.ValueCollection Kolekcja wartoÅ›ci sÅ‚ownika.
î% EqualityComparer klasa bazowa dla implementacji
IEqualityComparer.
î% KeyNotFoundException wyjÄ…tek dla sÅ‚owników.
î% LinkedList lista dwukierunkowa.
î% LinkedListNode wÄ™zeÅ‚ listy dwukierunkowej.
î% List lista indeksowana.
î% Queue kolejka.
î% SortedDictionary sÅ‚ownik posortowany.
î% SortedDictionary.KeyCollection.
î% SortedDictionary.ValueCollection.
î% SortedList kolekcja par klucz-wartość posortowanych przy użyciu
implementacji IComparer.
î% Stack stos.
Programowanie Obiektowe 232
Ć" Ogólne interfejsy
î% ICollection
f& Count, IsReadOnly,
f& Add(), Clear(), Contains(), CopyTo(), Remove().
î% IComparer
f& Compare()
î% IDictionary
ICollection
IEnumerable
f& Item[], Keys, Values,
f& Add(), ContainsKey(), Remove(), TryGetValue()
î% IEnumerable
f& GetEnumerator()
î% IEnumerator
f& Current,
f& MoveNext(), Reset()
Programowanie Obiektowe 233
î% IEqualityComparer
f& Equals(), GetHashCode()
î% IList
f& Item[],
f& IndexOf(), Insert(), RemoveAt()
Programowanie Obiektowe 234
Ć" Ogólne struktury
î% Dictionary.Enumerator
î% Dictionary.KeyCollection.Enumerator
î% Dictionary.ValueCollection.Enumerator
î% KeyValuePair
î% LinkedList.Enumerator
î% List.Enumerator
î% Queue.Enumerator
î% SortedDictionary.Enumerator
î% SortedDictionary.KeyCollection.Enumerator
î% SortedDictionary.ValueCollection.Enumerator
î% Stack.Enumerator
Programowanie Obiektowe 235
Ć" Przykład użycia słownika:
1 Dictionary
2 new Dictionary
3 wzrost.Add("Mariusz", 197);
4 wzrost.Add("Marcin", 211);
5 Console.WriteLine("Mariusz ma {0} cm wzrostu, a Marcin {1}",
6 wzrost["Mariusz"], wzrost["Marcin"]);
Programowanie Obiektowe 236
Ć" Definiowanie klas ogólnych:
1 public class Tablica
2 {
3 T[] tablica;
4 Tablica(int n) {
5 tablica = new T[n];
6 }
7 T this[int i] { return tablica[i]; }
8 ...
9 }
Programowanie Obiektowe 237
Ć" Założenia co do typów-parametrów:
1 public class Dictionary
2 where K: IComparable
3 {
4 public void Add(K key, V value)
5 {
6 ...
7 if (key.CompareTo(x) < 0) {...}
8 ...
9 }
10 }
Programowanie Obiektowe 238
Ć" Metody ogólne
1 public static swap
2 {
3 T z = x;
4 x = y;
5 y = z;
6 }
Ć" Założenia co do typów-parametrów metod:
1 public static Min
2 where T : IComparable
3 {
4 T min = tab[0];
5 for (int i=0; i
7 min = tab[i];
8 return min;
9 }
Programowanie Obiektowe 239
WyjÄ…tki
Ć" Schemat:
1 try {
2 ...
3 }
4 catch (ExceptionA e) {
5 ...
6 }
7 catch (ExceptionB e) {
8 ...
9 }
10 finally {
11 ...
12 }
Ć" Musi wystąpić przynajmniej jedna sekcja catch lub finally.
Ć" catch i finally się wzajemnie nie wykluczają jak w C++.
Programowanie Obiektowe 240
Ć" Tylko pierwsza pasująca sekcja catch jest wykonywana.
Ć" Klasy wyjątków muszą dziedziczyć po System.Exception.
Ć" Klasa System.Exception zawiera m.in. własności:
î% Message opis wyjÄ…tku,
î% StackTrace stos wywoÅ‚aÅ„,
î% TargetSite metoda, która zgÅ‚osiÅ‚a wyjÄ…tek,
î% Data sÅ‚ownik z dodatkowymi informacjami o wyjÄ…tku.
Ć" Przykład:
1 publicclassWeightCalculator
2 {
3 publicstaticfloatCalcBMI(floatkilos,floatmeters) {
4 if(meters< 0 ||meters> 3)
5 thrownewArgumentException("Impossible Height","meters");
6 if(kilos< 0 ||kilos> 1000)
7 thrownewArgumentException("Impossible Weight","kilos");
8 returnkilos/ (meters"meters);
9 }
10 }
Programowanie Obiektowe 241
11 classTest{
12 staticvoidMain() {
13 TestIt();
14 }
15 staticvoidTestIt() {
16 try{
17 floatbmi=WeightCalculator.CalcBMI(100, 5);
18 Console.WriteLine(bmi);
19 }
20 catch(ArgumentExceptionex) {
21 Console.WriteLine(ex);
22 }
23 finally{
24 Console.WriteLine("Thanks for running the program");
25 }
26 Console.Read();
27 }
28 }
Programowanie Obiektowe 242
Tryb niechroniony - unsafe
Ć" Metody i bloki niechronione oznacza się słowem kluczowym unsafe.
Ć" Używanie wskazników możliwe jest tylko w trybie niechronionym.
Konieczne jest wówczas przyszpilowanie obiektu deklaracją fixed.
Ć" Przykład:
1 unsafe void RedFilter(int[,] bitmap) {
2 const int length = bitmap.Length;
3 fixed (int* b = bitmap) {
4 int* p = b;
5 for(int i = 0; i < length; i++)
6
*p++ &= 0xFF;
7 }
8 }
Programowanie Obiektowe 243
Ć" Przykład mnożenia macierzy:
1 public static Macierz operator*(Macierz m1, Macierz m2) {
2 Macierz m3 = new Macierz(m1.LWierszy, m2.LKolumn);
3 unsafe {
4 fixed (double* pocz1 = m1.wartości) {
5 fixed (double* pocz2 = m2.wartości) {
6 fixed (double* pocz3 = m3.wartości) {
7 double
*p1 = pocz1,
8 koniec1 = pocz1+m1.LWierszy*m1.LKolumn;
9 while (p1 < koniec1)
10 {
11 ...
12 }
13 }
14 }
15 }
16 }
17 }
Wyszukiwarka
Podobne podstrony:
Programowanie w C i pro obiektowe wyklad C
Programowanie i jezyk C Wyklad 02 Instrukcje
Programowanie Obiektowe Ćwiczenia 5
[C ]Rataj Podstawy programowania obiektowego
Programowanie Obiektowe W Visual Basic Net Dla Ka dego
JavaScript Programowanie obiektowe
Programowanie obiektowe pojęcia
Podstawy Programowania 04 Programowanie Obiektowe
Jezyk C?ektywne programowanie obiektowe cpefpo
Programowanie Obiektowe W Pythonie
świerszczyński,programowanie obiektowe,Konstruktory i destruktory
Programowanie i jezyk C Wyklad 01 Typy danych
Programowanie obiektowe i C
więcej podobnych podstron