 
Wstęp
do programowania
Wykład 9 – klasy, moduły
 
Moduły
Napisane funkcje lub procedury przez np.. Użytkownika mogą być połączone
w jeden moduł, z którego można korzystać w wielu aplikacjach.
Reguły tworzenia modułów
•
Nazwa pliku, w którym znajduje się moduł powinna być taka sama jak
nazwa modułu.
• Moduł składa się z części opisowej, implementacyjnej i inicjującej. Część
inicjująca musi się kończyć kropką.
• Stosowanie modułów powoduje, że właściwe programy są znacznie
krótsze, bardziej przejrzyste i czytelne.
•
Dzięki temu, że moduły przechowywane są w postaci skompilowanej w
trakcie kompilacji programu definicje zawarte w modułach są
do programu wynikowego dołączane a zatem kompilacja programu
przebiega szybciej. (rozszerzenie .pas w delphi)
 
Moduły
Fragment modułu umieszczony pomiędzy słowami interface i
implementation jest częścią publiczną, a pomiędzy słowami
implementation oraz end . jest tzw. częścią prywatną modułu,
W programach, w których zadeklarowano chęć korzystania z modułu
dostępne są tylko definicje umieszczone w części publicznej;
żaden typ, zmienna lub stała umieszczona w części prywatnej nie
jest dostępna w programie.
•
Wszystkie definicje funkcji i procedur, niezależnie od tego czy mają
być dostępne w programie czy nie muszą być umieszczone
w części prywatnej. Procedura lub funkcja staje się publiczna gdy jej
nagłówek zostanie umieszczony w części publicznej modułu.
 
Moduły
Liczba modułów, z których może składać się program jest praktycznie
nieograniczona.
• Jeśli jeden moduł korzysta z innego to istotna jest kolejność nazw na
liście deklarowanych modułów. Moduł wykorzystywany powinien
znajdować się przed wykorzystującym.
•
Nazwy występujące w programie są nadrzędne w stosunku do tych
występujących w modułach. Przesłonięte identyfikatory z modułu
są dostępne w programie jeśli są poprzedzone nazwą modułu i
kropką.
 
Moduły
Unit Unit1
Interface
Implementation
End.
Część
pubiczna
Część
prywatna
Dołączanie modułów w programie za
pomocą słowa kluczowego uses
program modul_dpr;
uses
SysUtils, System
Unit1 in 'Unit1.pas';
 
Moduły -
użyj aplikacji
units
unit modul1;
interface
const n = 2;  Type Tab=array[1..N,1..N] of 
Integer;
procedure gener(var T:Tab );
procedure wypisz( T:Tab );
Implementation
procedure gener( var T:Tab);
var i,j:byte;
Begin for i:=1 to N do
for J:=1 to N do T[i,j]:=random(10);
end;
procedure wypisz(T: Tab );
var i,j:byte;
Begin
for i:=1 to N do
for j:=1 to N do
if j< N then write (T[i,j]:4,' ') else writeln
(T[i,j]:4)
end; end.
Program pr_modul1;
uses
SysUtils,
modul in 'modul1.pas';
var a: Tab;
Begin
gener(A );
wypisz(A);
readln;
end.
 
Moduły
Projekt w Lazarusie składać się może formularzy, modułów.
Projekt w Delphi składa się z plików:
 plik główny projektu (lpr)
plik zawierający informacje o formularzach i modułach aplikacji zawiera
kod inicjujący
 pliki modułów (pas) - kody źródłowe modułów
 pliki formularzowe (lfm)
 plik zasobów (lrs)
 plik informacyjny (lpi)
 
Klasy
Klasa jest złożoną strukturą danych rozbudowaną o funkcje składowe. 
Obiektem nazywamy konkretny egzemplarz danej klasy. 
W skład klasy wchodzą: dane (zmienne) składowe, funkcje składowe 
(metody), w tym konstruktory i destruktory. 
Klasę deklaruje się przy użyciu słowa kluczowego class, np: 
type Tnazwa_Klasy=class … end;  
W dobrym stylu jest nadawanie klasie nazwy z dużej litery T. 
Elementy klasy są podzielone na sekcje: publiczną i prywatną, 
chronioną. 
Elementy te mogą być deklarowane w dowolnej liczbie występujących 
po sobie sekcji wydzielonych przez etykiety public lub private 
Elementy klasy są domyślnie prywatne. Metod i zmiennych publicznych 
klasy można używać wszędzie w programie, natomiast do metod i
zmiennych prywatnych dostęp mają tylko inne metody klasy.
Klasa powinna być abstrakcyjnym typem danych, czyli takim, który raz 
zaprojektowany może być używany przez innych programistów bez
konieczności wgłębiania się w jego mechanizm.
 
Klasy
Sekcja publiczna deklaracji klasy nazywana jest interfejsem klasy. zawarte
w niej metody wraz opisami ich parametrów, działanie i format wyniku
powinny dawać programiście minimum informacji na temat klasy 
Według  zasady abstrakcyjności danych, wszystkie dane składowe klasy 
powinny znajdować się w sekcji prywatnej. 
W sekcji publicznej należy umieszczać metody operujące na danych 
prywatnych.
Jeśli metoda publiczna wykonuje wiele obliczeń lub pewne z nich 
wykonywane są przez wiele metod publicznych, to można je wyodrębnić w
postaci osobnej metody prywatnej. Są one wtedy wyłącznie na użytek
implementacji klasy. 
Implementacja klasy powinna być zaprojektowana przez programistę w 
sposób, który daje mu możliwość rozbudowania i udoskonalania działania
funkcji jej składowych, bez wprowadzania jakichkolwiek zmian w interfejsie.
Dostęp do danych i funkcji składowych obiektu uzyskujemy przez użycie 
operatora dostępu: ‘.’,
 
Klasy
Klasa – jest wzorcem czyli typem dla swoich zmiennych, czyli
obiektów
Obiekt – jest zmienną swojej klasy
Programowanie obiektowe - programowanie, w którym klasy
stanowią najważniejszą część w konstrukcji programu.
Podstawowe własności programowania obiektowego:
- dziedziczenie
- hermetyzacja
- polimorfizm
- rozszerzalność
 
Klasy
Dziedziczenie – jest własnością umożliwiającą klasie pochodnej uzyskanie
pól i metod swoich klas rodzicielskich,
• Jest możliwością tworzenia klas jako potomnych od klas rodzicielskich.
• Klasy potomne dziedziczą charakterystyki i działania klasy rodzic.
• Klasy pochodne – definiowane własności i operacje oraz mogą zmieniać
operacje odziedziczone.
Dziedziczenie
Budowa jednej klasy na bazie drugiej, przez dodawanie/przesłanianie jej
składowych:
 
Klasy
Hermetyzacja - własność, która pozwala na łączenie danych z metodami w
obrębie obiektu; zwana inaczej Enkapsulacją.
Polimorfizm - własność dzielenia pojedynczego działania i nazwy działania
poprzez   hierarchię obiektową w sposób właściwy dla każdego obiektu w 
tej hierarchii.
Polimorfizm – pozwala każdej klasie na posiadanie własnych potrzeb, 
metody te zapewniają jednolitą odpowiedź na komunikaty dochodzące do 
żądanych klas w hierarchii, umożliwia obiektom generowania własnych 
odpowiedzi na podobne komunikaty.
Rozszerzalność - własność pozwalająca rozszerzać i uaktualniać moduły już
skompilowane
 
Klasy
Sekcje klasy
public (publiczne) – definiuje pola i metody, które są dostępne z dowolnego 
miejsca programu oraz z modułu, w którym zostały zdefiniowane
private (prywatne) – definiuje pola i metody klasy, które są niedostępne spoza 
modułu (pliku kodu źródłowego), w którym zdefiniowano klasę
protected (chronione) – definiuje pola i metody klasy, które są widoczne tylko 
dla danej klasy i jej klas pochodnych (wykorzystywane w dziedziczeniu)
type
TFigura = class
private
bok: byte;
podstawa: 1..100;
procedure wypisz;
protected
kat: integer;
ile_pr: 0..2;
function pole(a,b:byte): Integer;
public
nazwa :string
procedure init;
procedure free;
end;
sekcja prywatna
sekcja chroniona
sekcja publiczna
 
program PR_KONSTR1;
type
TProstokat = class
a, b :Integer;         //wymiary prostokata
function obwod :Integer;
function pole:Integer;
end;
function TProstokat.obwod:Integer;
begin Result := (a+b)*2; end;
function TProstokat.pole:Integer;
begin Result := a*b; end;
Var   Pro1, Pro2: TProstokat;
Begin
Pro1:= Tprostokat.Create;
Pro1.a := 4; Pro1.b := 2;
// pro2.a:=10; pro2.b:=20; // bład! -Brak create
writeln('obwod= ',Pro1.obwod);
writeln('Pole = ',Pro1.pole);
//writeln('Pole 2= ',Pro2.pole);
Pro1.Free;
readln; end.
Klas – to pola i metody –
przykład cd. W1.15XII
 
program PrKONSTR2;
type
TProstokat = class
a, b :Integer;        //wymiary prostok
function obwod :Integer;
function pole:Integer;
end;
function TProstokat.obwod:Integer;
begin Result := (a+b)*2; end;
function TProstokat.pole:Integer;
begin Result := a*b; end;
type
Trojkat = class
a, b,c :Integer;        //wymiary 
function obwod :Integer;
function pole:Integer;
end;
function Trojkat.obwod:Integer;
begin Result := (a+b+c); end;
function Trojkat.pole:Integer;
begin Result := a*(b+c) div 2; end;
Var Pro1 :TProstokat;
Klas – to pola i metody -
przykład
Var Pro1 :TProstokat;
tro1:Trojkat;
Pro1:=TProstokat.Create;
//obowiazkowe
Pro1.a := 5;
Pro1.b := 7;
writeln('obwod pr= ',Pro1.obwod);
writeln('Pole pr= ',Pro1.pole);
readln;
Tro1:=Trojkat.Create;
tro1.a := 2;
tro1.b := 3;
tro1.c := 4;
writeln('obwod tr= ',tro1.obwod);
writeln('Pole  tr= ',tro1.pole);
Pro1.Free; //obowiazkowe
Tro1.Free; //obowiazkowe
readln; end.
 
program PrKonstr3;
type
TProstokat = class
a :Integer;        //wymiary prostok
procedure ustaw(_d:integer);
function wypisz:integer;
private
d: integer;
protected
b: integer;
public
c:integer;
end;
procedure TProstokat.ustaw(_d:integer);
begin
d:=_d;
end;
function TProstokat.wypisz:integer;
begin
Result:=d;
end;
Var Pro1 :TProstokat;
Klasa – dostęp pól klasy
Var   Pro1 :TProstokat;
begin
Pro1:=Tprostokat.Create;
Pro1.a := 4;    Pro1.b := 2;
Pro1.c := 50;
//Pro1.d := 1; //w module mozna
writeln('a= ',Pro1.a);
writeln('b = ',Pro1.b);
writeln('c = ',Pro1.c);
Pro1.ustaw(100);
writeln('d=',Pro1.Wypisz);
readln;
Pro1.Free
end.
 
Klasy –
konstruktor, destruktor
konstruktor  Create tworzy obiekt (przydziela wymaganą 
pamięć)
destruktor Free zwalnia przydzieloną pamięć
klasa może zawierać więcej niż jeden konstruktor, a powinna 
zawierać jeden destruktor
konstruktor powinien być wywołany jako pierwsza metoda dla 
nowego obiektu
wywołaniu destruktora kończy pracę z obiektem, aby 
ponownie korzystać z obiektu należy wywołać konstruktor
 
Klasy –
konstruktor, destruktor
Użycie konstruktora Create jest obowiązkowe dla każdego
egzemplarza klasy (przydziela wymaganą pamięć)
Np.. TABC=class..
var ob1 : TABC
ob1:=TABC.Create;
Użycie destruktor Free jest obowiązkowe dla każdego
Egzemplarza klasy (zwalnia przydzieloną pamięć)
Np.. ob1.Free;
 
Klasy –
konstruktor, destruktor
program Pr_Constructor4;
Type TProst=class
x,y: integer ;
a,b :integer; {bok}
constructor Create;
destructor Free;
function pole:longint;
end;
constructor TProst.Create;
begin Inherited Create;
a:=20; b:=4; end;
destructor Tprost.Free;
begin Inherited Free; {koniec pracy z TKwadrat} end;
function TProst.pole:longint;
begin Result:= a * b; end;
var Pkat :TProst;
BEGIN
Pkat:=Tprost.Create;
writeln('Pole prostokata: ', Pkat.pole);
Pkat.a:=100;
writeln('Pole prostokata: ', Pkat.pole);
Pkat.Free;
readln; END.
 
Klasy –
konstruktor, destruktor
program pr_konstruktor5; {constructor i destructor}
Type TProst=class
a,b :integer; {bok}
constructor Create(_a,_b :integer);
destructor Destroy;
function pole:longint;
end;
constructor TProst.Create(_a, _b:Integer);
begin Inherited Create;  //obowiazowe
a:=_a;
b:=_b;
writeln('Konstruktor TProst');      end;
destructor TProst.Destroy;
begin
writeln('Destruktor - Koniec pracy z TProst');
Inherited Destroy; end;
function TProst.pole:longint;
begin pole:= a * b; end;
var P1 ,p2:TProst;
BEGIN
P1:= Tprost.Create(20,?);
p2:= Create(4,7);
writeln('  Pole prostokata : ', P1.pole);
P1.Destroy;    //Pkat.Free;
p2.Destroy;
readln; END.
 
Klasy –
konstruktor, destruktor
procedure TFig.wypisz;
Begin    writeln( 'bok = ', bok^); 
end;
function Tfig.pole: Integer;
begin
Result:=bok^*bok^;
end;
var Kwadrat: TFig;
begin
Kwadrat := TFig.Create( 5 );
Kwadrat.wypisz;
Writeln(Kwadrat.pole)
Kwadrat.Destroy;
end.
program PrKonstr6
uses SysUtils;
type
TFig = class
bok: ^byte;
constructor  Create(x:byte); overload;
constructor  Create; overload;
destructor Free;
procedure wypisz;
function pole: Integer;
end;
constructor TFig.Create;
begin    New( bok ); end;
constructor TFig.Create( x:Byte );
begin
Create;
bok^ := x;
end;
destructor TFig.Free;
begin
Dispose( bok );
end;
procedure TFig.wypisz;
 
Typy konstruktorów
Program konstruktory;
{}
type
TPot = class
private
x, y: Integer;
public
constructor Create; overload;
//domyślny
constructor Create( dx, dy: Integer );
overload;
//zwykły
constructor Create( const dxy: TPot );
overload;
//kopiujący
end;
Jeżeli nie zdefiniujemy żadnego 
konstruktora, kompilator wykorzysta 
konstruktor klasy TObject
-wyróżniamy trzy rodzaje 
konstruktorów:
a) domyślny (bez parametrów)
b) zwykły (z parametrami, może być 
wiele takich konstruktorów)
c) kopiujący
Instrukcja przypisania  tylko nazwę i 
adres obiektu. 
Jeśli zadeklarujemy jakikolwiek
konstruktor pobierający parametry,
musimy także zadeklarować
konstruktor domyślny
(bezparametrowy).
Przy definicji konstruktora
domyślnego pożądane jest
inicjalizowanie danych.
 
Klasy –
konstruktory
Program PrKonstr7;
type
TPot = class
private
x, y: Integer;
public
constructor Create; overload;
constructor Create( dx, dy: Integer ); 
overload;
constructor Create( const DK: TPot );
overload;
end;
constructor TPot.Create;
Begin inherited Create;
x := 1; y := 0; end;
constructor TPot.Create(dx, dy: Integer);
Begin inherited Create;
x := dx; y := dy; end;
constructor TPot.Create(const DK: TPot);
Begin inherited Create;
x := DK.x; y := DK.y; end;
var a, b, c, d : TPot;
begin
a := TPot.Create;
b := TPot.Create( 7,13 );
c := TPot.Create( b );
//d := TPot.Create;
d:=b; //od wskaźnika 
writeln(' a: ',a.x,' ',a.y);
writeln(' b: ',b.x,' ',b.y);
writeln(' c ',c.x,' ‘,c.y);
writeln(' d ',d.x,' ',d.y);
a.Free;
b.Free;
c.Free;
d.Free;  //ten sam  co b bo d=b
Readln
end;.