Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys

8.6.7 Luokkamuuttujat ja suhde lokaaleihin muuttujiin

Muuttujat voidaan esitellä myös luokan kaikissa metodeissa näkyväksi. Mikäli muuttujat esitellään kaikkien ohjelman aliohjelmalausesulkujen ulkopuolella, näkyvät muuttujat koko luokan alueella. Jos muuttujat vielä varustetaan vaikkapa public määreellä, niin luokan ulkopuolisetkin luokat voivat niitä käyttää. Tällaista on syytä välttää. Seuraava ohjelma on kaikkea muuta kuin hyvän ohjelmointitavan mukainen, mutta pöytätestaamme sen siitä huolimatta:

java-muut\Alisotku.java - parametrin välitystä

	/**
	 * Mitä ohjelma tulostaa?? 
	 * @author  Vesa Lappalainen
	 * @version 1.0, 19.01.2003
	 */
	public class Alisotku {
	     
	  /**
	   * Palauttaa merkkijonon kokonaislukuna
	   * @param s muutettava merkkijono
	   * @return merkkijonosta saatu kokonaisluku
	   */  
	  private static int i(StringBuffer s) {
	    return Integer.parseInt(s.toString());
	  } 
	
	  /**
	   * Sijoittaa kokonaisluvun arvon merkkijonoon
	   * @param s merkkijono johon tulos sijoitetaan
	   * @param i kokonaisluku joka sijoitetaan
	   */
	  private static void set(StringBuffer s,int i) {
	    s.delete(0, s.length()).append(""+i);
	  }
	         
	/* 01 */ static int a; static StringBuffer b; static int c;
	/* 02 */
	/* 03 */ private static void ali_1(StringBuffer a, int b)
	/* 04 */ {
	/* 05 */   int d;
	/* 06 */   d  = i(a);
	/* 07 */   c  = b + 3;
	/* 08 */   b  = d - 1;
	/* 09 */   a.append(""+(c - 5));
	/* 10 */ }
	/* 11 */
	/* 11 */ static private void ali_2(StringBuffer a, StringBuffer b)
	/* 13 */ {
	/* 14 */   int c;
	/* 15 */   c  = i(a) + i(b);
	/* 16 */   set(a,9 - c);
	/* 17 */   set(b,32);
	/* 18 */ }
	/* 19 */
	/* 20 */ public static void main(String[] args) {
	/* 21 */   StringBuffer d = new StringBuffer(); b = new StringBuffer();
	/* 22 */   a=1; set(b,2); c=3; set(d,4);
	/* 23 */   ali_1(d,c);
	/* 24 */   ali_2(b,d);
	/* 25 */   ali_1(d,3+i(d));
	/* 26 */   System.out.println("" + a + " " + b + " " + c + " " + d);
	/* 27 */ }
	}

Käsittelemme (huonosti nimettyjä) metodeja i ja set "operaattoreina", eli oletamme niiden toiminnan tunnetuksi, eikä pöytätestissä askelleta niihin sisälle.

Pöytätestin tekeminen aloitetaan piirtämällä sarakkeet kutakin isompaa ohjelmassa olevaa kokonaisuutta varten. Esimerkissä näitä ovat

Sitten kukin sarake jaetaan vielä osiin siinä olevien muuttujien määrän mukaan. Kekoa varten tarvitaan karkeasti yhtä monta saraketta kuin ohjelmassa on suoritettavia new-operaattoreita (tai String a = "kissa"; tyyppisiä lauseita) .

Lyhyyden vuoksi olemme seuraavassa merkinneet N1 = ensimmäinen new:llä luotu olio ja N2 on toinen. Lisäksi on otettu c-mäinen merkintä &N1, eli viite olioon N1. Merkintä L.c tarkoittaa seuraavassa luokan c -muuttuja (jos on vaara sekaantua muuhun). Merkintää := on käytettä välilaskutoimituksissa erottamaan sijoitusta = -merkistä. Merkintä * muuttujien yläpuolella on muistutuksena sitä, että kyseessä on viitemuuttujat ja niiden käsittely muuttaa aina jotakin muuta muistipaikkaa. Pöytätestissä siis sarakkeet ovat muistipaikkoja ja rivit muistipaikkojen arvo tiettynä ajanhetkenä. Muistipaikka on merkitty harmaalla jos se ei ole voimassa tiettynä ajanhetkenä.


luokan
main
ali_1
ali_2
keko
apulaskut
           
   
*   
   
    
*   
   
   
*   
*   
   
SB
SB

   lause  
a
b
c
d
a
b
d
a
b
c
N1
N2

01 int a;
 0
null
 0
 









21 d = new

 &N2

&N1






""
""
syntyy tyhjät merkkijonot
22 a=1; b=2
 1 
 o-> 
 3 
o-> 
    
   
   
    
    
   
"4"
"2"

23 ali_1(d,c
   
   
   
    
&N1
 3 
  
    
    
   


ali_1(&N1,c)
05 int d






 ?






06 d = i(a); 
   
   
   
    
    
   
 4 
    
    
   


d:=i(N1)=4
07 c = b+3;
   
   
 6 
    
    
   
   
    
    
   


L.c:= 3+3 = 6
08 b = d-1;
   
   
   
    
    
 3 
   
    
    
   


b:= 4-1 = 3
09 a.ap(c-5)
   
   
   
   
o->
   
   
    
    
   
"41"

L.c-5=1; N1:="4"+"1"="41"
24 ali_2(b,d
   
   
   
    
    
   
   
&N2
&N1



ali_2(&N2,&N1)
14 int c;









 ?



15 c=i(a)+i(
   
   
   
    
    
   
   
    
    
43 


c:=41+2 = 43
16 set(a,9-c
   
  
   
    
    
   
   
o->
    
   

"-34"
N2:=9-c=-34;  
17 set(b,32) 
 
   
   
    
    
   
   
    
o->
   
"32"


25 ali_1(d,3
   
   
   
    
&N1
35 
  
    
    
   


ali_1(&N1,3+32)
06 d = i(a) 
   
   
   
    
    
   
32 
    
    
   


d:=i(N1)=32
07 c = b+3;
   
   
38 
    
    
   
   
    
    
   


L.c:= 35+3 = 38
08 b = d-1;
   
   
   
    
    
31 
   
    
    
   


b:= 32-1 = 31
09 a.ap(c-5
   
   
  
    
o->
   
   
    
    
   


L.c-5=33; N1:="32"+"33"="3233" 
26 printl
   
   
   
    
    
   
   
    
    
   
"3233"

Tulostus: 1 -34 38 3233

   
   
   
    
    
   
   
    
    
   


          ============= 

Luokkamuuttujat ovat rinnastettavissa globaaleihin muuttujiin. Samoin kun seuraavassa luvussa päästään käsiksi varsinaiseen olio-ohjelmointiin, niin myös julkiset attribuutit ovat rinnastettavissa globaaleihin muuttujiin. Globaaleiden muuttujien käyttöä tulee ohjelmoinnissa välttää. Tuskin mistään on tullut yhtä paljon ohjelmointivirheitä, kuin vahingossa muutetuista globaaleista muuttujista!

Käytännössä pöytätestiä voidaan monesti korvata hyvällä debuggerilla. Debuggerista valitettavasti ei useinkaan näe suorituksen historiaa. Ennen kun debuggerit eivät olleet niin yleisiä, korvattiin niitä sijoittamalla ohjelmakoodin sekaan muuttujien arvoja tulostavia lauseita. Joissakin tapauksissa tähänkin vielä joudutaan turvautumaan.

Tehtävä 8.22 Muuttujien näkyvyys

Pöytätestaa seuraava ohjelma:

java-muut\Alisotk2.java - parametrin välitystä

	/**
	 * Mitä ohjelma tulostaa?? 
	 * @author  Vesa Lappalainen
	 * @version 1.0, 19.01.2003
	 */
	public class Alisotk2 {
	
	  private static int i(StringBuffer s) {
	    return Integer.parseInt(s.toString());
	  }
	  private static void set(StringBuffer s,int i) {
	    s.delete(0, s.length()).append(""+i);
	  }
	
	/* 01 */ private static StringBuffer b; private static int c;
	/* 02 */
	/* 03 */ private static void s_1(StringBuffer a, int b)
	/* 04 */ {
	/* 05 */   int d;
	/* 06 */   d  = i(a);
	/* 07 */   c  = b + 3;
	/* 08 */   b  = d - 1;
	/* 09 */   set(a,c - 5);
	/* 10 */ }
	/* 11 */
	/* 12 */ private static void a_2(int a, StringBuffer b)
	/* 13 */ {
	/* 14 */   c  = a + i(b);
	/* 15 */   { int c; c = i(b);
	/* 16 */   a = 8 * c; }
	/* 17 */   set(b,175);
	/* 18 */ }
	/* 19 */
	/* 20 */ public static void main(String[] args) {
	/* 21 */   StringBuffer a = new StringBuffer("4"); int d=9;
	/* 22 */   System.out.println("" + a + " " + b + " " + c + " " + d);
	/* 23 */   b=new StringBuffer("3"); c=2; d=1;
	/* 24 */   s_1(b,c);
	/* 25 */   a_2(d,a);
	/* 26 */   s_1(a,3+d);
	/* 27 */   System.out.println("" + a + " " + b + " " + c + " " + d);
	/* 28 */ }
	}


Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys