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;.