6 tema. Klasės, metodai, objektai...

 Programa, klasės, objektai
 Pagrindinis pavyzdys
  Klasių iškvietimas
 Klasės aprašymas
 Metodų aprašymas
 Klasės konstruktoriai
 Klasių paketas
 Užduotis

Programa, klasės, objektai

Programos tekstas arba kodas yra tikslus būsimos ,,dirbtuvės", kurioje bus atliekami mums reikalingi darbai, planas. Tame plane numatyta, kokie turi būti įrenginiai, kokios jų savybės, kokius veiksmus jie turi atlikti. Kalbant ,,moksliškai" - kokie turi būti objektai, kokios jų savybės ir kokie jų metodai. Taigi programos tekstas (,,didysis" planas) suskyla į dalis, kuriose aprašomi būsimi objektai ir jų sąveikos. Šie ,,daliniai" planai yra pagrindiniai programos struktūriniai elementai arba klasės. Tai yra tarsi projektinė dokumentacija, pagal kurią galima sukurti daug panašias savybes turinčių veikiančių objektų. Kiekvienas objektas gali atlikti tam tikras funkcijas, kurias vadinsime to objekto metodais.

Iki šiol kūrėme tik tokias programas, kuriose būdavo aprašyta tik viena klasė. Taigi planavome tarsi stacionarias dirbtuves, iš kurių nieko negalima išnešti ir panaudoti kitur. Tačiau realioje dirbtuvėje yra įvairių įrankių ir kitokių daiktų (pavyzdžiui, muzikos grotuvas ar kavinukas), kuriuos galima išnešti ir panaudoti kitoje vietoje. Taigi nuo šiol pradėsime galvoti apie programas, sudarytas iš daugelio objektų, turinčių savo savybes ir metodus. Šie objektai sąveikauja tarpusavyje ir atlieka visus tuos darbus, kurie buvo numatyti planuojant programą (dirbtuvę). Be to išmoksime vienai programai sukurtas klases panaudoti kitose programose.

Pagrindinis pavyzdys: programa su keliomis klasėmis

Šio skyrelio pavyzdys parodo klasių ir jų metodų aprašymo sintaksę, o taip pat naudojimosi klasių metodais būdus. Reiktų ji gerai išnagrinėti: komentarai pateikti po programos tekstu. Be to - per pratybas paklausinėkite apie programos eilučių prasmę dėstytojo!
import java.awt.*;                    //1
import java.awt.event.*;
import java.applet.*;
import java.util.StringTokenizer;     //4

class Braizymas extends Canvas{       //5

Color spalva;                         //6
int x0,y0;                            //7

Braizymas(){                          //8
spalva=Color.black;	
x0=0; y0=0;}                          //10
	
Braizymas(Color sp){                  //11
spalva=sp;	
x0=0; y0=0;}

Braizymas(Color sp, int x, int y){
spalva=sp;	
x0=x; y0=y;}                          //16

public void apskritimas(int i,int j){ //17
Graphics g=getGraphics();
g.setColor(spalva);
g.translate(x0,y0);
g.drawOval(i,j,50,50);	}}            //21


class Aritmetika{                     //22

int n;                                //23

Aritmetika(){n=10;}                   //24
	
Aritmetika(int m){n=m;}               //25

public int sandauga(int i, int j){    //26
return ((i*j)%n);}                    //27

public int suma(int i, int j){        //28
return ((i+j)%n);}}                   //29


public class Kelios_klases            //30
extends Applet
implements ActionListener{            //32

Button mbr, msk1, msk2;               //33
TextField t;                          //34
Aritmetika a10, a5;                   //35
Braizymas br;                         //36

public void init() {                  //37
setLayout(new BorderLayout());
mbr= new Button("brezti");
mbr.addActionListener(this);
add("North",mbr);
msk1= new Button("skaiciuoti mod 10");
msk1.addActionListener(this);
add("East",msk1);
msk2= new Button("skaiciuoti mod 5");
msk2.addActionListener(this);
add("West",msk2);
t= new TextField();
add("South",t);                       //49

a10= new Aritmetika();                //50
a5= new Aritmetika(5);                //51

br= new Braizymas();                  //52
add("Center", br);}


public void                           //53
actionPerformed(ActionEvent u){
int a, b;	

if (u.getSource()==mbr){
try{StringTokenizer str=
new StringTokenizer(t.getText());
br.apskritimas(Integer.parseInt(str.nextToken()),
Integer.parseInt(str.nextToken()));	}
catch (Exception e){
t.setText("Ivedimo klaidos!!!");	
}}

if (u.getSource()==msk1){
try{StringTokenizer str=
new StringTokenizer(t.getText());
a=Integer.parseInt(str.nextToken());
b=Integer.parseInt(str.nextToken());
t.setText("Skaičių "+a+ " ir 
"+b+" suma moduliu "+10+" lygi "+
a10.suma(a,b)+" o sandauga "+           //70

a10.sandauga(a,b));}
catch (Exception e){
t.setText("Ivedimo klaidos!!!");	
}}

if (u.getSource()==msk2){
try{StringTokenizer str=
new StringTokenizer(t.getText());
a=Integer.parseInt(str.nextToken());
b=Integer.parseInt(str.nextToken());
t.setText("Skaičių "+a+ " ir 
"+b+" suma moduliu "+5+" lygi "+
a5.suma(a,b)+" o sandauga "+a5.sandauga(a,b));}
catch (Exception e){
t.setText("Ivedimo klaidos!!!");	
}}
}}


Pažiūrėkite, kaip veikia.

   Į pradžią   

Klasių iškvietimas

1-4 eilutės. Šios eilutės nurodo, kokios papildomos klasės iš Java klasių rinkinių (paketų) reikalingos mūsų programai. Jeigu eilutė baigiasi žvaigždute - įkeliamas visas paketas. Atkreipkime dėmesį, kad ketvirtoji eilutė nurodo, kad iš viso paketo naudosime tik vieną klasę StringTokenizer.

Klasės aprašymas

5 eilutė. Šioje eilutėje prasideda klasės Braizymas aprašymas. Bendra klasės antraštės sintaksė tokia:
[modifikatoriai] class klasės_vardas
                 [extends superklasė]
                 [implements metodų_rinkinio_vardas]

Laužtiniuose skliaustuose nurodytų parametrų gali nebūti. Jeigu modifikatorių nėra (kaip mūsų pavyzdyje), tai ši klasė bus prieinama tik to paties failo klasėms. Jeigu reikia, kad klasė būtų prieinama kitoms to paties paketo klasėms, o taip pat ir klasėms nesančioms šiame pakete, reikia nurodyti modifikatorių public. Tačiau tame pačiame faile gali būti tik viena klasė su šiuo modifikatoriumi ir pats failas turi vadintis tuo pačiu vardu kaip ir ši klasė. Vadinasi, jeigu reiktų, kad klase Braizymas galėtų naudotis ne tik šio failo klasės, turėtume išsaugoti šią klasė atskirame faile ir nurodyti modifikatorių public.
Po žodžio extends, nurodoma superklasės, t.y., klasės, kurios savybes paveldi mūsų klasė vardas. Mūsų klasė yra klasės Canvas savybių paveldėtoja. Galima įsivaizduoti, kad Canvas yra tiesiog piešimo lenta.
Jeigu norime, kad mūsų objektai reaguotų į įvykius, klasės antraštėje nurodome implements ActionListener. Tai reiškia, kad klasėje bus naudojamas tam tikras reagavimo į įvykius metodų rinkinys (interface). Panašių metodų rinkinių (interfeisų) yra ir daugiau.

6-7 eilutėse nurodoma, kokie duomenys bus naudojami mūsų klasėje. Aprašant duomenis, nurodomas jų tipas, o taip pat gali būti nurodyti tam tikri naudojimo specifikatoriai. Jie yra tokie patys kaip ir metodams, žr. kitą skyrelį.

   Į pradžią   

Metodų aprašymas

8-10, 17-21, 26-27 ir kitos eilutės. Visiems numatytiems klasės veiksmams reikia sukurti metodus. Metodų aprašymo bendroji sintaksė tokia:
           [naudojimo specifikatorius]
           [static] [abstract] [final] [native] [synchronized]
           duomenų_tipas metodo_vardas
           ([parametrai], [parametrai]...)
           [throws išimčių_sąrašas]
Naudojimo specifikatoriai nurodo, iš kur galima išsikviesti metodą. Specifikatoriai ir apribojimai, kuriuos jie nustato nurodyti lentelėje.
Metodo su nurodytu specifikatoriumi iškvietimas
Specifikatorius Iš klasės Iš dukterinės klasėsIš paketo
publicgalimasgalimasgalimas
privategalimasnegalimasnegalimas
protectedgalimasgalimasgalimas
nėragalimas negalimasgalimas
Paprastai norėdami naudotis kokiu nors klasėje aprašytu metodu turime sukurti tos klasės objektą ir tada kreiptis į to objekto metodą. Pavyzdžiui, 28-29 programos eilutėse aprašytas klasės Aritmetika metodas suma(), 50-51 eilutėse sukuriami du šios klasės objektai ir vėliau kreipiamasi į jų metodus, pavyzdžiui, 70 eilutėje. Tačiau jeigu metodą apibrėšime su static specifikatoriumi, atsiras galimybė metodą išsikviesti nesukūrus tos klasės objekto. Sakoma, kad metodai su specifikatoriumi yra klasės metodai. Galima, pavyzdžiui, į vieną klasę ,,sudėti" kelis dažnai naudojamus įrankius, t.y. metodus su specifikatoriumi static ir, kai reikia, iškviesti juos iš bet kurios paketo klasės.
Metodas, atlikęs darbą, gali perduoti rezultatą, kuris gali būti vieno iš pagrindinių tipų duomuo arba bet kurios klasės objektas. Perduodamų duomenų tipą reikia būtinai nurodyti prieš metodo vardą. Pavyzdžiui, jeigu metodo darbo rezultas yra spalva, tai jo aprašymas gali atrodyti taip:
public Color metodas(){
Color spalva;
...operacijos, sukuriančios kintamąjį spalva...
return spalva;
} 
Jeigu metodas neperduoda jokių duomenų, tai vietoje duomenų tipo rašome void .
Iškviečiant metodą jam gali būti perduodamos parametrų reikšmės. Pavyzdžiui, jeigu mūsų metodas, kurtų spalvą naudodamas perduodamą jam int tipo kintamojo reikšmę, tai jį aprašytume taip:
public Color metodas(int param){
Color spalva;
...operacijos, sukuriančios kintamąjį spalva...
return spalva;
} 

   Į pradžią   

Klasės konstruktoriai

8-16 eilutės Objekto sukūrimas pagal klasės aprašymą - svarbus veiksmas. Jam irgi reikalingas metodas. Metodai, kurie sukuria objektus pagal jų aprašymą vadinami konstruktoriais. Klasės konstruktoriaus vardas turi sutapti su klasės vardu. Jau ne kartą naudojomės konstruktoriais. Pavyzdžiui, eilutės
...
Button mygt=new Button();
Button mygt1=new Button("Kitas mygtukas");
...
iškviečia klasės Button konstruktorius, kad jie sukurtų du mygtukų klasės objektus. Jau ir šis pavyzdys rodo, kad klasė gali turėti ne vieną konstruktorių. Iš tiesų - natūralu, kad tos pačios klasės objektus galime kurti įvairiai: kartais nurodome visus parametrus, kartais paliekame standartines dalies parametrų reikšmes ir pan. Klasėje Braizymas numatyti net trys konstruktoriai, o klasėje Aritmetika - du. 50-51 eilutėse sukuriami du klasės Aritmetika objektai, pasinaudojant dviem skirtingais konstruktoriais. Tačiau jeigu klasės aprašyme nenurodome, kokie turi būti klasės konstruktoriai, tai kompiliuojant Java naudojasi ,,numatytuoju" konstruktoriumi ir vis tiek sukuria objektus. Pavyzdžiui, trečiosios klasės Kelios_klasės kode konstruktorius neaprašytas, tačiau joje yra metodas init(), kurio pakanka objektui sukurti.
Klases galime kurti ,,nuo pradžios", tačiau galime pasinaudoti jau mūsų pačių ar kitų žmonių sukurtomis klasėmis pritaikydami jas mūsų reikmėms. Tada naujoji klasė paveldi visas ,,motininės" klasės savybes ir metodus, bei mūsų valia įgyja naujų. Galime naujajai klasei aprašyti naujus konstruktorius, tačiau galime pasinaudoti ir ,,motininės" klasės konstruktoriumi. Panagrinėkime tokį programos fragmentą:
public class Mano_klasė extends Draugo_klasė{
Mano_klasė(){
super();
}
....
}
Klasėje aprašytas keistas konstruktorius - jis sudarytas iš vieno žodelio super(). Šis žodelis reiškia, kad iškviečiamas superklasės (t.y. klasės Draugo_klasė) konstruktorius.

   Į pradžią   

Klasių paketas

O dabar ,,išardykime" savo programą: trijų klasių kodus išsaugokime atskiruose failuose, be to nurodykime, kad pirmosios dvi jas sukompiliavus būtų patalpintos į klasių paketą mano_irankiai. Klasė Braizymas
package mano_irankiai;
import java.awt.*;                    
     
public class Braizymas extends Canvas{       

Color spalva;                         
int x0,y0;                            

public Braizymas(){                          
spalva=Color.black;	
x0=0; y0=0;}                          
	
public Braizymas(Color sp){                  
spalva=sp;	
x0=0; y0=0;}

public Braizymas(Color sp, int x, int y){
spalva=sp;	
x0=x; y0=y;}                          

public void apskritimas(int i,int j)
Graphics g=getGraphics();
g.setColor(spalva);
g.translate(x0,y0);
g.drawOval(i,j,50,50);	}}    
Klasė Aritmetika
package mano_irankiai;
public class Aritmetika{                     

int n;                                

public Aritmetika(){n=10;}                   
	
public Aritmetika(int m){n=m;}               

public int sandauga(int i, int j){    
return ((i*j)%n);}                    

public int suma(int i, int j){        
return ((i+j)%n);}}   
Klasė Kelios_klases
import java.awt.*;                    
import java.awt.event.*;
import java.applet.*;
import java.util.StringTokenizer;
import mano_irankiai.*;

public class Kelios_klases            
extends Applet
implements ActionListener{            

Button mbr, msk1, msk2;               
TextField t;                          
Aritmetika a10, a5;                   
Braizymas br;                         

public void init() {                  
setLayout(new BorderLayout());
mbr= new Button("brezti");
mbr.addActionListener(this);
add("North",mbr);
msk1= new Button("skaiciuoti mod 10");
msk1.addActionListener(this);
add("East",msk1);
msk2= new Button("skaiciuoti mod 5");
msk2.addActionListener(this);
add("West",msk2);
t= new TextField();
add("South",t);                       

a10= new Aritmetika();                
a5= new Aritmetika(5);                

br= new Braizymas();                  
add("Center", br);}


public void                           
actionPerformed(ActionEvent u){
int a, b;	

if (u.getSource()==mbr){
try{StringTokenizer str=
new StringTokenizer(t.getText());
br.apskritimas(Integer.parseInt(str.nextToken()),
Integer.parseInt(str.nextToken()));	}
catch (Exception e){
t.setText("Ivedimo klaidos!!!");	
}}

if (u.getSource()==msk1){
try{StringTokenizer str=
new StringTokenizer(t.getText());
a=Integer.parseInt(str.nextToken());
b=Integer.parseInt(str.nextToken());
t.setText("Skaičių "+a+ " ir 
"+b+" suma moduliu "+10+" lygi "+
a10.suma(a,b)+" o sandauga "+           

a10.sandauga(a,b));}
catch (Exception e){
t.setText("Ivedimo klaidos!!!");	
}}

if (u.getSource()==msk2){
try{StringTokenizer str=
new StringTokenizer(t.getText());
a=Integer.parseInt(str.nextToken());
b=Integer.parseInt(str.nextToken());
t.setText("Skaičių "+a+ " ir 
"+b+" suma moduliu "+5+" lygi "+
a5.suma(a,b)+" o sandauga "+a5.sandauga(a,b));}
catch (Exception e){
t.setText("Ivedimo klaidos!!!");	
}}
}}
Patarimas. Kompiliuokite failus Braizymas.java ir Aritmetika.java įvedę tokias komandas:
javac -d . Braizymas.java ir  javac -d . Aritmetika.java
Turėtų atsirasti aplankas mano_irankiai, kuriame bus dvi sukompiliuotos klasės.

   Į pradžią   

Dabar atskiru failu išsaugokime ir sukompiliuokime programos pagrindinės klasės kodą. Sukompiliuota klasė turi būti aplanko mano_irankiai išorėje. Išorėje turi būti ir html failas, reikalingas įskiepiui paleisti.

Užduotis

  1. Atsisiųskite 6 užduoties klasių failus Braizymas.java ir Aritmetika.java, sukompiliuokite jas sudarydami klasių paketą.
  2. Sukurkite dvi naujas klases, kurios paveldi turimų klasių savybes. Klasę Braižymas papildykite tuo metodu, kurį sukūrėte atlikdami 3 užduotį, o klasę Aritmetika - 2 užduotyje sukurtu metodu (arba kokiu nors nauju metodu).
  3. Sukurkite naują klasę, kuri aprašytų vieną iš šiame puslapyje išvardytų objektų ir ją sukompiliuokite taip, kad ji atsidurtų jūsų pakete.
  4. Parašykite pagrindinę klasę, kuri išsikviestų visas tris paketo klases ir su jomis ,,dirbtų".

         Į pradžią