Podstawy programowania obiektowego



Podobne dokumenty
Programowanie obiektowe i zdarzeniowe

Podstawy programowania obiektowego

Programowanie obiektowe i zdarzeniowe

Wykład 5 Okna MDI i SDI, dziedziczenie

Polimorfizm, metody wirtualne i klasy abstrakcyjne

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

Zaawansowane programowanie w C++ (PCP)

Programowanie obiektowe

Wykład 4: Klasy i Metody

Mechanizm dziedziczenia

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Programowanie obiektowe w języku

Programowanie obiektowe

Dziedziczenie. dr Jarosław Skaruz

Wykład 6: Dziedziczenie

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

TEMAT : KLASY DZIEDZICZENIE

Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

Zaawansowane programowanie w C++ (PCP)

Definiowanie własnych klas

Dokumentacja do API Javy.

Programowanie obiektowe

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Metody Metody, parametry, zwracanie wartości

Wykład 7: Pakiety i Interfejsy

.NET Klasy, obiekty. ciąg dalszy

Wykład 12. Programowanie serwera MS SQL 2005 w C#

Enkapsulacja, dziedziczenie, polimorfizm

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Zaawansowane programowanie w języku C++ Programowanie obiektowe

Programowanie obiektowe

C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie C++ - DZIEDZICZENIE.

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Dziedziczenie Dana jest klasa Punkt w pliku o nazwie Punkt.java:

Programowanie 2. Język C++. Wykład 3.

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.

Programowanie obiektowe

DOSTĘP DO METOD I ZMIENNYCH. Dostęp do zmiennych (na podstawie:l.lemay,r.cadenhead,java 2 dla każdego, Helion 2001)

Dziedziczenie. » Dodawanie nowych elementów klasy (składowych funkcyjnych, danych składowych)» Modyfikacje odziedziczonych składowych funkcyjnych

Programowanie obiektowe

Informatyka I. Dziedziczenie. Nadpisanie metod. Klasy abstrakcyjne. Wskaźnik this. Metody i pola statyczne. dr inż. Andrzej Czerepicki

Mechanizm dziedziczenia

Wykład V. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Programowanie obiektowe

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

Programowanie obiektowe

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

PARADYGMATY PROGRAMOWANIA Wykład 4

Rozdział 4 KLASY, OBIEKTY, METODY

Programowanie obiektowe Wykład 6. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14

Dziedziczenie. Ogólna postać dziedziczenia klas:

Podstawy programowania obiektowego

Klasy. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 13

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Wykład 8: Obsługa Wyjątków

Aplikacje w środowisku Java

Technologie i usługi internetowe cz. 2

Polimorfizm. dr Jarosław Skaruz

Programowanie Obiektowe Ćwiczenie 4

Programowanie w C++ Wykład 14. Katarzyna Grzelak. 3 czerwca K.Grzelak (Wykład 14) Programowanie w C++ 1 / 27

Plik klasy. h deklaracje klas

Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego. Iwona Kochaoska

Programowanie obiektowe i zdarzeniowe

Laboratorium z przedmiotu: Inżynieria Oprogramowania INEK Instrukcja 6

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 20 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 32

Programowanie w C++ Wykład 13. Katarzyna Grzelak. 4 czerwca K.Grzelak (Wykład 13) Programowanie w C++ 1 / 26

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

WSNHiD, Programowanie 2 Lab. 2 Język Java struktura programu, dziedziczenie, abstrakcja, polimorfizm, interfejsy

Platformy Programistyczne Wykład z Javy dla zaawansowanych

Podstawy Języka Java

Programowanie obiektowe

Języki i metody programowania Java. Wykład 2 (część 2)

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

Java: interfejsy i klasy wewnętrzne

11.6 Klasa do obsługi liczb wymiernych

dr inż. Jarosław Forenc

Przypomnienie o klasach i obiektach

Programowanie obiektowe

Programowanie obiektowe

Języki i metody programowania Java Lab2 podejście obiektowe

Obiekty: co i jak. Wykonał: Piotr Pięda dla koła naukowego KNI

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Instrukcja 2 Laboratorium z Podstaw Inżynierii Oprogramowania

Podstawy programowania obiektowego

Programowanie w Javie 1 Wykład i Ćwiczenia 3 Programowanie obiektowe w Javie cd. Płock, 16 października 2013 r.

Klasy i obiekty cz II

MAS dr. Inż. Mariusz Trzaska. Realizacja różnych modeli dziedziczenia w obiektowych językach programowania

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Dziedziczenie jednobazowe, poliformizm

Języki i metody programowania Java INF302W Wykład 2 (część 1)

Przykład -

Decorator (dekorator)

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Transkrypt:

1/41 Podstawy programowania obiektowego wykład 5 dziedziczenie i wyjątki Dziedziczenie jest sposobem na utworzenie nowej klasy na podstawie klasy już istniejącej. Dziedziczenie tworzy szczególną (bardziej specyficzną) odmianę klasy istniejącej. Klasa istniejąca (z której dziedziczymy) nazywana jest klasą bazową. Nowa klasa (utworzona przez dziedziczenie) nazywana jest klasą pochodną. Relacja między klasą istniejącą (bardziej ogólną), a nową (specjalizowaną) wyraża się poprzez sformułowania: <klasa pochodna> jest szczególnym przypadkiem <klasy bazowej> <klasa pochodna> jest rodzajem <klasy bazowej> <klasa bazowa> jest uogólnieniem <klasy pochodnej>

2/41 Np.: Koło jest szczególnym przypadkiem figury Przesyłka polecona jest rodzajem przesyłki pocztowej Osoba jest uogólnieniem pracownika class Osoba class Figura class PrzesyłkaPocztowa class Pracownik : Osoba class Koło : Figura class PrzesyłkaPolecona : PrzesyłkaPocztowa

3/41 Klasa pochodna dziedziczy pola i metody klasy bazowej: class Osoba public string imię; public string nazwisko; public override string ToString() return imię + " " + nazwisko; class Pracownik : Osoba // pusto

Klasa pochodna dziedziczy pola i metody klasy bazowej: class Osoba public string imię; public string nazwisko; public override string ToString() return... class Pracownik : Osoba // pusto class Program static void Main(string[] args) Osoba os = new Osoba(); Jan Kowalski os.imię = "Jan"; os.nazwisko = "Kowalski"; Console.WriteLine(os.ToString()); Pracownik pr = new Pracownik(); pr.imię = "Piotr"; pr.nazwisko = "Nowak"; Console.WriteLine(pr.ToString()); Piotr Nowak 4/41

5/41 Klasa pochodna może dodać własne pola: class Osoba public string imię; public string nazwisko; public override string ToString() return imię + " " + nazwisko; class Pracownik : Osoba public double płaca;

6/41 Klasa pochodna może dodać własne pola: class Osoba public string imię; public string nazwisko; public override string ToString() return imię + " " + nazwisko; class Pracownik : Osoba public double płaca; class Program static void Main(string[] args) Pracownik pr = new Pracownik(); pr.imię = "Piotr"; pr.nazwisko = "Nowak"; Console.WriteLine(pr.ToString()); Piotr Nowak pr.płaca = 2200.0;

7/41 Klasa pochodna może dodać własne metody: class Osoba public string imię; public string nazwisko; public override string ToString() return imię + " " + nazwisko; class Pracownik : Osoba public double płaca; public void Wypłać() Console.WriteLine(imię + " " + nazwisko + " otrzymuje " + płaca + "zł");

Klasa pochodna może dodać własne metody: class Osoba... class Pracownik : Osoba public double płaca; public void Wypłać() Console.WriteLine(imię + " " + nazwisko + " otrzymuje " + płaca + "zł"); class Program static void Main(string[] args) Pracownik pr = new Pracownik(); Piotr Nowak pr.imię = "Piotr"; pr.nazwisko = "Nowak"; Console.WriteLine(pr.ToString()); pr.płaca = 2200.0; pr.wypłać(); Piotr Nowak otrzymuje 2200.0 zł 8/41

Klasa pochodna może nadpisać (przesłonić) metodę klasy bazowej: class Osoba... public override string ToString() return imię + " " + nazwisko; class Pracownik : Osoba... public override string ToString() return imię + " " + nazwisko + ": " + płaca; class Program static void Main(string[] args) Pracownik pr = new Pracownik(); pr.imię = "Piotr"; pr.nazwisko = "Nowak"; Piotr Nowak: 2200.0 pr.płaca = 2200.0; Console.WriteLine(pr.ToString()); 9/41

10/41 Klasa pochodna może nadpisać (przesłonić) metodę klasy bazowej. Poprzednia (odziedziczona) wersja metody nadal jest dostępna. Można się do niej odwołać przy pomocy słowa kluczowego base. class Osoba... public override string ToString() return imię + " " + nazwisko; class Pracownik : Osoba public override string ToString() return base.tostring() + ": " + płaca;

11/41 Do odziedziczonej wersji metody można się odwołać przy pomocy słowa kluczowego base. class Osoba... class Pracownik : Osoba public double płaca; public void Wypłać()... public override string ToString() return base.tostring() + ": " + płaca; class Program static void Main(string[] args) Pracownik pr = new Pracownik(); pr.imię = "Piotr"; pr.nazwisko = "Nowak"; Piotr Nowak: 2200.0 pr.płaca = 2200.0; Console.WriteLine(pr.ToString());

12/41 Klasa pochodna nie dziedziczy konstruktorów z klasy bazowej! class Osoba public string imię; public string nazwisko; public Osoba(string imię, string nazwisko) this.imię = imię; this.nazwisko = nazwisko; public override string ToString()... class Pracownik : Osoba public double płaca;... class Program static void Main(string[] args) Osoba os = new Osoba("Jan", "Kowalski"); Pracownik pr = new Pracownik("Piotr", "Nowak"); Błąd!

Klasa pochodna nie dziedziczy konstruktorów z klasy bazowej. class Osoba public string imię; public string nazwisko; public Osoba(string imię, string nazwisko)... public override string ToString()... class Pracownik : Osoba public double płaca; Musimy dostarczyć własny konstruktor public Pracownik(string im, string nazw, double płaca) this.imię = im; this.nazwisko = nazw; this.płaca = płaca;... class Program Nadal błąd? static void Main(string[] args) Osoba os = new Osoba("Jan", "Kowalski"); Pracownik pr = new Pracownik("Piotr", "Nowak", 2200.0); 13/41

14/41 Klasa pochodna to klasa bazowa plus dodatki (nowe pola, nowe metody). Obiekt klasy pochodnej jest to obiekt klasy bazowej z dodatkami (z nowymi polami, nowymi metodami). Wewnątrz obiektu klasy Pracownik znajduje się obiekt klasy Osoba. W momencie tworzenia obiektu klasy Pracownik najpierw musi być stworzony obiekt klasy Osoba: pr class Osoba public Osoba() Console.WriteLine("Tworzę osobę.");... class Pracownik : Osoba public Pracownik() Console.WriteLine("Tworzę pracownika.");...... Pracownik pr = new Pracownik(); Pracownik Osoba imię nazwisko Osoba(...) ToString() płaca Pracownik(...) Wypłać() ToString() Tworzę osobę. Tworzę pracownika.

15/41 W momencie tworzenia obiektu klasy pochodnej najpierw musi być wywołany konstruktor klasy bazowej. Jeśli konstruktor przyjmuje jakieś parametry, należy mu je przekazać. Służy do tego słowo kluczowe base. this Pracownik class Osoba base Osoba public string imię; imię public string nazwisko; nazwisko public Osoba(string imię, string nazwisko) Osoba(...) this.imię = imię; tostring() this.nazwisko = nazwisko; płaca Pracownik(...) wypłać() class Pracownik : Osoba tostring() public double płaca; public Pracownik(string im, string nazw, double płaca): base(imię, nazwisko) this.płaca = płaca;... Pracownik pr = new Pracownik("Piotr", "Nowak", 2200.0);

16/41 Przykład: konto z oprocentowaniem. class Konto private double suma; public Konto(double wkład) suma = wkład; public void Wpłać(double kwota) suma += kwota; public void Wypłać(double kwota) suma -= kwota; public double Saldo() return suma; class KontoOprocentowane : Konto private double procent; public KontoOprocentowane(double wkład, double proc) : base(wkład) procent = proc; public void NaliczProcent() suma += suma * procent; Błąd!

17/41 Przykład: konto z oprocentowaniem. class Konto protected double suma; public Konto(double wkład) poza dostępem suma = publicznym wkład; i public void Wpłać(double prywatnym, kwota) mamy suma do += kwota; public void Wypłać(double dyspozycji kwota) również suma dostęp -= kwota; public double Saldo() return chroniony suma; (składowe dostępne dla klas pochodnych) class KontoOprocentowane : Konto private double procent; public KontoOprocentowane(double wkład, double proc) : base(wkład) procent = proc; public void NaliczProcent() suma += suma * procent;

18/41 Przykład: konto z oprocentowaniem. class Program static void Main(string[] args) KontoOprocentowane konto; konto = new KontoOprocentowane(1000.0, 0.05); konto.wpłać(200.0); konto.naliczprocent(); konto.wypłać(500.0); Console.WriteLine(konto.Saldo()); 760.0

19/41 Klasa pochodna dziedziczy nie tylko pola i metody, ale również typ. class Osoba protected String imię; protected String nazwisko; class Pracownik : Osoba protected double płaca; public void wypłać() /*...*/ Klasa Pracownik dziedziczy z klasy Osoba, a zatem Pracownik jest szczególnym rodzajem Osoby, a zatem Pracownik jest Osobą. Co z tego wynika? Rzutowanie w górę: Tworzymy Pracownika, ale traktujemy go jako Osobę. Osoba os = new Pracownik("Piotr", "Nowak", 2200.0); os.wypłać();

20/41 Klasa pochodna dziedziczy nie tylko pola i metody, ale również typ. class Osoba protected String imię; protected String nazwisko; class Pracownik : Osoba protected double płaca; public void wypłać() /*...*/ Osoba os = new Pracownik("Piotr", "Nowak", 2200.0); os.wypłać(); //... Pracownik pr = (Pracownik)os; pr.wypłać(); Rzutowanie w dół: Tę Osobę potraktujemy jako Pracownika (to działa, gdyż faktycznie jest to Pracownik).

21/41 Klasa pochodna dziedziczy nie tylko pola i metody, ale również typ. class Osoba protected String imię; protected String nazwisko; class Pracownik : Osoba protected double płaca; public void wypłać() /*...*/ Osoba os = new Pracownik("Piotr", "Nowak", 2200.0); os.wypłać(); //... if(os is Pracownik) Pracownik pr = (Pracownik)os; pr.wypłać(); Rzutowanie w dół: Bezpieczniejsze rozwiązanie sprawdzenie faktycznego typu obiektu

22/41 Klasa pochodna dziedziczy nie tylko pola i metody, ale również typ. class Osoba protected String imię; protected String nazwisko; class Pracownik : Osoba protected double płaca; public void wypłać() /*...*/ Osoba os = new Pracownik("Piotr", "Nowak", 2200.0); os.wypłać(); //... Pracownik pr = os as Pracownik; if (pr!= null) pr.wypłać(); Rzutowanie w dół: Jeszcze inne rozwiązanie null oznacza brak obiektu pod tą referencją

23/41 Do czego może się to przydać? Dzięki temu możemy traktować w jednakowy sposób wiele obiektów należących do jednej rodziny (hierarchii) określane jest to jako polimorfizm. class Figura public void rysuj() Console.WriteLine("rysuję figurę"); class Trójkąt : Figura public void rysuj() Console.WriteLine("rysuję trójkąt"); class Koło : Figura public void rysuj() Console.WriteLine("rysuję koło"); class Prostokąt : Figura public void rysuj() Console.WriteLine("rysuję prostokąt");

24/41 Do czego może się to przydać? Dzięki temu możemy traktować w jednakowy sposób wiele obiektów należących do jednej rodziny (hierarchii) określane jest to jako polimorfizm. static void Main(string[] args) Figura[] figury = new Figura[10]; figury[0] = new Koło(); figury[1] = new Trójkąt(); figury[2] = new Prostokąt();

Do czego może się to przydać? Dzięki temu możemy traktować w jednakowy sposób wiele obiektów należących do jednej rodziny (hierarchii) określane jest to jako polimorfizm. static void Main(string[] args) Figura[] figury = new Figura[10]; figury[0] = new Koło(); figury[1] = new Trójkąt(); figury[2] = new Prostokąt(); figury[1].rysuj(); Pytanie: jaka figura się narysuje? która metoda rysuj() się wywoła? class Figura rysuję figurę public void rysuj() Console.WriteLine("rysuję figurę"); 25/41

26/41 Do czego może się to przydać? Dzięki temu możemy traktować w jednakowy sposób wiele obiektów należących do jednej rodziny (hierarchii) określane jest to jako polimorfizm. static void Main(string[] args) Figura[] figury = new Figura[10]; figury[0] = new Koło(); figury[1] = new Trójkąt(); figury[2] = new Prostokąt(); (figury[1] as Trójkąt).rysuj(); // lub: ((Trójkąt)figury[1]).rysuj(); Rzutowanie w dół pozwala dostać się do rzeczywistego obiektu ukrytego w tablicy. rysuję trójkąt

27/41 Do czego może się to przydać? Dzięki temu możemy traktować w jednakowy sposób wiele obiektów należących do jednej rodziny (hierarchii) określane jest to jako polimorfizm. static void Main(string[] args) Figura[] figury = new Figura[10]; figury[0] = new Koło(); figury[1] = new Trójkąt(); figury[2] = new Prostokąt(); Skąd jednak mamy pewność, że to faktycznie trójkąt? Random rnd = new Random(); for (int i = 0; i < figury.length; ++i) switch (rnd.next(3)) case 0: figury[i] = new Koło(); break; case 1: figury[i] = new Trójkąt(); break; case 2: figury[i] = new Prostokąt(); break;

Do czego może się to przydać? Dzięki temu możemy traktować w jednakowy sposób wiele obiektów należących do jednej rodziny (hierarchii) określane jest to jako polimorfizm. static void Main(string[] args) Figura[] figury = new Figura[10]; figury[0] = new Koło(); figury[1] = new Trójkąt(); figury[2] = new Prostokąt(); Skąd jednak mamy pewność, że to faktycznie trójkąt? for (int i = 0; i < figury.length; ++i) Console.WriteLine("Wybierz rodzaj figury:..."); int wybór = int.parse(console.readline()); switch (wybór) case 0: figury[i] = new Koło(); break; case 1: figury[i] = new Trójkąt(); break; case 2: figury[i] = new Prostokąt(); break; 28/41

29/41 Do czego może się to przydać? Dzięki temu możemy traktować w jednakowy sposób wiele obiektów należących do jednej rodziny (hierarchii) określane jest to jako polimorfizm. static void Main(string[] args) Figura[] figury = new Figura[10]; // // wypełnianie tablicy figur... // if (figury[1] is Trójkąt) ((Trójkąt)figury[1]).rysuj(); else if (figury[1] is Koło) ((Koło)figury[1]).rysuj(); else if (figury[1] is Prostokąt) ((Prostokąt)figury[1]).rysuj(); Operator is sprawdza faktyczny typ obiektu w tablicy.

30/41 Do czego może się to przydać? Dzięki temu możemy traktować w jednakowy sposób wiele obiektów należących do jednej rodziny (hierarchii) określane jest to jako polimorfizm. static void Main(string[] args) Figura[] figury = new Figura[10]; // // wypełnianie tablicy figur... Operację możemy wykonać dla // każdego elementu tablicy. foreach (Figura figura in figury) if (figura is Trójkąt) ((Trójkąt)figura).rysuj(); else if (figura is Koło) ((Koło)figura).rysuj(); else if (figura is Prostokąt) ((Prostokąt)figura).rysuj(); Operator is sprawdza faktyczny typ obiektu w tablicy.

31/41 Jeśli oznaczymy metodę jako wirtualną, program sam (automatycznie) będzie dokonywał powyższych sprawdzeń i rzutowań w momencie jej wywołania. class Figura public virtual void rysuj()... class Trójkąt : Figura public override void rysuj()... class Koło : Figura public override void rysuj()... class Prostokąt : Figura public override void rysuj()... Przesłaniając metodę wirtualną dodajemy słowo kluczowe override, wskazujące, że chcemy nadpisać wersję z klasy bazowej

32/41 Jeśli oznaczymy metodę jako wirtualną, program sam (automatycznie) będzie dokonywał powyższych sprawdzeń i rzutowań w momencie jej wywołania. Teraz poniższy kod będzie działał prawidłowo. static void Main(string[] args) Figura[] figury = new Figura[10]; // // wypełnianie tablicy figur... // foreach (Figura figura in figury) figura.rysuj(); Zawsze wywoła się wersja metody rysuj() z odpowiedniej klasy.

Aby dziedziczyć z klasy, programista nie musi znać jej implementacji. class Zbiór public void Dodaj(int wartość) /*... */ public void Usuń(int wartość) /*... */ public bool CzyJest(int wartość) /*... */ class ZbiórParzysty : Zbiór public void Dodaj(int wartość) if (wartość % 2 == 0) base.dodaj(wartość); class Program static void Main(string[] args) ZbiórParzysty zbiór = new ZbiórParzysty(); zbiór.dodaj(4); zbiór.dodaj(5); false zbiór.dodaj(6); Console.WriteLine(zbiór.CzyJest(5)); 33/41

To samo dotyczy kompozycji. class Plik //... public Plik(string nazwa) /*... */ public void Zapisz(string tekst) /*... */ public string Odczytaj() /*... */ public void Zamknij() /*... */ class MaszynaSzyfrująca //... public MaszynaSzyfrująca(int klucz) /*... */ public string Szyfruj(string tekst) /*... */ public string Odszyfruj(string tekst) /*... */ class PlikSzyfrowany : Plik private MaszynaSzyfrująca ms; public PlikSzyfrowany(string nazwa, int klucz) : base(nazwa) ms = new MaszynaSzyfrująca(klucz); 34/41

35/41 To samo dotyczy kompozycji. class PlikSzyfrowany : Plik private MaszynaSzyfrująca ms; public PlikSzyfrowany(string nazwa, int klucz) : base(nazwa) ms = new MaszynaSzyfrująca(klucz); public void Zapisz(string tekst) string zaszyfrowany = ms.szyfruj(tekst); base.zapisz(zaszyfrowany); public string Odczytaj() string zaszyfrowany = base.odczytaj(); string tekst = ms.odszyfruj(zaszyfrowany); return tekst;

class Program static void Main(string[] args) PlikSzyfrowany plik; plik = new PlikSzyfrowany("dane.bin", 1234); plik.zapisz("ala ma kota."); plik.zamknij(); Console.ReadKey(); 36/41

37/41 Jak powiadamiać o błędach? Może wypisać komunikat? class Konto public void wypłać(double kwota) if (kwota <= 0) Console.WriteLine("Błędna kwota"); else if (kwota > suma) Console.WriteLine("Brak środków"); else suma -= kwota; Komunikat to informacja dla użytkownika, ale jak powiadomić programistę, aby mógł zareagować na błąd?

38/41 Jak powiadamiać o błędach? Może wypisać komunikat? class Konto public void wypłać(double kwota)... Komunikat to informacja dla użytkownika, ale jak powiadomić programistę, aby mógł zareagować na błąd? static void Main(string[] args) // wykonywanie przelewu Konto k1 = new Konto(), k2 = new Konto(); double kwota = double.parse(console.readline()); k1.wypłać(kwota); k2.wpłać(kwota); Jeśli był błąd przy wypłacie, nie powinniśmy wpłacać!

Jak powiadamiać o błędach? W programowaniu obiektowym preferowanym rozwiązaniem są wyjątki. class Konto Wystąpienie wyjątku powoduje public void wypłać(double kwota) zakończenie metody. if (kwota <= 0) throw new Exception("Błędna kwota"); if (kwota > suma) throw new Exception("Brak środków"); suma -= kwota; static void Main(string[] args) // wykonywanie przelewu Konto k1 = new Konto(), k2 = new Konto(); double kwota = double.parse(console.readline()); k1.wypłać(kwota); k2.wpłać(kwota); Domyślna reakcja na wystąpienie wyjątku to zakończenie programu (to lepsze niż działanie z błędem). 39/41

Pytanie: Jak lepiej reagować na wyjątek? Odpowiedź: Łapać go. class Konto public void wypłać(double kwota)... static void Main(string[] args) // wykonywanie przelewu Konto k1 = new Konto(), k2 = new Konto(); double kwota = double.parse(console.readline()); try catch k1.wypłać(kwota); k2.wpłać(kwota); Blok objęty kontrolą. Blok łapania wyjątku. Console.WriteLine("Operacja nieudana"); 40/41

Pytanie: Jak lepiej reagować na wyjątek? Odpowiedź: Łapać go. class Konto public void wypłać(double kwota)... static void Main(string[] args) // wykonywanie przelewu Konto k1 = new Konto(), k2 = new Konto(); double kwota = double.parse(console.readline()); try k1.wypłać(kwota); k2.wpłać(kwota); catch(exception ex) W ten sposób możemy uzyskać informację o wyjątku, który wystąpił. Console.WriteLine("Operacja nieudana: "+ ex.message); 41/41